Я пытаюсь установить два Arduino mircos, один в качестве приемника и один в качестве контроллера, для беспроводного пульта для моего медиацентра.RF24 и Arduino Micro испытывают потерю пакетов
Контроллер отправляет комбинации кнопок в приемник. Затем приемник подталкивает соответствующие комбинации клавиш.
Я использую RF24 library from ManiacBug с микрофонами Arduino и приемопередатчиками NRF24L01 +.
Я хочу, чтобы контроллер оставался в режиме записи, а приемник - в режиме прослушивания. Существует не так много причин для переключения режимов, поскольку связь является односторонней. (Я мог бы добавить автоматическое подтверждение для двойных проверочных пакетов, но вот в этом смысл.)
Моя проблема в том, что если я сохраню их каждый в соответствующем режиме, общение очень противоречиво и чаще всего терпит неудачу.
Код для контроллера
#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"
#include "printf.h"
RF24 radio(9,10);
// Radio pipe addresses for the 2 nodes to communicate.
const uint64_t pipes[2] = { 0xF0F0F0F0E1LL, 0xF0F0F0F0D2LL };
// button
const unsigned short nButtons = 2;
const unsigned short buttonPin[] = {6,7};
unsigned curr,prev;
unsigned short getButtons(const unsigned short nButtons,
const unsigned short * const buttonPin);
unsigned short getButtons(const unsigned short nButtons,
const unsigned short * const buttonPin){
// write each button to a bit
unsigned short i,buttons = 0,state;
for(i = 0; i < nButtons; ++i){
state = digitalRead(buttonPin[i]);
if(state == HIGH){
buttons |= (1u << i);
}
}
return buttons;
}
void setup(void){
Serial.begin(57600);
printf_begin();
radio.begin();
// optionally, increase the delay between retries & # of retries
radio.setRetries(15,15);
// optionally, reduce the payload size. seems to
// improve reliability
radio.setPayloadSize(sizeof(unsigned short));
radio.openWritingPipe(pipes[0]);
unsigned short i;
for(i = 0; i < nButtons; ++i)
pinMode(buttonPin[i],INPUT);
curr = prev = 0;
}
void loop(void){
curr = getButtons(nButtons,buttonPin);
if(curr != prev){
printf("Buttons: %u\n\r",curr);
bool ok = radio.write(&curr, sizeof(unsigned short));
prev = curr;
if (ok)
printf("sent.\n\r");
else
printf("failed.\n\r");
// have to cycle listening otherwise communication fails
radio.startListening();
radio.stopListening();
}
}
И приемник
#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"
#include "printf.h"
RF24 radio(9,10);
// Radio pipe addresses for the 2 nodes to communicate.
const uint64_t pipes[2] = { 0xF0F0F0F0E1LL, 0xF0F0F0F0D2LL };
const unsigned short nButtons = 2;
const unsigned short keys[] = {216, // left
215}; // right
const char* name[] = {"LEFT","RIGHT"};
unsigned short curr = 0,prev = 0;
void keyMap(const unsigned short curr, const unsigned short prev,
const unsigned short nButtons){
// map the button changes to keyboard commands
unsigned short i,change;
change = curr^prev;
for(i = 0; i < nButtons; ++i){
if((change & (1u << i)) && (curr & (1u << i))){
printf("Press %s\n\r",name[i]);
Keyboard.press(keys[i]);
}
else if(change & (1u << i)){
printf("Release %s\n\r",name[i]);
Keyboard.release(keys[i]);
}
}
}
void setup(void){
Serial.begin(57600);
printf_begin();
radio.begin();
// optionally, increase the delay between retries & # of retries
radio.setRetries(15,15);
// optionally, reduce the payload size. seems to
// improve reliability
radio.setPayloadSize(sizeof(unsigned short));
radio.openReadingPipe(1,pipes[0]);
radio.startListening();
Keyboard.begin();
curr = prev = 0;
}
void loop(void){
// if there is data ready
if (radio.available()){
// Dump the payloads until we've gotten everything
unsigned short got_buttons;
bool done = false;
while (!done){
// Fetch the payload, and see if this was the last one.
done = radio.read(&got_buttons, sizeof(unsigned short));
curr = got_buttons;
keyMap(curr,prev,nButtons);
prev = curr;
printf("Got payload %u.\n\r",got_buttons);
}
}
}
Проблема у меня в коде контроллера. Я должен иметь radio.startListening(); radio.stopListening();
, иначе передача будет происходить почти каждый раз. Если вы удалите эти два утверждения, тогда сообщение будет проходить, если вы быстро нажмете кнопку.
Я открыл исходный код для этих двух методов и заметил, что оба они звонят flush_tx()
и flush_rx()
. Может быть, буферы заполняются? Я не слишком хорошо разбираюсь в подобных вещах, поэтому не уверен, как отлаживать.
Если у вас есть представление о том, почему я получаю такое поведение, или если у вас есть предложения по отладке, мне было бы очень интересно!
удален - ошибка – MortenSickel