4

私はArduinoの世界にまったく慣れていません。DHT22センサーを使用して、次のコードを書きました。12 時間後、希望の温度を下回ったときに、温室のヒーターがオンになりませんでした。

電源をオフにして再度オンにすると、すべて正常に動作するようになりました。このコードが非常に厄介であることはわかっていますが、メモリ リークはありますか? または、それが機能しなくなる原因となっている可能性のある他の何か?

http://pastebin.com/CcdUN3jb

編集 - 2 秒ごとに 1 ずつ増加するオープン カウンターを見つけました。それがそうだったとは想像できませんが、ここで変更しました:http://pastebin.com/nuRjHJkR

4

2 に答える 2

6

旧陸軍のアドバイス:

直らないなら塗装しましょう。

ウォッチドッグ タイマーは、コードに関係なくプラントを維持する目的で、これらのマイクロコントローラーに存在します。loop() を通過するたびに、犬に単純な餌を与えます

wdt_reset();

プログラムがハングして犬への餌やりを停止すると、MCU がリセットされます。

setup() でウォッチドッグのタイムアウトを設定します。目的のために、最長の loop() 実行時間に大きなマージンを提供する 8 秒の大きなタイムアウトを使用できます。これらのセンサーの読み取りにはどのくらいの時間がかかりますか?

簡単な説明については、Arduino ページからのリンクを参照してください: ウォッチドッグ

于 2013-01-15T06:28:33.343 に答える
2

コードで明らかな 1 つの危険は 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 を使用すると、予期しない文字列変換を引き起こす 100 万件のデータ エラーに 1 件のエラーが発生しても、安全にコードを実行し続けることができます。

このように、ループ内で char buf[] を割り当てるメリットはあまりありません。プログラムは loop() を無限に実行するだけなので、これをスタック上のローカル変数にすることでメモリ リソースを節約することにはなりません。スタックメモリが使用されていない微視的なウィンドウのみがあります。しかし、スタック上にあるため、オーバーフロー buf を実行すると、オーバーフローによって戻りアドレスが消去され、プログラムがクラッシュする可能性があります。それはすべて危険であり、ノーリターンです。

このように考えてください

const size_t sizeBuf = 128;
char szBuf[128+1];

void loop() {
 ...

 snprintf(szBuf, sizeBuf, "Integer......", ... );
 szBuf[sizeBuf] = '\0';

この方法では、メモリが静的に割り当てられ、コンパイル時にプログラムに必要なメモリ量がわかります。

于 2013-01-15T06:01:09.480 に答える