コードで明らかな 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';
この方法では、メモリが静的に割り当てられ、コンパイル時にプログラムに必要なメモリ量がわかります。