我对 Arduino 世界很陌生。编写了以下代码 - 使用 DHT22 传感器。12 小时后,我温室的加热器在低于所需温度时没有打开。
关闭电源并重新打开后,一切恢复正常。我知道这段代码很乱——但它有内存泄漏吗?或者其他可能导致它停止工作的东西?
编辑 - 我发现一个开放的计数器每 2 秒增加 1。我无法想象就是这样,但我在这里改变了它:http: //pastebin.com/nuRjHJkR
我对 Arduino 世界很陌生。编写了以下代码 - 使用 DHT22 传感器。12 小时后,我温室的加热器在低于所需温度时没有打开。
关闭电源并重新打开后,一切恢复正常。我知道这段代码很乱——但它有内存泄漏吗?或者其他可能导致它停止工作的东西?
编辑 - 我发现一个开放的计数器每 2 秒增加 1。我无法想象就是这样,但我在这里改变了它:http: //pastebin.com/nuRjHJkR
老军忠告:
如果你不能修复它,画它。
这些微控制器中存在看门狗定时器只是为了让您的植物保持活力,而不管您的代码如何。每次通过 loop(),你用一个简单的方法喂狗
wdt_reset();
如果您的程序挂起并停止喂狗,MCU 将重置。
您可以在 setup() 中配置看门狗的超时时间。出于您的目的,您可以使用 8 秒的大超时,这应该为最长的 loop() 执行时间提供巨大的余量。这些传感器读取需要多长时间?
有关简单描述,请参见 Arduino 页面中的链接: 看门狗
代码中明显的一个危险是 sprintf()。如果没有人再次使用它,世界将变得更美好。替换这个
void loop() {
...
char buf[128];
sprintf(buf, "Integer-only reading: Temperature %hi.%01hi C, Humidity %i.%01i %% RH",
myDHT22.getTemperatureCInt()/10, abs(myDHT22.getTemperatureCInt()%10),
myDHT22.getHumidityInt()/10, myDHT22.getHumidityInt()%10);
//Serial.println(buf);
和
void loop() {
...
const size_t sizeBuf = 128;
char szBuf[128+1];
snprintf(szBuf, sizeBuf, "Integer......", ... );
szBuf[sizeBuf] = '\0';
所有字符串函数都存在“n”个版本,并且都提供了目标缓冲区大小的规范,以便您可以确保它们永远不会超出缓冲区。注意函数不保证零终止,所以要多出一行来保证。
因此,使用 snprintf,您可以放心,如果一百万个数据错误中的 1 个错误会导致一些意外的字符串转换,您的代码会继续运行。
沿着这条线,在循环内分配 char buf[] 并没有太多好处。由于程序所做的只是无休止地执行 loop(),因此您不会通过将其设为堆栈上的局部变量来节省内存资源。只有一个不使用堆栈内存的微观窗口。但是通过在堆栈上,如果你溢出 buf,溢出可以擦除返回地址,这肯定会导致程序崩溃。这一切都是危险,没有回报。
这样想
const size_t sizeBuf = 128;
char szBuf[128+1];
void loop() {
...
snprintf(szBuf, sizeBuf, "Integer......", ... );
szBuf[sizeBuf] = '\0';
在这种方法中,内存是静态分配的,您在编译时就知道程序需要多少内存。