Arduino'坠毁了?' 12小时后

时间:2013-01-14 19:55:23

标签: crash arduino

我对Arduino世界都很陌生。写下面的代码 - 使用DHT22传感器。 12小时后,我的温室加热器低于所需温度时没有开启。

关闭电源并重新开启后,一切恢复正常。我知道这段代码非常混乱 - 但它是否有任何内存泄漏?还是其他可能导致它停止工作的东西?

http://pastebin.com/CcdUN3jb

编辑 - 我发现一个开放的计数器每2秒增加1。我无法想象就是这样,但我在这里改变了它:http://pastebin.com/nuRjHJkR

2 个答案:

答案 0 :(得分:6)

旧军建议:

如果无法修复,请将其涂漆。

这些微控制器中存在看门狗定时器,只是为了让您的工厂保持活力,无论您的代码如何。每次通过循环(),你用一个简单的

喂狗
wdt_reset();

如果您的程序挂起并停止喂狗,MCU将重置。

您可以在setup()中配置监视程序的超时。出于您的目的,您可以使用8秒的大超时,这应该在最长的循环()执行时间上提供巨大的余量。这些传感器读取需要多长时间?

有关简单说明,请参阅Arduino页面中的链接:watchdog

答案 1 :(得分:2)

您的代码中明显存在的一个危险是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';

在这种方法中,内存是静态分配的,并且您在编译时知道程序需要多少内存。