Nrf24L01 with 1 mbed and 1 Arduino Uno

20 May 2012

Hello my fellow mbed peeps, i hope some one could help me with this lil project.

im sending packets from the arduino fine and it's geting ACk back form the mbed reciever but i cant seem to get the mbed side to pick up on the packet in the the radio and print it to the serial. can some one look at this and give me some pointers please.

#include "mbed.h"
#include "nRF24L01P.h"

Serial pc(USBTX, USBRX); // tx, rx
nRF24L01P my_nrf24l01p(p5, p6, p7, p8, p9, p10);    // mosi, miso, sck, csn, ce, irq

int main() {
#define TRANSFER_SIZE 10

char rxData[TRANSFER_SIZE];
    my_nrf24l01p.powerUp();
    my_nrf24l01p.setRfFrequency (2501);
    my_nrf24l01p.setTransferSize(10);
    my_nrf24l01p.setCrcWidth(8);
    my_nrf24l01p.enableAutoAcknowledge(NRF24L01P_PIPE_P0);
    my_nrf24l01p.setRxAddress(0x00F0F0F0F0);
    my_nrf24l01p.setTxAddress(0xF0F0F0F0D2LL);
      // Display the setup of the nRF24L01+ chip
       pc.printf( "nRF24L01+ Frequency    : %d MHz\r\n",  my_nrf24l01p.getRfFrequency() );
       pc.printf( "nRF24L01+ Data Rate    : %d kbps\r\n", my_nrf24l01p.getAirDataRate() );
       pc.printf( "nRF24L01+ TX Address   : 0x%010llX\r\n", my_nrf24l01p.getTxAddress() );
       pc.printf( "nRF24L01+ RX Address   : 0x%010llX\r\n", my_nrf24l01p.getRxAddress() );
       pc.printf( "nRF24L01+ CrC Width    : %d CrC\r\n", my_nrf24l01p.getCrcWidth() );
       pc.printf( "nRF24L01+ TransferSize : %d Paket Size\r\n", my_nrf24l01p.getTransferSize () );
    my_nrf24l01p.setReceiveMode();
    my_nrf24l01p.enable();
       pc.printf( "Setup complete, Starting While loop\r\n");
    
 while (1) {
         if(my_nrf24l01p.readable(NRF24L01P_PIPE_P0)){
               do{
                 my_nrf24l01p.read( NRF24L01P_PIPE_P0, rxData, sizeof( rxData ) );
                 int i;
                 for (i = 0; i > 0; i ++) {
                 pc.printf("Vals : %d\n\r", rxData[i]);  
                 }    
              }while(my_nrf24l01p.readable(NRF24L01P_PIPE_P0)== true );
        }                                           
 }
}

here is the arduino code for refrence if you need.

#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"
#include "printf.h"

  RF24 radio(9,10);
  const uint64_t pipes[2] = { 0xF0F0F0F0E1LL, 0xF0F0F0F0D2LL };
void setup(void)
{
  Serial.begin(57600);
  printf_begin();
  printf("\n\rRadio Setup\n\r");
  radio.begin();
  radio.setDataRate(RF24_2MBPS);
  radio.setCRCLength(RF24_CRC_8);
  radio.setPayloadSize(10);
  radio.setChannel(101);
  radio.setAutoAck(true);
  radio.printDetails();
}
void loop(void)
{
    radio.stopListening();
    radio.openWritingPipe(0x00F0F0F0F0);
    unsigned long time = millis();
    printf("Now sending %lu...",time);
    bool ok = radio.write( &time,sizeof(unsigned long));
      if (ok) 
        printf("ok...\n\r"); 
       else  
        printf("failed.\n\r");
      delay(100);
  }

thanks in advance.

20 May 2012

Hi Cyric,

This bit looks suspicious:

if(my_nrf24l01p.readable(NRF24L01P_PIPE_P0)){
    do {
        my_nrf24l01p.read( NRF24L01P_PIPE_P0, rxData, sizeof( rxData ) );
        int i;
        for (i = 0; i > 0; i ++) {
            pc.printf("Vals : %d\n\r", rxData[i]);  
        }    
    } while(my_nrf24l01p.readable(NRF24L01P_PIPE_P0)== true );
}                                           

Assuming you are successfully entering this if(), the for() loop in your code will never execute.

The structure of a for loop is:

for (initialization; condition; increase) statement;
where
    condition is checked each time around the loop, and if true, the loop continues

In your case, the condition i > 0 will not be true the first time entering the loop (the initialisation sets i = 0), so this loop will never execute. May not be your (only) problem, but something to look at.

A nice explanation of all the control structures can be found here:

Hope that helps,

Simon

20 May 2012

Thanks Simon for helping. i hope you can help some more.

Ok now i do get a trigger but the output is borked it's puting up no more than 3 digits supos to be time in milliseconds coming from the arduino. so the arduino is sending like this Arduino is sending.

Now sending 379...ok...
Now sending 485...ok...
Now sending 590...ok...
Now sending 696...ok...
Now sending 801...ok...
Now sending 907...ok...
Now sending 1011...ok...
Now sending 1117...ok...

mbed is outputing.

Vals : 0
Vals : 0
Vals : 0
Vals : 0
Vals : 137
Vals : 24
Vals : 0
Vals : 0

if i use the pc.putc i get a lot of garbage coming up like trying to open binary in ascii. here is the updated code.

#include "mbed.h"
#include "nRF24L01P.h"

Serial pc(USBTX, USBRX); // tx, rx
nRF24L01P my_nrf24l01p(p5, p6, p7, p8, p9, p10);    // mosi, miso, sck, csn, ce, irq

int main() {
#define TRANSFER_SIZE 8

char rxData[TRANSFER_SIZE];
int rxDataCnt = 0;
    
    my_nrf24l01p.powerUp();
    my_nrf24l01p.setRfFrequency (2501);
    my_nrf24l01p.setTransferSize(8);
    my_nrf24l01p.setCrcWidth(8);
    my_nrf24l01p.enableAutoAcknowledge(NRF24L01P_PIPE_P0);
    my_nrf24l01p.setRxAddress(0x00F0F0F0F0);
    my_nrf24l01p.setTxAddress(0xF0F0F0F0D2LL);
      // Display the setup of the nRF24L01+ chip
       pc.printf( "nRF24L01+ Frequency    : %d MHz\r\n",  my_nrf24l01p.getRfFrequency() );
       pc.printf( "nRF24L01+ Data Rate    : %d kbps\r\n", my_nrf24l01p.getAirDataRate() );
       pc.printf( "nRF24L01+ TX Address   : 0x%010llX\r\n", my_nrf24l01p.getTxAddress() );
       pc.printf( "nRF24L01+ RX Address   : 0x%010llX\r\n", my_nrf24l01p.getRxAddress() );
       pc.printf( "nRF24L01+ CrC Width    : %d CrC\r\n", my_nrf24l01p.getCrcWidth() );
       pc.printf( "nRF24L01+ TransferSize : %d Paket Size\r\n", my_nrf24l01p.getTransferSize () );
    my_nrf24l01p.setReceiveMode();
    my_nrf24l01p.enable();
       pc.printf( "Setup complete, Starting While loop\r\n");
    
 while (1) {

        if ( my_nrf24l01p.readable() ) {
            rxDataCnt = my_nrf24l01p.read( NRF24L01P_PIPE_P0, rxData, sizeof( rxData ) );
            for ( int i = 0; rxDataCnt > 0; rxDataCnt--, i++ ) {
                 pc.printf("Vals : %d\n\r", rxData[i]);                 
               //pc.putc( rxData[i] );
            }
        }
 }
}

agin thanks for the help so far.

20 May 2012

Hi Cyric,

The data you are sending is a 32-bit value (unsigned long). write() takes a pointer to bytes (chars, 8-bit values) to send and the number to send, so you are passing it a pointer to the value and the size of the value in bytes:

unsigned long time = millis();
bool ok = radio.write( &time,sizeof(unsigned long));

i.e. sizeof(unsigned long) should equal 4. Sounds correct.

On the receiving side however, you are reading the bytes individually and displaying them individually. That means you'll just see the value of the bytes making up your time value, not the time itself. The rxData array actually only contains one value, so you should translate it back to one value and display that.

I'm not certain whether you'll need to correct for endianness, but assuming not, you probably want to do something like the following:

while (1) {
    if ( my_nrf24l01p.readable() ) {
        rxDataCnt = my_nrf24l01p.read( NRF24L01P_PIPE_P0, rxData, sizeof( rxData ) );
        unsigned long *time_ptr = (unsigned long*)rxData; // pointer manipulation split out to make working obvious
        unsigned long time = *time_ptr;                   
        pc.printf("Received %d bytes\n\r", rxDataCnt);
        pc.printf("Value = %d\n\r", time);
    }
}

This may not be quite correct, but the first thing to verify is you should now get is one "Value" printout for ever time sent. Once you've confirmed that is the case, you can check the value itself is being decoded correctly.

Hope that is a step in the right direction!

Simon

20 May 2012

worked right out of the box thanks a heep. now i know they can talk fine.

Thanks Simon

05 Dec 2014

Hello, I'm trying to communicate an Arduino UNO to a FRDMKL25Z. I try whit this code, but it doesn't work.

I have the following configuration in KL25:

nRF24L01P my_nrf24l01p(PTD2, PTD3, PTD1, PTD0, PTD5, PTA13); mosi, miso, sck, csn, ce, irq

[....]

my_nrf24l01p.enableAutoAcknowledge(NRF24L01P_PIPE_P0); my_nrf24l01p.setRxAddress(0x00F0F0F0F0); my_nrf24l01p.setTxAddress(0xF0F0F0F0D2LL);

In Arduino Program:

radio.openWritingPipe(0x00F0F0F0F0);

Then I write for this Pipe with radio.write but the program Arduino, always fail when try to write

And the program MBED, never return true in this line:

if(my_nrf24l01p.readable(NRF24L01P_PIPE_P0)){

Thanks!

29 Dec 2014

dont know where my mBed is at the moment also i have not used thos NRFs in a while sorry. does the NRF24 lib example sketches work on the arduino with your modules? if not then it's a wiring issue or your hardware is falting.