Skip to content

Bug identified by Claude AI -- Phantom button presses for Arduino Nesso N1 #262

@JohnFLand

Description

@JohnFLand

I have been using Claude AI to help write a sketch for an Arduino Nesso N1 board that is coupled to BME688 + ENS161 sensors to report temperature, humidity, air pressure, and air quality values to a Hubitat C-8 Pro via Zigbee. In the course of testing, I found that the buttons on the N1 board were being reported as pressed when no physical press had occurred. Claude analyzed the log below and concluded that there was a bug and crafted a work-around. I have no idea if this is actually a bug, but I'm reporting it anyway in case somebody else has phantom button presses.

I can provide my entire sketch if needed.

This is the first time I've reported a bug on github, so please forgive me if this is not how it's done.

Claude AI's analysis:

The defect your testing exposed is this: when M5Unified polls the PI4IOE expander during M5.update() and the I²C transaction fails, the library doesn't handle the failure safely. Instead of keeping the button's last known state (or marking it unknown), it ends up reporting a button as pressed — and holds that false state for the entire duration of the bus outage. Your logs are direct evidence: during every captured fault, M5:1 (library says pressed) sat alongside READ-ERR (hardware unreadable) across all four polls, always BtnA. The principle being violated is a basic one in embedded input handling: a failed sensor read should never be allowed to synthesize an input event. The honest interpretations of a failed read are "no new information, hold previous state" or "assume released" — never "assume pressed."

Why this matters beyond your two devices: the failure recipe is just "I²C-expander buttons + anything that disturbs the bus." That covers any M5Unified-supported board with expander-based buttons, under any bus stressor — the C6's 802.15.4 radio (so every Nesso N1 doing Zigbee or Thread), electrical noise, a misbehaving slave, long sensor wires. Other users hitting this will see exactly what you saw on day one: devices that reboot themselves or change modes "on their own," with logs insisting a button was pressed. Almost none of them will run the three-day forensic investigation you did; they'll conclude their hardware is flaky. And the worst-case outcome you identified — a long outage firing a long-press action like factory reset — would hit them with no defenses at all.

