3

SPI経由でnRF24l01 +無線モジュールを使用しているArduinoプロジェクトがあります(このライブラリを使用:http://tmrh20.github.io/RF24/)およびソフトウェアシリアル経由のRFIDリーダー。私はArduinoをスリープ状態にして、メッセージを受信したとき、またはRFIDタグを読み取る準備ができたときに、割り込みを介してArduinoを目覚めさせます。RFID はピン 4 と 5 にあり、nRF はピン 9 ~ 13 と割り込み用の番号 2 をカバーします。

これらのモジュールは両方とも、スリープ コードと割り込みコードを別々に使用すると正常に動作しますが、1 つのスケッチに組み合わせると、Arduino は RFID タグにより起動し、それを読み取り、無線で何かを送信しようとして、ハングします。 write() へのライブラリ呼び出しが戻るのを待っています。

2 つのライブラリについて少し掘り下げましたが、ほとんどの場合、softwareserial ライブラリの頭も尻尾もわかりません。私の nRF モジュールと同じ ISR を舞台裏で使用しているようですが、なぜそれが大きな問題になるのかすぐにはわかりません。また、無線がハングする理由もわかりません。

私はそれがロングショットかもしれないことを知っていますが、誰かが何が起こっているのか知っていますか? 多分誰かがこれらのライブラリを知っていますか?回避策について何か考えはありますか?ありがとう。

4

1 に答える 1

0

私は同じ症状を経験していましたが、問題は私のコードのバッファ オーバーランであることが判明しました。オーバーラン自体は、ライブラリが割り込み処理を中断していたSoftwareSerialため、バイトを削除したことが原因でした。RF24

問題のコードは、 を使用して GPS 受信機から読み取りSoftwareSerial、NMEA センテンスを解析して、 を使用して無線で送信するための緯度と経度の情報を抽出しRF24ます。次のようになります。

if (gpsSerial.available()) {
  int c = gpsSerial.read();
  if (c == '\r') {
    buf[bdx] = '\0';
    // process buf here, which contains a null terminated NMEA sentence
    // and then send via RF24
    bdx = 0;
  else if (c != '\n' && bdx < BUFLEN) buf[bdx++] = c;
}

BUFLEN単一の NMEA センテンスよりも大きくなるようにサイズ設定された場所。

経験豊富な読者は、問題のある行に気付くでしょう:

buf[bdx] = '\0';

範囲チェックなしでbuf に書き込みます。通常の操作では、GPS モジュールからの途切れのない文字列があれば、このコードは正常に機能\rbufます。ただし、情報を送信するRF24と十分な遅延が発生し、 によって文字が削除または破損されるSoftwareSerialため、この仮定は成り立たなくなります。

だから今何が起こるかはこれです:

  1. a\rが失われ、前の NMEA センテンスが破棄されない
  2. 次の NMEA センテンスが読み込まれますbuf
  3. bdxの範囲チェックで停止するまで進みます。else
  4. \r次の NMEA センテンスの反論
  5. buf[bdx] = '\0';の末尾を過ぎて書き込みますbuf

この時点で Arduino は応答を停止し、writeブロックしているように見えます。

修正は、次の行の前に追加されたものifです。

if (bdx >= BUFLEN) bdx = 0;

この行以外に変更を加えることなく、コードは問題なく 5 時間以上実行されるようになりましたwrite

于 2015-12-13T18:05:41.000 に答える