我正在尝试设置两个Arduino mircos,一个作为接收器,一个作为控制器,作为我的媒体中心的无线遥控器。
控制器将按钮组合发送给接收器。接收器然后按下相应的键盘组合。
我使用RF24 library from ManiacBug和Arduino micro和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()
。可能是缓冲区正在填满?我对这类事情不太熟悉,所以不确定如何调试。
如果您对我为什么会遇到这种行为有任何见解,或者您有任何调试建议,我会非常感兴趣!
答案 0 :(得分:0)
Arduino上RF24的常见问题是由于模块的电源供电,因为它们可能需要比3.3V线路上的许多arduinos更高的电流。它们是从arduino上的3.3V供电还是为模块提供其他电源?我正在使用电压调节器从arduino的5V线为它们供电,以获得3.3V电压。 例如。 http://www.dx.com/p/ams1117-3-3-3v-power-module-boards-w-indicator-blue-5-pcs-163564#.Vqiu_43Sk-U或使用纯粹的ams1117或类似的,如果你不介意一些焊接。也可能是供电线路上的大约10uF冷凝器就足够了。