Piotr observed the freeze correlates with digit '8' on the last
(units) tube position, regardless of which sensor is shown
(25.08 C, 48 %, 1018 hPa). '8' lights the most 14-seg segments of
any digit, and the units digit changes most often, so the last
position is both peak-current and the most-written-to. At brightness
15 (max) that peak current likely dips the supply / glitches the I2C
bus, which the in-ISR delay()/endTransmission() then turns into a
permanent hang.
This commit drops brightness 15 -> 4 as a cheap, reversible probe.
If freezes stop or get much rarer, the root cause is current/brownout
(fix: decoupling cap on display VCC, or separate supply, plus an I2C
bus-recovery/timeout) rather than purely the ISR timing.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The tube library calls delay(100) after every display write and the
BME280 library calls delay(100) when re-initializing after a failed
transfer. Inside the TC3 timer ISR the SysTick interrupt is blocked,
so micros() stops advancing past ~1ms and delay() can spin forever
when its start sample lands exactly at the bottom of the micros()
sawtooth. All clocks derive from the same 48MHz source, so the ISR
phase is locked and one specific code path (display update on a
falling temperature reading) hits the fatal window reproducibly.
ISRs now only raise flags; sensor reads, display updates and timer
rescheduling run from loop(), where delay() works normally.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>