2015-10-10 7 views
2

У меня есть проект Arduino, который использует радиомодуль nRF24l01 + через SPI (используя эту библиотеку: http://tmrh20.github.io/RF24/) и считыватель RFID по программному обеспечению. Я сплю своего Arduino и заставляю их разбудить его через прерывание, когда получено сообщение или метка RFID готова к чтению. RFID находится на выводах 4 и 5, в то время как nRF покрывает контакты 9-13, а также номер 2 для его прерывания.Arduino softwareserial сталкивается с SPI?

Оба эти модуля работают нормально с кодом сна и прерывания отдельно, но когда они объединены в один эскиз, Arduino будет просыпаться из-за метки RFID, читать его, а затем попытаться отправить что-то по радио и затем просто зависайте, ожидая вызова библиотеки для записи() для возврата.

Я немного углубился в две библиотеки, но в основном я не могу сделать головы или хвосты библиотеки программного обеспечения. Кажется, может быть, использовать тот же ISR за кулисами, что и мой модуль nRF, но я не сразу понимаю, почему это должно быть большой проблемой, и я не понимаю, почему это должно привести к зависанию радио.

Я знаю, что это может быть длинный выстрел, но кто-нибудь может понять, что может быть? Может быть, кто-нибудь знает эти библиотеки? Любые мысли о работе вокруг? Благодарю.

+0

Вы имеете в виду программное обеспечение SPI с RFID-считывателем? –

+0

RFID-считыватель использует программное обеспечение, поэтому использует протокол типа UART. NRF использует SPI. – MaxStrange

+0

, так что я принимаю его, аппаратные последовательные порты все взяты? В любом случае, они должны хорошо работать вместе. Как работает питание на радио? отдельный запас? это uno? если это uno, и вы используете 3.3v, я бы использовал отдельный источник 3.3v, поскольку текущая емкость его довольно маленькая, и добавление другого устройства, например, могло бы заставить его перестать работать. Однако, если это не так, то после прочтения с RFID отключите серийный номер программного обеспечения, чтобы он не отключил прерывания (в случае, если он получает другую при попытке передать). посмотрите, работает ли он. его проблема с программным обеспечением или проблема с электропитанием. –

ответ

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';

Который пишет ЬиЕ без проверки диапазона. При нормальной работе с непрерывным потоком символов из модуля GPS этот код работает нормально, потому что мы всегда будем сталкиваться с \r до того, как закончим пространство buf. Однако отправка информации по RF24 вызывает достаточно задержек, когда символы отбрасываются или повреждаются SoftwareSerial, и это предположение больше не выполняется.

Так что теперь это происходит:

  1. \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 часов без проблем, в то время как ранее он не будет длиться более За 30 секунд до write «блоки».