3

我有一个 Arduino 项目,它在 SPI 上使用 nRF24l01+ 无线电模块(使用此库:http ://tmrh20.github.io/RF24/ )和在软件序列上的 RFID 阅读器。我正在睡觉我的 Arduino,并让他们在收到消息或准备读取 RFID 标签时通过中断将其唤醒。RFID 位于引脚 4 和 5 上,而 nRF 覆盖引脚 9 - 13 以及用于中断的 2 号引脚。

这两个模块都可以分别与睡眠和中断代码一起正常工作,但是当组合成一个草图时,Arduino 会由于 RFID 标签而唤醒,读取它,然后尝试通过无线电发送一些东西,然后就挂了,等待库调用 write() 返回。

我已经深入研究了这两个库,但我大多无法确定软件序列库的正面或反面。它似乎可能在幕后使用与我的 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;
}

WhereBUFLEN的大小比任何单个 NMEA 句子都大。

有经验的读者会发现有问题的行:

buf[bdx] = '\0';

在没有范围检查的情况下写入 buf 。\r在正常操作中,来自 GPS 模块的不间断字符流,此代码工作正常,因为我们总是会遇到buf. 但是,通过发送信息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;

write除了这一行之外没有其他修改,代码现在已经运行了超过 5 个小时而没有问题,而以前它在“阻塞”之前不会持续超过 30 秒。

于 2015-12-13T18:05:41.000 回答