Arduino ESP32在12小时后冻结

Arduino ESP32在12小时后冻结,arduino,mqtt,esp32,Arduino,Mqtt,Esp32,下午好,我想制作一个连续可操作的网关,用esp32测量温度。 设备每隔1.5秒通过MQTT发送数据。 Esp在12-24小时后冻结。 我读到一些用户每6-7个月操作一次设备,但没有重置,我怎么能在没有重置的情况下长时间操作设备 注1:作为代码中的一种解决方法,我每12小时使用MQTT、Ethernet和ESP.restart()重置一次设备,然后设备才能冻结 注2:LED指示系统正在工作 无法连接以太网或MQTT时,红灯亮起 蓝色表示尝试连接到MQTT或以太网 绿色表示系统处于活动状态。设备冻

下午好,我想制作一个连续可操作的网关,用esp32测量温度。 设备每隔1.5秒通过MQTT发送数据。 Esp在12-24小时后冻结。 我读到一些用户每6-7个月操作一次设备,但没有重置,我怎么能在没有重置的情况下长时间操作设备

注1:作为代码中的一种解决方法,我每12小时使用MQTT、Ethernet和ESP.restart()重置一次设备,然后设备才能冻结

注2:LED指示系统正在工作

  • 无法连接以太网或MQTT时,红灯亮起
  • 蓝色表示尝试连接到MQTT或以太网
  • 绿色表示系统处于活动状态。设备冻结时,绿色led仍亮起
我使用的库的版本:

  • Arduino IDE==1.8.14
  • ESP库版本==1.0.6
  • MQTT库版本==2.5.0
  • ESP库版本==2.0.9
ESP链接:

守则:

#包括
#包括
#包括
#包括
////////////////////////以太网配置//////////////////////////
字节mac[]={0xDE,0xAD,0xBE,0xEF,0xFE,0xED};
////////////////////////以太网配置//////////////////////////
////////////////////////LED和DHT22配置图//////////////////////////
字节red=2;
字节绿色=0;
字节蓝色=4;
字节temp=15;
#定义DHT类型DHT22
DHT DHT=DHT(温度,DHT类型);
////////////////////////LED和DHT22配置图//////////////////////////
////////////////////////MQTT CONFİG//////////////////////////
#定义mqttServer IP地址(xxx,xxx,xx,xxx)
常量char*mqttUser=“测试”;
const char*mqttPassword=“测试”;
const char*deviceId=“Ai传感器1”;
////////////////////////MQTT CONFİG//////////////////////////
无符号长lastMillis=0;
字节x;
字节y;
以太网络客户端;
MQTTClient;
//每12小时接收一次外部重置命令
无效回调(字符串和主题、字符串和有效负载){
如果(有效载荷=“1”)
{
ESP.restart();//这只是一种避免冻结问题的解决方法
}  
}
无效设置_eth(){
延迟(10);
digitalWrite(蓝色,高);//打开LED
//串行打印(“连接以太网…”);
if(以太网开始(mac)==0){
//Serial.println(“未能使用DHCP配置以太网”);
对于(;;)
;
}
begin(mac,Ethernet.localIP());
数字写入(蓝色,低电平);
}
void connect(){
//串行打印(“连接mqtt…”);
数字写入(蓝色,高);
而(!client.connected()){
if(client.connect(deviceId、mqttUser、mqttPassword)){
//订阅
//客户。订阅(“esp/data1”);
}否则{
延迟(500);
}
}
//Serial.println(“\n已连接!”);
数字写入(蓝色,低电平);
//客户。订阅(“esp/data1”);
}
无效设置(){
//序列号开始(115200);
pinMode(红色,输出);
引脚模式(绿色,输出);
pinMode(蓝色,输出);
数字写入(红色,低电平);
数码写入(绿色,低电平);
数字写入(蓝色,低电平);
dht.begin();
设置_eth();
setHost(mqttServer,1883);
client.setKeepAlive(90);
begin(mqttServer,net);
connect();
}
void循环(){
client.loop();
延迟(10);
客户认购(“esp/rst”);
onMessage(回调);
staticjsonbufferjson;
JsonObject&JSONencoder=JSON.createObject();
如果(毫秒()-lastMillis>1500){
数码写入(绿色,低电平);
数字写入(蓝色,低电平);
数字写入(红色,低电平);
如果(!client.connected()){
数字写入(红色,高);
如果(y==5){
//Serial.println(“立即重新启动系统…”);
特别是重新启动();
y=0;
}
y++;
connect();
}
if(Ethernet.linkStatus()==LinkON){
//序列号。打印号(“On”);
数码写入(绿色,高);
}
否则{
数字写入(红色,高);
如果(x==5){
//Serial.println(“立即重新启动系统…”);
特别是重新启动();
x=0;
}
x++;
}
lastMillis=millis();
//Serial.println(Ethernet.maintain());
JSONencoder[“DEVICE=“]=deviceId;
JSONencoder[“USER=“]=mqttUser;
JSONencoder[“TEMP=“]=dht.readTemperature();
JSONencoder[“HUMD=“]=dht.read湿度();
JSONencoder[“STATE=“]=true;
char-JSONmessageBuffer[100];
printTo(JSONmessageBuffer,sizeof(JSONmessageBuffer));
publish(“esp/data1”,JSONmessageBuffer);
}
}

从设备重新启动的那一刻起就有设备的输出会很有帮助-这可能会描述导致它的原因

如果没有这些,最好的猜测是你正在耗尽内存。要检查这一点,您应该定期打印出可用堆空间(执行此操作的FreeRTOS函数是
xPortGetFreeHeapSize()


我注意到,在
loop()
的每次迭代中,您只需执行一次操作-每次发布数据时,很可能不需要调用
subscribe()
onMessage()
,他们可能会分配新的堆内存来存储相关的上下文。

从设备重新启动的那一刻起就有设备的输出会很有帮助,这可能会描述导致它的原因

如果没有这些,最好的猜测是你正在耗尽内存。要检查这一点,您应该定期打印出可用堆空间(执行此操作的FreeRTOS函数是
xPortGetFreeHeapSize()


我注意到,在
loop()
的每次迭代中,您只需执行一次操作-每次发布数据时,很可能不需要调用
subscribe()
onMessage()
,他们可能会分配新的堆内存来存储相关的上下文。

我打赌你重启设备的次数太多了。您需要实施不同的故障模式和故障保护,而不是在每个问题上重新启动设备。在触发重启并使用时,设备可能处于有趣的状态