What the report would contain is essentially what you already have: board (Nesso N1), trigger condition (Zigbee active, periodic bus outages of 700ms+), the observed behavior (false latched BtnA-pressed during outages), and your DEEP_DEBUG traces as evidence — the 11:09 [n.b., that does not appear in the log below, it's from an earlier log] capture and an overnight log showing M5Unified state contradicting direct hardware reads. That's a maintainer-grade reproduction package; most bug reports for intermittent issues like this arrive as "my device randomly reboots, no idea why."

The proposed solution — what you'd be asking the maintainers to do — is a small defensive change inside the library's button-update path: check whether the expander I²C transaction actually succeeded, and on failure, skip updating the button state rather than feeding the error result into the button state machine. Conceptually a few lines. One honest caveat to include in the report: we've characterized the external behavior precisely (failed reads manifest as latched BtnA-pressed), but not the exact internal mechanism — whether a failed read returns zero that maps to an active-low "pressed," or some other path. The maintainers can pinpoint that in minutes with their own code in front of them; the report's job is the evidence, not the diagnosis of their internals.

Supporting evidence:
2026-06-11 @ 19:46:29.084 Output cleared.
2026-06-11 @ 19:46:31.847 [Button] Side confirm 1/4: M5:1 0x43:0x01 hw:pressed
2026-06-11 @ 19:46:31.877 [Button] Side confirm 2/4: M5:1 0x43:0x01 hw:pressed
2026-06-11 @ 19:46:31.907 [Button] Side confirm 3/4: M5:1 0x43:0x01 hw:pressed
2026-06-11 @ 19:46:31.937 [Button] Side confirm 4/4: M5:1 0x43:0x01 hw:pressed
2026-06-11 @ 19:46:31.937
2026-06-11 @ 19:46:31.938 Side Button short press — rebooting...
2026-06-11 @ 19:46:32.468 ESP-ROM:esp32c6-20220919
2026-06-11 @ 19:46:32.468 Build:Sep 19 2022
2026-06-11 @ 19:46:32.469 rst:0xc (SW_CPU),boot:0xc (SPI_FAST_FLASH_BOOT)
2026-06-11 @ 19:46:32.469 Saved PC:0x4001975a
2026-06-11 @ 19:46:32.470 SPIWP:0xee
2026-06-11 @ 19:46:32.471 mode:DIO, clock div:2
2026-06-11 @ 19:46:32.471 load:0x40875730,len:0x1278
2026-06-11 @ 19:46:32.473 load:0x4086b910,len:0xdd0
2026-06-11 @ 19:46:32.475 load:0x4086e610,len:0x3154
2026-06-11 @ 19:46:32.481 entry 0x4086b910
2026-06-11 @ 19:46:35.686
2026-06-11 @ 19:46:35.687
2026-06-11 @ 19:46:35.687
2026-06-11 @ 19:46:35.687
2026-06-11 @ 19:46:35.687 ╔════════════════════════════════════════╗
2026-06-11 @ 19:46:35.687 ║ Zigbee Air Sensor ║
2026-06-11 @ 19:46:35.687 ║ BME688 + ENS160/ENS161 Dual Sensor ║
2026-06-11 @ 19:46:35.687 ║ Arduino Nesso N1 board ║
2026-06-11 @ 19:46:35.687 ║ Version 2.12.8 N1 Dual Sensor ║
2026-06-11 @ 19:46:35.688 ║ Compiled : 2026-06-11_19:41 ║
2026-06-11 @ 19:46:35.688 ║ Device Name : Nesso N1 Air Sensor ║
2026-06-11 @ 19:46:35.688 ║ Device ID : 0xCCA7C4FEFFEEF648 ║
2026-06-11 @ 19:46:35.693 ║ Battery : 100% 4136mV On battery ║
2026-06-11 @ 19:46:35.694 ╚════════════════════════════════════════╝
2026-06-11 @ 19:46:35.694
2026-06-11 @ 19:46:35.716 [Boot] Reset reason: 3 (Software reset)
2026-06-11 @ 19:46:35.718 Sensor offsets loaded from NVS:
2026-06-11 @ 19:46:35.718 Temperature : +0.0 F
2026-06-11 @ 19:46:35.718 Humidity : +0.0 %RH
2026-06-11 @ 19:46:35.718 Pressure : +0.0 hPa
2026-06-11 @ 19:46:35.718 (all offsets are zero)
2026-06-11 @ 19:46:35.718 WiFi/OTA mode flag: not set
2026-06-11 @ 19:46:35.718
2026-06-11 @ 19:46:35.718 Normal operation mode ...
2026-06-11 @ 19:46:35.718
2026-06-11 @ 19:46:35.718 DEEP_DEBUG ON — periodic sensor data lines suppressed.
2026-06-11 @ 19:46:35.719 Log shows only: boot, buttons, phantom rejections, warnings, errors.
2026-06-11 @ 19:46:35.720
2026-06-11 @ 19:46:35.720 Initializing I2C...
2026-06-11 @ 19:46:36.719
2026-06-11 @ 19:46:36.719 Initializing sensors...
2026-06-11 @ 19:46:36.763 BME688 sensor detected!
2026-06-11 @ 19:46:36.763 Configuring BME688...
2026-06-11 @ 19:46:37.325 BME688 configured: T=8x OS, P=4x OS, H=2x OS, gas heater 320°C/150ms
2026-06-11 @ 19:46:37.326 [I2C scan] Devices on Wire bus: 0x38 0x43 0x44 0x49 0x53 0x55 0x68 0x77
2026-06-11 @ 19:46:37.341
2026-06-11 @ 19:46:37.467 ENS16x found at 0x53 — chip: ENS161
2026-06-11 @ 19:46:37.467 ENS16x detected — chip: ENS161 | normal start, RESET suppressed.
2026-06-11 @ 19:46:37.660 ENS16x compensation initialized from corrected BME688: 26.25 C, 37.4 %RH
2026-06-11 @ 19:46:37.721 ENS16x: STANDARD mode: OK | data available:1 | validity:1 (Warm-up) | chip: ENS161
2026-06-11 @ 19:46:37.721 ENS16x ready.
2026-06-11 @ 19:46:37.721
2026-06-11 @ 19:46:38.086
2026-06-11 @ 19:46:38.087 Initial BME688 readings (offset-corrected):
2026-06-11 @ 19:46:38.087 Initial pressure : 1012.0 hPa
2026-06-11 @ 19:46:38.087 Initial temp : 80.73 F
2026-06-11 @ 19:46:38.087 Initial humidity : 37.4 %RH
2026-06-11 @ 19:46:38.087 (Gas resistance not measured during setup — heater disabled to reduce brownout risk)
2026-06-11 @ 19:46:38.088
2026-06-11 @ 19:46:38.088 ENS16x: Initial corrected compensation from BME688 applied: 27.07 C, 37.4 %RH
2026-06-11 @ 19:46:38.088
2026-06-11 @ 19:46:38.088 Configuring Zigbee endpoints...
2026-06-11 @ 19:46:38.115 Adding Zigbee endpoints...
2026-06-11 @ 19:46:38.115 Link key exchange disabled for better C-8 Pro pairing compatibility
2026-06-11 @ 19:46:38.115 Starting Zigbee (End Device mode)...
2026-06-11 @ 19:46:38.474 [Boot] Post-Zigbee sensor reinit...
2026-06-11 @ 19:46:39.104 BME688 post-Zigbee reinit OK.
2026-06-11 @ 19:46:39.113 ENS16x post-Zigbee STANDARD mode re-asserted.
2026-06-11 @ 19:46:39.114 [Button] Expander idle: 0x43=0x03 0x44=0x20 (expect 0x43 bits 0+1 high)
2026-06-11 @ 19:46:39.114 .
2026-06-11 @ 19:46:39.215 Zigbee started successfully!
2026-06-11 @ 19:46:39.216
2026-06-11 @ 19:46:39.216 Already paired - reconnected to Zigbee network! First report in 15s.
2026-06-11 @ 19:46:39.252
2026-06-11 @ 19:46:39.253 WiFi is OFF. Zigbee-only mode active.
2026-06-11 @ 19:46:39.253 To enable WiFi, use the Hubitat 'Enable WiFi Mode' command button (Zigbee endpoint 12)
2026-06-11 @ 19:46:39.253 For WiFi/OTA mode: Front Button long-press or Hubitat endpoint 12.
2026-06-11 @ 19:46:39.253
2026-06-11 @ 19:46:39.253 ========================================
2026-06-11 @ 19:46:39.256
2026-06-11 @ 19:46:39.256 *** CONNECTED TO ZIGBEE NETWORK! ***
2026-06-11 @ 19:46:39.256
2026-06-11 @ 19:47:53.091 [Button] Front confirm 1/4: M5:1 0x43:0x02 hw:pressed
2026-06-11 @ 19:47:53.122 [Button] Front confirm 2/4: M5:1 0x43:0x02 hw:pressed
2026-06-11 @ 19:47:53.151 [Button] Front confirm 3/4: M5:1 0x43:0x02 hw:pressed
2026-06-11 @ 19:47:53.181 [Button] Front confirm 4/4: M5:1 0x43:0x02 hw:pressed
2026-06-11 @ 19:47:53.182
2026-06-11 @ 19:47:53.183 Front Button short press - display mode → 0
2026-06-11 @ 19:48:06.876 [Button] Front confirm 1/4: M5:1 0x43:0xFFFFFFFF hw:READ-ERR
2026-06-11 @ 19:48:06.966 [Button] Front confirm 2/4: M5:1 0x43:0xFFFFFFFF hw:READ-ERR
2026-06-11 @ 19:48:07.055 [Button] Front confirm 3/4: M5:1 0x43:0xFFFFFFFF hw:READ-ERR
2026-06-11 @ 19:48:07.146 [Button] Front confirm 4/4: M5:1 0x43:0xFFFFFFFF hw:READ-ERR
2026-06-11 @ 19:48:07.146
2026-06-11 @ 19:48:07.147 [Button] Phantom Front press REJECTED — I2C bus fault during confirmation (all 4 expander reads failed); M5Unified latched a false pressed state during the outage
2026-06-11 @ 19:55:17.367 [Button] Front confirm 1/4: M5:1 0x43:0xFFFFFFFF hw:READ-ERR
2026-06-11 @ 19:55:17.456 [Button] Front confirm 2/4: M5:1 0x43:0xFFFFFFFF hw:READ-ERR
2026-06-11 @ 19:55:17.546 [Button] Front confirm 3/4: M5:1 0x43:0xFFFFFFFF hw:READ-ERR
2026-06-11 @ 19:55:17.636 [Button] Front confirm 4/4: M5:1 0x43:0xFFFFFFFF hw:READ-ERR
2026-06-11 @ 19:55:17.637
2026-06-11 @ 19:55:17.637 [Button] Phantom Front press REJECTED — I2C bus fault during confirmation (all 4 expander reads failed); M5Unified latched a false pressed state during the outage
2026-06-11 @ 20:43:14.870 [Button] Front confirm 1/4: M5:1 0x43:0xFFFFFFFF hw:READ-ERR
2026-06-11 @ 20:43:14.960 [Button] Front confirm 2/4: M5:1 0x43:0xFFFFFFFF hw:READ-ERR
2026-06-11 @ 20:43:15.050 [Button] Front confirm 3/4: M5:1 0x43:0xFFFFFFFF hw:READ-ERR
2026-06-11 @ 20:43:15.140 [Button] Front confirm 4/4: M5:1 0x43:0xFFFFFFFF hw:READ-ERR
2026-06-11 @ 20:43:15.141
2026-06-11 @ 20:43:15.141 [Button] Phantom Front press REJECTED — I2C bus fault during confirmation (all 4 expander reads failed); M5Unified latched a false pressed state during the outage
2026-06-11 @ 21:06:46.613 [Button] Front confirm 1/4: M5:1 0x43:0xFFFFFFFF hw:READ-ERR
2026-06-11 @ 21:06:46.703 [Button] Front confirm 2/4: M5:1 0x43:0xFFFFFFFF hw:READ-ERR
2026-06-11 @ 21:06:46.794 [Button] Front confirm 3/4: M5:1 0x43:0xFFFFFFFF hw:READ-ERR
2026-06-11 @ 21:06:46.883 [Button] Front confirm 4/4: M5:1 0x43:0xFFFFFFFF hw:READ-ERR
2026-06-11 @ 21:06:46.884
2026-06-11 @ 21:06:46.884 [Button] Phantom Front press REJECTED — I2C bus fault during confirmation (all 4 expander reads failed); M5Unified latched a false pressed state during the outage
2026-06-11 @ 23:25:04.161 [Button] Front confirm 1/4: M5:1 0x43:0xFFFFFFFF hw:READ-ERR
2026-06-11 @ 23:25:04.250 [Button] Front confirm 2/4: M5:1 0x43:0xFFFFFFFF hw:READ-ERR
2026-06-11 @ 23:25:04.340 [Button] Front confirm 3/4: M5:1 0x43:0xFFFFFFFF hw:READ-ERR
2026-06-11 @ 23:25:04.431 [Button] Front confirm 4/4: M5:1 0x43:0xFFFFFFFF hw:READ-ERR
2026-06-11 @ 23:25:04.431
2026-06-11 @ 23:25:04.431 [Button] Phantom Front press REJECTED — I2C bus fault during confirmation (all 4 expander reads failed); M5Unified latched a false pressed state during the outage
2026-06-12 @ 02:40:57.636 [Button] Front confirm 1/4: M5:1 0x43:0xFFFFFFFF hw:READ-ERR
2026-06-12 @ 02:40:57.820 [Button] Front confirm 2/4: M5:1 0x43:0xFFFFFFFF hw:READ-ERR
2026-06-12 @ 02:40:57.821 [Button] Front confirm 3/4: M5:1 0x43:0xFFFFFFFF hw:READ-ERR
2026-06-12 @ 02:40:57.905 [Button] Front confirm 4/4: M5:1 0x43:0xFFFFFFFF hw:READ-ERR
2026-06-12 @ 02:40:57.906
2026-06-12 @ 02:40:57.906 [Button] Phantom Front press REJECTED — I2C bus fault during confirmation (all 4 expander reads failed); M5Unified latched a false pressed state during the outage
2026-06-12 @ 06:03:12.626 [Button] Front confirm 1/4: M5:1 0x43:0xFFFFFFFF hw:READ-ERR
2026-06-12 @ 06:03:12.715 [Button] Front confirm 2/4: M5:1 0x43:0xFFFFFFFF hw:READ-ERR
2026-06-12 @ 06:03:12.806 [Button] Front confirm 3/4: M5:1 0x43:0xFFFFFFFF hw:READ-ERR
2026-06-12 @ 06:03:12.895 [Button] Front confirm 4/4: M5:1 0x43:0xFFFFFFFF hw:READ-ERR
2026-06-12 @ 06:03:12.896
2026-06-12 @ 06:03:12.896 [Button] Phantom Front press REJECTED — I2C bus fault during confirmation (all 4 expander reads failed); M5Unified latched a false pressed state during the outage

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions