As title, I'm trying to use Scheduler to manage different task, it works very well at the beginning, but after several hours, some task die(but others are still alive). below is my test code. the encoder task will die after about 2 hours after each reboot. Please kindly help me to figure out the problem.
`
// 需要用到的库
#include <Arduino.h>
#include <Scheduler.h> // 分时管理
#include <ClickEncoder.h> // 旋钮按键
#include <Adafruit_Sensor.h>
#include <DHT.h> // DHT22 传感器库
#include <brzo_i2c.h> // I2C
#include <SH1106Brzo.h> // OLED
#define ENCODER_PINA D4 // 对应GPIO2,印刷版上D4
#define ENCODER_PINB D7 // 对应GPIO13,印刷版上D7
#define ENCODER_BTN D6 // 对应GPIO12,印刷版上D6
#define ENCODER_STEPS_PER_NOTCH 4
#define DHT_PIN D5 // 对应GPIO14,印刷版上D5
#define DHT_TYPE 11 // DHT22温湿度传感器
#define OLED_ADDRESS 0x3C
#define OLED_SCL D1
#define OLED_SDA D2
#define GLYPH_WIDTH 32
#define GLYPH_HEIGHT 64
// 图形
static const char glyphs[4][GLYPH_WIDTH * GLYPH_HEIGHT] PROGMEM = {
{ // 图案0,关闭状态
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x07, 0x00, 0x00, 0xFC, 0x3F, 0x00,
0x00, 0xFF, 0xFF, 0x00, 0x80, 0xFF, 0xFF, 0x01, 0xC0, 0xFF, 0xFF, 0x03,
0xE0, 0x7F, 0xFE, 0x07, 0xF0, 0x7F, 0xFE, 0x0F, 0xF8, 0x7F, 0xFE, 0x0F,
0xF8, 0x79, 0x9E, 0x1F, 0xFC, 0x78, 0x1E, 0x1F, 0x7C, 0x7E, 0x7E, 0x3E,
0x7C, 0x7E, 0x7E, 0x3E, 0x7E, 0x7F, 0xFE, 0x3E, 0x3E, 0x7F, 0xFE, 0x7C,
0x3E, 0x7F, 0xFE, 0x7C, 0x3E, 0x7F, 0xFE, 0x7C, 0x3E, 0x7F, 0xFE, 0x7C,
0x3C, 0x7F, 0xFE, 0x3C, 0x7C, 0xFE, 0x7F, 0x3E, 0x7C, 0xFE, 0x7F, 0x3E,
0xFC, 0xFC, 0x3F, 0x1F, 0xF8, 0xF9, 0x8F, 0x1F, 0xF0, 0xE3, 0xC7, 0x0F,
0xF0, 0x07, 0xE0, 0x0F, 0xE0, 0x1F, 0xF8, 0x07, 0xC0, 0xFF, 0xFF, 0x03,
0x80, 0xFF, 0xFF, 0x01, 0x00, 0xFE, 0x7F, 0x00, 0x00, 0xF8, 0x1F, 0x00,
0x00, 0xC0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00
},
{ // 图案1,加热状态
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x01, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00,
0x00, 0xE0, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x00,
0x00, 0xF8, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00,
0x00, 0xFC, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x00,
0x00, 0xFE, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x08, 0x00, 0xFE, 0x01, 0x0C,
0x00, 0xFE, 0x01, 0x0E, 0x00, 0xFE, 0x01, 0x07, 0x00, 0xFC, 0x03, 0x07,
0x20, 0xFC, 0x87, 0x07, 0x60, 0xFC, 0x87, 0x07, 0xE0, 0xFC, 0xCF, 0x0F,
0xE0, 0xF9, 0xDF, 0x0F, 0xE0, 0xF9, 0xFF, 0x0F, 0xE0, 0xF9, 0xFF, 0x0F,
0xE0, 0xF9, 0xFF, 0x0F, 0xE0, 0xF9, 0xFF, 0x1F, 0xF0, 0xF9, 0xFF, 0x1F,
0xF0, 0xFD, 0xFF, 0x1F, 0xF8, 0xFD, 0xFD, 0x3F, 0xFC, 0xFF, 0xF9, 0x3F,
0xFC, 0xFF, 0xF9, 0x7F, 0xFE, 0xFF, 0xF9, 0x7F, 0xFE, 0xFF, 0xF8, 0x7F,
0xFE, 0xF7, 0xF8, 0x7F, 0xFF, 0xF7, 0xF8, 0x7F, 0xFF, 0x67, 0xD8, 0x7F,
0xFF, 0x67, 0xC8, 0x7F, 0xFF, 0x27, 0xC8, 0x7F, 0xFF, 0x03, 0xC8, 0x7F,
0xFF, 0x03, 0xC8, 0x7F, 0xFE, 0x03, 0x88, 0x7F, 0xFE, 0x01, 0x80, 0x3F,
0xFC, 0x01, 0x00, 0x3F, 0xFC, 0x01, 0x00, 0x1F, 0xF8, 0x01, 0x00, 0x0F,
0xF0, 0x01, 0x00, 0x07, 0xE0, 0x03, 0x80, 0x03, 0x80, 0x07, 0xC0, 0x00,
0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00
},
{ // 图案2,制冷状态
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00,
0x00, 0xC0, 0x03, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0xE0, 0x07, 0x00,
0x00, 0xF0, 0x0F, 0x00, 0x00, 0xF0, 0x0F, 0x00, 0x00, 0xF8, 0x1F, 0x00,
0x00, 0xFC, 0x3F, 0x00, 0x00, 0xFE, 0x3F, 0x00, 0x00, 0xFE, 0x7F, 0x00,
0x00, 0xFF, 0xFF, 0x00, 0x80, 0xFF, 0xFF, 0x01, 0x80, 0xFF, 0xFF, 0x01,
0xC0, 0xFF, 0xFF, 0x03, 0xE0, 0xFF, 0xFF, 0x07, 0xF0, 0xFF, 0xFF, 0x0F,
0xF0, 0x7F, 0xFE, 0x0F, 0xF8, 0x5F, 0xF8, 0x1F, 0xFC, 0x1F, 0xFC, 0x3F,
0xFC, 0x3D, 0xBC, 0x3F, 0xFC, 0x7D, 0x9E, 0x3F, 0x3E, 0x78, 0x1E, 0x7C,
0xFE, 0x78, 0x1E, 0x7F, 0x3E, 0x60, 0x06, 0x7C, 0x3E, 0x46, 0x62, 0x7C,
0xFE, 0x1F, 0xF8, 0x7F, 0xFE, 0x3F, 0xFC, 0x7F, 0xFE, 0x0F, 0xF0, 0x7F,
0x3E, 0x40, 0x22, 0x7C, 0x7E, 0x70, 0x0E, 0x7F, 0x7E, 0x78, 0x1E, 0x7E,
0x3C, 0x7C, 0x1E, 0x3C, 0xFC, 0x7D, 0x9E, 0x3F, 0xF8, 0x3D, 0xBC, 0x1F,
0xF8, 0x1F, 0xF8, 0x1F, 0xF0, 0x5F, 0xFA, 0x0F, 0xE0, 0x7F, 0xFE, 0x07,
0xC0, 0xFF, 0xFF, 0x03, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFE, 0x7F, 0x00,
0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00
},
{ // 图案3,自动状态
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x07, 0x00, 0x00, 0xFC, 0x3F, 0x00,
0x00, 0xFF, 0xFF, 0x00, 0x80, 0xFF, 0xFF, 0x01, 0xC0, 0xFF, 0xFF, 0x03,
0xE0, 0xFF, 0xFF, 0x07, 0xF0, 0xFF, 0xFF, 0x0F, 0xF8, 0xFF, 0xFF, 0x0F,
0xF8, 0xFF, 0xFF, 0x1F, 0xFC, 0xFF, 0xFF, 0x1F, 0xBC, 0xBB, 0x60, 0x3C,
0xBC, 0xBB, 0xBB, 0x3B, 0x5E, 0xBB, 0xBB, 0x3B, 0x5E, 0xBB, 0xBB, 0x7B,
0x5E, 0xBB, 0xBB, 0x7B, 0x0E, 0xBA, 0xBB, 0x7B, 0xEE, 0xBA, 0xBB, 0x7B,
0xEC, 0xC6, 0x7B, 0x3C, 0xFC, 0xFF, 0xFF, 0x3F, 0xFC, 0xFF, 0xFF, 0x3F,
0xFC, 0xFF, 0xFF, 0x1F, 0xF8, 0xFF, 0xFF, 0x1F, 0xF0, 0xFF, 0xFF, 0x0F,
0xF0, 0xFF, 0xFF, 0x0F, 0xE0, 0xFF, 0xFF, 0x07, 0xC0, 0xFF, 0xFF, 0x03,
0x80, 0xFF, 0xFF, 0x01, 0x00, 0xFE, 0x7F, 0x00, 0x00, 0xF8, 0x1F, 0x00,
0x00, 0xC0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00
}
};
ClickEncoder encoder = ClickEncoder(ENCODER_PINA, ENCODER_PINB, ENCODER_BTN, ENCODER_STEPS_PER_NOTCH);
DHT dht(DHT_PIN,DHT_TYPE);
SH1106Brzo oled(OLED_ADDRESS, OLED_SDA, OLED_SCL);
volatile uint8_t targetTemperature = 20;
volatile uint8_t currentHumidity = 20;
volatile uint8_t currentTemperature = 20;
volatile uint8_t targetMode = 0, currentMode = 0;
volatile bool isOledOn = true;
// 编码器管理进程
class EncoderTask : public Task {
protected:
void setup() {
encoder.setDoubleClickEnabled(true);
encoder.setButtonHeldEnabled(false);
encoder.setButtonOnPinZeroEnabled(false);
}
void loop() {
static uint32_t lastService = 0;
if (lastService + 1000 < micros()) {
lastService = micros();
encoder.service();
}
static int16_t encLast, encValue = 0;
encValue += encoder.getValue();
if(encValue != encLast) {
if(isOledOn) { // 只有在屏幕点亮的时候才调整温度,避免误操作
targetTemperature = (encValue > encLast) ? targetTemperature + 1 : targetTemperature - 1;
if(targetTemperature > 38) targetTemperature = 38;
if(targetTemperature <10) targetTemperature = 10;
}
encLast = encValue;
}
ClickEncoder::Button b = encoder.getButton();
if (b != ClickEncoder::Open) {
switch (b) {
case ClickEncoder::Clicked:
isOledOn = !isOledOn;
break;
case ClickEncoder::DoubleClicked:
if(isOledOn) { // 只有在屏幕点亮的时候操作切换模式才有效,避免误操作
currentMode += 1;
if(currentMode > 3) currentMode = 0;
}
break;
}
}
}
bool shouldRun() {
bool run = Task::shouldRun();
// Your code here
//Serial.println("This task should be running");
return run;
}
} encoder_task;
// DHT温湿度传感器管理进程
class DHTTask : public Task {
public:
void setup() {
pinMode(DHT_PIN, INPUT);
}
void loop() {
currentTemperature = (int)dht.readTemperature();
currentHumidity = (int)dht.readHumidity();
static bool state = false;
state = !state;
Serial.print(state);
Serial.print(": Target: ");
Serial.println(targetTemperature);
delay(10000); // 每10秒采集一次温湿度数据
}
} dht_task;
// OLED显示管理进程
class OledTask : public Task {
public:
void setup() {
// 初始化OLED液晶屏并显示初始提示
oled.init();
//oled.flipScreenVertically();
oled.setColor(WHITE);
oled.setFont(ArialMT_Plain_24);
oled.setTextAlignment(TEXT_ALIGN_LEFT);
oled.clear();
oled.drawString(40, 12, "INIT");
oled.display();
}
void loop() {
char ctemp[3], humi[3], ttemp[3];
sprintf(ctemp, "%d", currentTemperature);
sprintf(humi, "%d", currentHumidity); // not used yet.
sprintf(ttemp, "%d", targetTemperature);
oled.clear();
// 画模式图案
oled.drawXbm(16, 0, GLYPH_WIDTH, GLYPH_HEIGHT, glyphs[currentMode]);
// 画个房子
oled.drawLine(10, 14, 26, 0);
oled.drawLine(26, 0, 74, 30);
oled.drawLine(74, 30, 58, 30);
oled.drawLine(58, 30, 58, 64);
oled.drawString(78, 1, ctemp);
oled.drawString(78, 32, ttemp);
oled.display();
if(isOledOn) oled.displayOn();
else oled.displayOff();
}
} oled_task;
// 主设置程序
void setup() {
Serial.begin(115200);
Serial.println("");
delay(1000);
// 加入各个任务
Scheduler.start(&encoder_task);
Scheduler.start(&dht_task);
Scheduler.start(&oled_task);
// 启动任务的执行
Scheduler.begin();
}
// 主循环
void loop() {
}
`