Document icon-probe results; keep iconfinder bitprobe as artifact
Probed remaining frame bytes for Bluetooth/power icons on a blank panel: - found cross-wired glyph dots (byte0 bit7, byte4 bit7) and an I2C timeout (byte8 bit4), but no standalone icon bits - waveshare reference does not drive these icons; likely multi-bit or unpopulated on the glass (cosmetic, deprioritized) - restore temphummon.c as the active firmware build in CMakeLists
This commit is contained in:
parent
ebbeffa432
commit
d9bac7cf28
2 changed files with 64 additions and 59 deletions
|
|
@ -93,6 +93,20 @@ All three are **bit 5 (0x20) of the SECOND byte of the pair**, matching the manu
|
||||||
| **Decimal point (bottom)** | `f[8]` | bit 5 (0x20) | after bottom-line **ones** → `88.8` |
|
| **Decimal point (bottom)** | `f[8]` | bit 5 (0x20) | after bottom-line **ones** → `88.8` |
|
||||||
| **% sign (humidity)** | `f[10]` | bit 5 (0x20) | after bottom-line **tenths** → `88.8%` |
|
| **% sign (humidity)** | `f[10]` | bit 5 (0x20) | after bottom-line **tenths** → `88.8%` |
|
||||||
|
|
||||||
|
### Bluetooth / power icons (probed — NOT found, likely multi-bit or unpopulated)
|
||||||
|
|
||||||
|
A single-bit probe of the remaining frame bytes (0 bits5-7, 4/8/10 bits 4/6/7,
|
||||||
|
14 all) found **no standalone Bluetooth or battery/power icon**. Bits found:
|
||||||
|
- byte 0 bit7 → a cross-wired glyph dot (top-ones region)
|
||||||
|
- byte 4 bit7 → a cross-wired glyph dot (bottom-ones region)
|
||||||
|
- byte 8 bit4 → caused an **I²C hardware timeout**
|
||||||
|
- most other candidate bits → blank
|
||||||
|
|
||||||
|
The Waveshare reference code does NOT drive any Bluetooth/power icon, and the
|
||||||
|
IST7134 datasheet doesn't name one either. Conclusion: if the icons exist on
|
||||||
|
the glass they are **multi-bit patterns** (like °C = 0x05), not a simple single
|
||||||
|
bit reachable by a bare frame write — not worth more bench time. Cosmetic only.
|
||||||
|
|
||||||
### Verified glyph segment map (from probing)
|
### Verified glyph segment map (from probing)
|
||||||
|
|
||||||
For a digit byte-pair, the **first byte** = left column + horizontal bars, the
|
For a digit byte-pair, the **first byte** = left column + horizontal bars, the
|
||||||
|
|
@ -259,6 +273,7 @@ nix run .#flash
|
||||||
- [x] **Port Waveshare digit lookup table** — all 10 digits (0–9) verified working on the display
|
- [x] **Port Waveshare digit lookup table** — all 10 digits (0–9) verified working on the display
|
||||||
- [x] **Internal temperature sensor** — reads ESP32-H2 internal temp sensor, shows on display line 1, updates every 1s
|
- [x] **Internal temperature sensor** — reads ESP32-H2 internal temp sensor, shows on display line 1, updates every 1s
|
||||||
- [x] **Find decimal point & % bits** — probing session mapped them: `f[4]/f[8]` bit5 = decimals, `f[10]` bit5 = %
|
- [x] **Find decimal point & % bits** — probing session mapped them: `f[4]/f[8]` bit5 = decimals, `f[10]` bit5 = %
|
||||||
|
- [~] **Power/Bluetooth icons** — single-bit probe found no standalone icon bits; likely multi-bit patterns or unpopulated (cosmetic, deprioritized)
|
||||||
- [ ] **Add humidity sensor** — wire up an external I²C sensor (SHT40, BME280, etc.) and show on display line 2
|
- [ ] **Add humidity sensor** — wire up an external I²C sensor (SHT40, BME280, etc.) and show on display line 2
|
||||||
- [ ] **Configure Matter/Thread** — enable OpenThread / Matter components in `sdkconfig`
|
- [ ] **Configure Matter/Thread** — enable OpenThread / Matter components in `sdkconfig`
|
||||||
- [ ] **Implement Matter cluster** — temperature and humidity measurement clusters
|
- [ ] **Implement Matter cluster** — temperature and humidity measurement clusters
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,19 @@
|
||||||
/**
|
/**
|
||||||
* dpfinder — ESP32-H2 Zero + 1.9" Segment E-Paper (IST7134 via I²C)
|
* iconfinder — ESP32-H2 Zero + 1.9" Segment E-Paper (IST7134 via I²C)
|
||||||
*
|
*
|
||||||
* Targeted decimal-point / % tester, guided by the manual:
|
* Hunt the POWER (battery) and BLUETOOTH icons.
|
||||||
* "The decimal point and % are the 5th place in the 4th, 8th, and 10th
|
* Per the manual: "13th position = °C/°F, 14th unused, and icons at other
|
||||||
* positions respectively." (positions = vertical columns, L→R, T→B)
|
* positions" — we empirically probe the remaining untested frame bytes on a
|
||||||
|
* BLANK background (so a lone icon is unmistakable).
|
||||||
*
|
*
|
||||||
* We don't trust our model for exactly which BYTE is column 4/8/10, so we
|
* Bytes probed (0-indexed):
|
||||||
* just test bit-5 (0x20) at a handful of candidate bytes on a clear display
|
* byte 0 bits 5-7 (high bits we never tested; leading-1 glyph is 0-4)
|
||||||
* (a few "8" digits for context) and the human reports which shows a decimal
|
* byte 2 all 8 (second byte of top-tens pair)
|
||||||
* point or %.
|
* byte 6 all 8 (second byte of bottom-tens pair)
|
||||||
|
* byte 13 bits 3-7 (after the C/F letter bits 0-2)
|
||||||
|
* byte 14 all 8 (manual says unused, confirm)
|
||||||
|
* Dangerous black-control bits (byte 2 bit4, byte 4 bit7, byte 13 bit1)
|
||||||
|
* are SKIPPED to keep the panel stable.
|
||||||
*
|
*
|
||||||
* Wiring (GPIO4→SDA, GPIO5→SCL, GPIO10→RST, GPIO11→BUSY, 3V3→VCC, GND→GND)
|
* Wiring (GPIO4→SDA, GPIO5→SCL, GPIO10→RST, GPIO11→BUSY, 3V3→VCC, GND→GND)
|
||||||
*/
|
*/
|
||||||
|
|
@ -24,24 +29,13 @@
|
||||||
#define PIN_SCL GPIO_NUM_5
|
#define PIN_SCL GPIO_NUM_5
|
||||||
#define PIN_RST GPIO_NUM_10
|
#define PIN_RST GPIO_NUM_10
|
||||||
#define PIN_BUSY GPIO_NUM_11
|
#define PIN_BUSY GPIO_NUM_11
|
||||||
|
|
||||||
#define PIN_BOOT GPIO_NUM_9
|
#define PIN_BOOT GPIO_NUM_9
|
||||||
|
|
||||||
#define FRAME_LEN 15
|
#define FRAME_LEN 15
|
||||||
|
|
||||||
#define ADVANCE_MODE 1
|
#define ADVANCE_MODE 1
|
||||||
#define AUTO_HOLD_MS 3000
|
#define AUTO_HOLD_MS 3000
|
||||||
#define BOOT_TIMEOUT_MS 0
|
#define BOOT_TIMEOUT_MS 0
|
||||||
|
|
||||||
/* Digit "1" = minimal glyph (0x1f sets bits 0-4 only; bit 5 stays DARK so
|
|
||||||
* an added bit-5 decimal point is clearly visible). */
|
|
||||||
static const uint8_t DIG1[2] = {0x1f, 0x00};
|
|
||||||
|
|
||||||
/* The 6 digit positions (byte pair). */
|
|
||||||
static const uint8_t POS[6][2] = {
|
|
||||||
{1, 2}, {3, 4}, {5, 6}, {7, 8}, {9, 10}, {11, 12},
|
|
||||||
};
|
|
||||||
|
|
||||||
static i2c_master_bus_handle_t bus;
|
static i2c_master_bus_handle_t bus;
|
||||||
static i2c_master_dev_handle_t cmd_dev, dat_dev;
|
static i2c_master_dev_handle_t cmd_dev, dat_dev;
|
||||||
|
|
||||||
|
|
@ -101,18 +95,14 @@ static void epd_write(const uint8_t *frame, uint8_t extra_byte)
|
||||||
i2c_master_transmit(cmd_dev, s, sizeof(s), pdMS_TO_TICKS(100));
|
i2c_master_transmit(cmd_dev, s, sizeof(s), pdMS_TO_TICKS(100));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Show a readout of "1"s (one in each position) + one extra bit.
|
/* Show one bit of one byte on a BLANK background. */
|
||||||
* Base "1" leaves bit5 dark, so a decimal/% bit at bit5 is clearly seen. */
|
static void show_blank_plus(uint8_t frame_byte, uint8_t phys_bit, int tag)
|
||||||
static void show_1s_plus(uint8_t frame_byte, uint8_t phys_bit, int tag)
|
|
||||||
{
|
{
|
||||||
uint8_t f[FRAME_LEN];
|
uint8_t f[FRAME_LEN];
|
||||||
memset(f, 0, FRAME_LEN);
|
memset(f, 0, FRAME_LEN);
|
||||||
for (int p = 0; p < 6; p++) {
|
|
||||||
f[POS[p][0]] = DIG1[0];
|
|
||||||
f[POS[p][1]] = DIG1[1];
|
|
||||||
}
|
|
||||||
f[frame_byte] |= (uint8_t)(1u << phys_bit);
|
f[frame_byte] |= (uint8_t)(1u << phys_bit);
|
||||||
ESP_LOGI("dpfinder", "TEST %d: byte %d bit %d", tag, frame_byte, phys_bit);
|
ESP_LOGI("iconfinder", "T%d: byte %d bit %d (global %d)",
|
||||||
|
tag, frame_byte, phys_bit, frame_byte * 8 + phys_bit);
|
||||||
|
|
||||||
uint8_t off[FRAME_LEN];
|
uint8_t off[FRAME_LEN];
|
||||||
memset(off, 0, FRAME_LEN);
|
memset(off, 0, FRAME_LEN);
|
||||||
|
|
@ -122,14 +112,11 @@ static void show_1s_plus(uint8_t frame_byte, uint8_t phys_bit, int tag)
|
||||||
epd_write(f, 0x00);
|
epd_write(f, 0x00);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------------ */
|
|
||||||
static void boot_init(void)
|
static void boot_init(void)
|
||||||
{
|
{
|
||||||
gpio_config_t bc = {
|
gpio_config_t bc = {
|
||||||
.pin_bit_mask = (1ULL << PIN_BOOT),
|
.pin_bit_mask = (1ULL << PIN_BOOT), .mode = GPIO_MODE_INPUT,
|
||||||
.mode = GPIO_MODE_INPUT,
|
.pull_up_en = GPIO_PULLUP_ENABLE, .pull_down_en = GPIO_PULLDOWN_DISABLE,
|
||||||
.pull_up_en = GPIO_PULLUP_ENABLE,
|
|
||||||
.pull_down_en = GPIO_PULLDOWN_DISABLE,
|
|
||||||
.intr_type = GPIO_INTR_DISABLE,
|
.intr_type = GPIO_INTR_DISABLE,
|
||||||
};
|
};
|
||||||
gpio_config(&bc);
|
gpio_config(&bc);
|
||||||
|
|
@ -137,11 +124,8 @@ static void boot_init(void)
|
||||||
|
|
||||||
static void wait_for_advance(void)
|
static void wait_for_advance(void)
|
||||||
{
|
{
|
||||||
if (ADVANCE_MODE == 0) {
|
if (ADVANCE_MODE == 0) { vTaskDelay(pdMS_TO_TICKS(AUTO_HOLD_MS)); return; }
|
||||||
vTaskDelay(pdMS_TO_TICKS(AUTO_HOLD_MS));
|
ESP_LOGI("iconfinder", "press BOOT to advance next...");
|
||||||
return;
|
|
||||||
}
|
|
||||||
ESP_LOGI("dpfinder", "press BOOT to advance next...");
|
|
||||||
int64_t t_start = esp_timer_get_time();
|
int64_t t_start = esp_timer_get_time();
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if (gpio_get_level(PIN_BOOT) == 0) {
|
if (gpio_get_level(PIN_BOOT) == 0) {
|
||||||
|
|
@ -152,7 +136,7 @@ static void wait_for_advance(void)
|
||||||
}
|
}
|
||||||
if (BOOT_TIMEOUT_MS > 0 &&
|
if (BOOT_TIMEOUT_MS > 0 &&
|
||||||
esp_timer_get_time() - t_start > BOOT_TIMEOUT_MS * 1000LL) {
|
esp_timer_get_time() - t_start > BOOT_TIMEOUT_MS * 1000LL) {
|
||||||
ESP_LOGW("dpfinder", "no BOOT press in %d ms, auto-advancing", BOOT_TIMEOUT_MS);
|
ESP_LOGW("iconfinder", "no BOOT press in %d ms", BOOT_TIMEOUT_MS);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
vTaskDelay(pdMS_TO_TICKS(20));
|
vTaskDelay(pdMS_TO_TICKS(20));
|
||||||
|
|
@ -192,32 +176,38 @@ void app_main(void)
|
||||||
boot_init();
|
boot_init();
|
||||||
epd_init();
|
epd_init();
|
||||||
|
|
||||||
ESP_LOGI("dpfinder", "== Test decimal/% at bit5 (0x20) of candidate bytes ==");
|
ESP_LOGI("iconfinder", "== Probe icon-region bytes on blank panel ==");
|
||||||
|
|
||||||
/* Phase 0: plain all 1s, no extra bit (reference). */
|
int tag = 0;
|
||||||
{
|
|
||||||
uint8_t f[FRAME_LEN];
|
/* byte 0 bits 5-7 (leading-1 glyph is bits 0-4; high bits unknown) */
|
||||||
memset(f, 0, FRAME_LEN);
|
for (int b = 5; b < 8; b++) { show_blank_plus(0, b, ++tag); wait_for_advance(); }
|
||||||
for (int p = 0; p < 6; p++) {
|
|
||||||
f[POS[p][0]] = DIG1[0];
|
/* byte 4 (top-ones second byte): we know bits 0-3 = glyph right col,
|
||||||
f[POS[p][1]] = DIG1[1];
|
* bit 5 = decimal. The icon candidates are bits 4,6,7. Probe those. */
|
||||||
}
|
for (int b = 4; b < 8; b++) {
|
||||||
uint8_t off[FRAME_LEN];
|
if (b == 5) continue; /* decimal, already known */
|
||||||
memset(off, 0, FRAME_LEN);
|
show_blank_plus(4, b, ++tag); wait_for_advance();
|
||||||
epd_lut_GC(); epd_write(off, 0x00);
|
|
||||||
epd_lut_DU_WB(); epd_write(f, 0x00);
|
|
||||||
ESP_LOGI("dpfinder", "REF: all 1s (no extras)");
|
|
||||||
wait_for_advance();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Bit 5 (=0x20) at each candidate byte, 0-indexed: 3,4,7,8,9,10 */
|
/* byte 8 (bottom-ones second byte): same reasoning, bits 4,6,7 */
|
||||||
const int cand_byte[] = {3, 4, 7, 8, 9, 10};
|
for (int b = 4; b < 8; b++) {
|
||||||
for (int i = 0; i < (int)(sizeof(cand_byte)/sizeof(cand_byte[0])); i++) {
|
if (b == 5) continue; /* decimal, already known */
|
||||||
show_1s_plus(cand_byte[i], 5, i + 1);
|
show_blank_plus(8, b, ++tag); wait_for_advance();
|
||||||
wait_for_advance();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ESP_LOGI("dpfinder", "== Done. ==");
|
/* byte 10 (bottom-tenths second byte): bits 4,6,7 (bit5=percent) */
|
||||||
|
for (int b = 4; b < 8; b++) {
|
||||||
|
if (b == 5) continue; /* percent, already known */
|
||||||
|
show_blank_plus(10, b, ++tag); wait_for_advance();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* byte 14 all bits (manual says unused - confirm) */
|
||||||
|
for (int b = 0; b < 8; b++) {
|
||||||
|
show_blank_plus(14, b, ++tag); wait_for_advance();
|
||||||
|
}
|
||||||
|
|
||||||
|
ESP_LOGI("iconfinder", "== Done. ==");
|
||||||
uint8_t off[FRAME_LEN];
|
uint8_t off[FRAME_LEN];
|
||||||
memset(off, 0, FRAME_LEN);
|
memset(off, 0, FRAME_LEN);
|
||||||
epd_lut_DU_WB();
|
epd_lut_DU_WB();
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue