RF24和Arduino Micro遇到丢包问题

时间:2015-06-05 00:47:03

标签: c++ arduino

我正在尝试设置两个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()。可能是缓冲区正在填满?我对这类事情不太熟悉,所以不确定如何调试。

如果您对我为什么会遇到这种行为有任何见解,或者您有任何调试建议,我会非常感兴趣!

1 个答案:

答案 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冷凝器就足够了。