Fix display freeze: move I2C work out of interrupt context #8
@@ -18,11 +18,11 @@ void buttonISRstate() {
|
|||||||
else if (countdown == 0) {
|
else if (countdown == 0) {
|
||||||
// TODO: restart metronome timer to align countdown
|
// TODO: restart metronome timer to align countdown
|
||||||
countdown = COUNTDOWN;
|
countdown = COUNTDOWN;
|
||||||
updateTube();
|
displayNeedsUpdate = true;
|
||||||
} else {
|
} else {
|
||||||
countdown = -1;
|
countdown = -1;
|
||||||
digitalWrite(BUTTON_LED_PIN, LOW);
|
digitalWrite(BUTTON_LED_PIN, LOW);
|
||||||
updateTube();
|
displayNeedsUpdate = true;
|
||||||
// TODO: disable metronome timer
|
// TODO: disable metronome timer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
32
metronom.ino
32
metronom.ino
@@ -37,18 +37,19 @@ volatile float sensorValue[SENSORS] = {};
|
|||||||
volatile uint displaySensor = TEMPERATURE;
|
volatile uint displaySensor = TEMPERATURE;
|
||||||
volatile bool displayNeedsUpdate = false;
|
volatile bool displayNeedsUpdate = false;
|
||||||
volatile bool tubeRotated = false;
|
volatile bool tubeRotated = false;
|
||||||
|
volatile bool sensorsDue = false;
|
||||||
int tubeTimerID;
|
int tubeTimerID;
|
||||||
|
|
||||||
|
/* I2C (BME280 reads, tube writes) must never run in interrupt context:
|
||||||
|
both libraries call delay(), which inside an ISR can spin forever
|
||||||
|
because SysTick (millis/micros) is blocked. ISRs only raise flags;
|
||||||
|
loop() does the actual bus work. */
|
||||||
void TasksHandler(void) {
|
void TasksHandler(void) {
|
||||||
TasksISRs.run();
|
TasksISRs.run();
|
||||||
|
}
|
||||||
|
|
||||||
if (displayNeedsUpdate || tubeRotated)
|
void scheduleSensors() {
|
||||||
updateTube();
|
sensorsDue = true;
|
||||||
|
|
||||||
if (tubeRotated) {
|
|
||||||
TasksISRs.changeInterval(tubeTimerID, SENSOR_TIMESHARE[displaySensor]);
|
|
||||||
tubeRotated = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void setup() {
|
void setup() {
|
||||||
@@ -62,7 +63,7 @@ void setup() {
|
|||||||
|
|
||||||
TaskTimer.attachInterruptInterval_MS(TASK_HANDLER_INTERVAL, TasksHandler);
|
TaskTimer.attachInterruptInterval_MS(TASK_HANDLER_INTERVAL, TasksHandler);
|
||||||
TasksISRs.setInterval(METRONOME_INTERVAL, runMetronome);
|
TasksISRs.setInterval(METRONOME_INTERVAL, runMetronome);
|
||||||
TasksISRs.setInterval(SENSOR_INTERVAL, readSensors);
|
TasksISRs.setInterval(SENSOR_INTERVAL, scheduleSensors);
|
||||||
tubeTimerID = TasksISRs.setInterval(SENSOR_TIMESHARE[displaySensor], rotateTube);
|
tubeTimerID = TasksISRs.setInterval(SENSOR_TIMESHARE[displaySensor], rotateTube);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -79,4 +80,17 @@ void runMetronome() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void loop() {}
|
void loop() {
|
||||||
|
if (sensorsDue) {
|
||||||
|
sensorsDue = false;
|
||||||
|
readSensors();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (displayNeedsUpdate || tubeRotated)
|
||||||
|
updateTube();
|
||||||
|
|
||||||
|
if (tubeRotated) {
|
||||||
|
TasksISRs.changeInterval(tubeTimerID, SENSOR_TIMESHARE[displaySensor]);
|
||||||
|
tubeRotated = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user