forked from Arduino/metronom
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>
56 lines
1.6 KiB
C++
56 lines
1.6 KiB
C++
#include "grove_alphanumeric_display.h"
|
|
|
|
Seeed_Digital_Tube tube;
|
|
char tubeText[5] = "";
|
|
|
|
void initTube() {
|
|
// Wire initialized by BME280 sensor
|
|
tube.setTubeType(TYPE_4, TYPE_4_DEFAULT_I2C_ADDR);
|
|
// Brightness drives LED current. The freeze correlates with '8' on the last
|
|
// multiplexed digit (most segments lit -> peak current) at full brightness 15,
|
|
// which points at a supply/I2C-bus glitch. Lowered to probe that hypothesis;
|
|
// raise back toward 15 if the display is too dim and freezes don't return.
|
|
tube.setBrightness(4);
|
|
tube.setBlinkRate(BLINK_OFF);
|
|
}
|
|
|
|
void rotateTube() {
|
|
displaySensor = (displaySensor + 1) % SENSORS;
|
|
tubeRotated = true;
|
|
}
|
|
|
|
void updateTube() {
|
|
char newText[5];
|
|
bool highPoint = false, lowPoint = false;
|
|
uint value = countdown;
|
|
|
|
if (countdown <= 0) {
|
|
switch (displaySensor) {
|
|
case TEMPERATURE:
|
|
value = (uint) (sensorValue[TEMPERATURE] * 100);
|
|
lowPoint = true;
|
|
break;
|
|
case HUMIDITY:
|
|
// TODO: add % sign?
|
|
value = (uint) (sensorValue[HUMIDITY]);
|
|
break;
|
|
case PRESSURE:
|
|
value = (uint) (sensorValue[PRESSURE] / 100);
|
|
break;
|
|
}
|
|
}
|
|
sprintf(newText, "%4u", value);
|
|
|
|
// TODO: In the current mode of display refresh (displayNeedsUpdate) it should not be necessary to check previous text
|
|
// Maybe add LED switching for case when the strings match as a rough check before removing comparison?
|
|
// Or LED switching when display is updated?
|
|
if (strcmp(tubeText, newText)) {
|
|
strcpy(tubeText, newText);
|
|
tube.displayString(tubeText);
|
|
tube.setPoint(highPoint, lowPoint);
|
|
tube.display();
|
|
}
|
|
|
|
displayNeedsUpdate = false;
|
|
}
|