主要是避免任务的阻塞,使用了FreeRTOS的任务功能,这个历程创建了 3 个事务,以及事务内看门狗历程等,也可以使用 loop内进行喂狗操作,均试验成功。
#include "esp_adc_cal.h"
#include "esp_task_wdt.h" //设置看门狗用
#include "soc/rtc_wdt.h"
#include "esp_err.h"
#include "esp_system.h"
#define TWDT_TIMEOUT_S 5
#define TASK_RESET_PERIOD_MS 1000
#define MAIN_DELAY_MS 10000
#define BTN_STOP_ALARM 0
#define LED_D4 12
#define LED_D5 13
#define TXD1 0
#define RXD1 1
#define ToggleOutput(out) do { digitalWrite(out, !digitalRead(out)); } while(0)
#define ToggleOutBlink(out,interval) do {static uint32_t estp=0;if( (millis()-estp)>=interval ){ estp=millis();digitalWrite(out, !digitalRead(out));} } while(0)
String comdata = "";//声明字符串变量
String comdata1 = "";//声明字符串变量
// This is a task. pdMS_TO_TICKS(500)
void vTask1(void *pvParameters){
//Serial.println("Got Data on UART...");
while(1){
if(Serial.available()) // if there is data on the line
{
//SerialErrCount=0;
comdata += char(Serial.read());// read string until we see a newline character
comdata.toUpperCase();
if(comdata == "ON")
{
comdata ="";
digitalWrite(LED_D4, HIGH);
Serial.println("I turned it ON!"); // Reply text to send to Serial Monitor
}
else
if(comdata == "OFF")
{
comdata ="";
digitalWrite(LED_D4, LOW);
Serial.println("I turned it OFF"); // Reply text to send to Serial Monitor
}
else {
vTaskDelay(1 / portTICK_PERIOD_MS);
if(comdata.length()>=34){
Serial.println(comdata+"\n"); // Reply text to send to Serial Monitor
//Serial.flush(); //等待串口发送完毕???
comdata ="";
while(Serial.read()>= 0){}//clear serialport
ToggleOutput(LED_D4);
}
}
}else // break; // 收到事件后处理完毕自动跳出循环 测试 OK!
vTaskDelay(1); //必须放一个以便响应其它人物的消息循环,否则将死锁。
}
}
void vTask2(void *pvParameters){ //Serial.readBytes( &ch, 1 ) ;
//Serial1.println("Got Data on UART...");
while(1){
if(Serial1.available()) // if there is data on the line 是非阻塞的
{
//Serial1ErrCount=0;
comdata1 += char(Serial1.read()); // read string until we see a newline character
comdata1.toUpperCase();
if(comdata1 == "ON")
{
//comdata1 ="";
digitalWrite(LED_D4, HIGH);
Serial1.println("I turned it ON!"); // Reply text to send to Serial Monitor
}
else
if(comdata1 == "OFF")
{
//comdata1 ="";
digitalWrite(LED_D4, LOW);
Serial1.println("I turned it OFF"); // Reply text to send to Serial Monitor
}
else {
vTaskDelay(1 / portTICK_PERIOD_MS);
if(comdata1.length()>=24){
Serial1.println(comdata1+"\n"); // Reply text to send to Serial Monitor
//Serial1.flush();//等待串口发送完毕???
comdata1 ="";
while(Serial1.read()>= 0){}//clear serialport
ToggleOutput(LED_D5);
}
}
}else //break; //收到事件后处理完毕自动跳出循环 测试 OK!
vTaskDelay(1); //必须放一个以便响应其它人物的消息循环,否则将死锁。
}
}
void vTask3(void *pvParameters){
esp_task_wdt_add(NULL);
while(1){
esp_task_wdt_reset();
vTaskDelay(pdMS_TO_TICKS(TASK_RESET_PERIOD_MS));//1000 ms 喂狗一次
//ToggleOutput(LED_D5);
}
vTaskDelete(NULL);
esp_task_wdt_delete(NULL);
}
void setup() {
Serial.begin(9600);
Serial1.begin(115200,SERIAL_8N1,RXD1,TXD1);
pinMode(LED_D4, OUTPUT);
pinMode(LED_D5, OUTPUT); //
digitalWrite(LED_D4, LOW);
digitalWrite(LED_D5, LOW);
xTaskCreatePinnedToCore(vTask1,NULL,1024*2,NULL,configMAX_PRIORITIES - 1,NULL,ARDUINO_RUNNING_CORE);
xTaskCreatePinnedToCore(vTask2,NULL,1024*2,NULL,configMAX_PRIORITIES - 2,NULL,ARDUINO_RUNNING_CORE);
xTaskCreatePinnedToCore(vTask3,NULL,512*2,NULL,configMAX_PRIORITIES - 3,NULL,ARDUINO_RUNNING_CORE);
esp_task_wdt_init(TWDT_TIMEOUT_S, false);//uint32_t timeout:TWDT计时溢出的周期,单位秒。
}
void loop() {
// esp_task_wdt_reset();
// vTaskDelay(pdMS_TO_TICKS(TASK_RESET_PERIOD_MS));//1000 ms 喂狗一次
// ToggleOutBlink(LED_D5,1000);
}