This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Advice for simple communication from nrf51822 to nrf24l01 ?

Hi everyone ! I'm trying to send data from an nrf51822 to an nrf24l01 with arduino and I guess I'm doing something wrong...

For the moment I succeeded to have these talking together:

...so I guess the hardware is not the problem :) (if you're curious about the context, the project is explained here: hackster.io/cedric/twi)

I looked for similar problems on the forum but I don't find the solution to my problem, if anyone has a suggestion I would be infinitely grateful ;D

Here is the configuration I use:

nrf51 (TX): radio_config.c main.c

nrf24 (RX) with arduino: Mirf.cpp RX.ino

I used the nrf51 sdk suggestions and an nrf24 library (+datasheets) to understand it, but it doesn't work (yet!), the nrf24 reception pipe stays empty.

Anyone has any suggestion to offer ? Thanks a lot !! ;)

  • (1/3)

    Apologies for the delay - been busy. The code below (spread over 3 messages) is running on a Raspberry Pi Model B with an NRF24L01 board, and an NRF51822 without softdevice.

    At the RPi end, the enableAckPayload routine in maniacbug's RF24.cpp needs to be modified so that both the writeregister commands set the EN_DYN_ACK register too. ie. change from:

    write_register(FEATURE,read_register(FEATURE) | _BV(EN_ACK_PAY) | _BV(EN_DPL) );
    

    to

    write_register(FEATURE,read_register(FEATURE) | _BV(EN_ACK_PAY) | _BV(EN_DPL) | _BV(EN_DYN_ACK) );
    
  • (2/3) Bare bones of the RPi code that calls the RF24 routines:

    #include "../RF24.h";
    

    RF24 radio("/dev/spidev0.0",8000000 , 25);
    const int role_pin = 7; const uint64_t pipes[2] = { 0xF0F0F0F0E1LL, 0xF0F0F0F0D2LL };

    void rf24setup(void){

    radio.begin(); radio.setRetries( 15, 15); radio.setChannel(0x05); radio.setPALevel(RF24_PA_MAX); radio.setPALevel(RF24_PA_MAX); radio.setDataRate(RF24_1MBPS); radio.setPayloadSize(0x0c); radio.enableAckPayload();

    radio.openWritingPipe(pipes[0]); radio.openReadingPipe(1,pipes[1]); radio.startListening(); radio.printDetails(); }

    int main( int argc, char *argv[]){

    // Declarations
    uint8_t message[12];
    
        // Initialise radio (and print settings to screen)
        rf24setup();
    
    // Finishing
    while (1)
    {
    	radio.startListening(); // Start listening for incoming messages
    
    	while ( ! radio.available() ) { // Wait for a message
    		__msleep(10);
    	}
    
    	radio.read( &message,12); // Get the message
    
    	// do something with message here	
                
    	radio.stopListening(); // stop listening so we can send an acknowledgement
    	radio.writeAckPayload(2,&message,13);
    }
    

    }

  • (3/3) Bare-bones of NRF51822 transmitting code:

    #include "micro_esb.h"
    

    #include "uesb_error_codes.h"

    static uesb_payload_t tx_payload, rx_payload;

    void uesb_event_handler() { static uint32_t rf_interrupts; static uint32_t tx_attempts;

    uesb_get_clear_interrupts(&rf_interrupts);
    
    if(rf_interrupts & UESB_INT_TX_SUCCESS_MSK)
    {   
    			ackd=true;
    	}
    
    if(rf_interrupts & UESB_INT_TX_FAILED_MSK)
    {
        uesb_flush_tx();
    }
    
    if(rf_interrupts & UESB_INT_RX_DR_MSK)
    {
        uesb_read_rx_payload(&rx_payload);
        NRF_GPIO->OUTCLR = 0xFUL << 8;
        NRF_GPIO->OUTSET = (uint32_t)((rx_payload.data[2] & 0x0F) << 8);
    }
    
    uesb_get_tx_attempts(&tx_attempts);
    NRF_GPIO->OUTCLR = 0xFUL << 12;
    NRF_GPIO->OUTSET = (tx_attempts & 0x0F) << 12;
    

    }

    int main(void) {

    // Put power up high for testing purposes
    uesb_set_tx_power(UESB_TX_POWER_4DBM);
    
    // Set receive address
    uint8_t rx_addr_p0[] = {0xD2, 0xF0, 0xF0, 0xF0, 0xF0};
    uint8_t rx_addr_p1[] = {0xE1, 0xF0, 0xF0, 0xF0, 0xF0};
    uint8_t rx_addr_p2   = 0x66;	
    
    // Start the high-frequency clock - we'll need it for the radio
    NRF_CLOCK->EVENTS_HFCLKSTARTED = 0;
    NRF_CLOCK->TASKS_HFCLKSTART = 1;
    while(NRF_CLOCK->EVENTS_HFCLKSTARTED == 0);	
    
    // Configure the radio
    uesb_config_t uesb_config       = UESB_DEFAULT_CONFIG;
    uesb_config.rf_channel          = 5;
    uesb_config.crc                 = UESB_CRC_16BIT;
    uesb_config.retransmit_count    = 6;
    uesb_config.retransmit_delay    = 500;
    uesb_config.dynamic_ack_enabled = true;
    uesb_config.protocol            = UESB_PROTOCOL_ESB_DPL;
    uesb_config.bitrate             = UESB_BITRATE_1MBPS;
    uesb_config.event_handler       = uesb_event_handler;
    
    uesb_init(&uesb_config);
    uesb_set_address(UESB_ADDRESS_PIPE0, rx_addr_p0);
    uesb_set_address(UESB_ADDRESS_PIPE1, rx_addr_p1);
    uesb_set_address(UESB_ADDRESS_PIPE2, &rx_addr_p2);
    
    // Load the payload with some dummy information
    tx_payload.length  = 13;
    tx_payload.pipe    = 0;
    tx_payload.data[0] = 0x01;
    tx_payload.data[1] = 0x02;
    tx_payload.data[2] = 0x03;
    tx_payload.data[3] = 0x04;
    
    
    while (true)
    {
    
    			// -------------- TRANSMIT ---------------------
    		
    			if(uesb_write_tx_payload(&tx_payload) == UESB_SUCCESS)
    			{
    					tx_payload.data[0]++;
    			}
    		
    			nrf_delay_ms(100);
    			
    		
    			
    }
    

    }

  • Apologies for formatting issues (and abuse of commenting system for posting code)!

  • Hi Gavin, Thanks so much! This is super helpful. I got this up and running pretty well on an arduino, and can post back to my github for others once I'm done cleaning it up a bit.

    One other question - when running this code are you properly receiving acks back to the 51822 that cause the success portion of the uesb_event_handler to run? I seem to only be entering the failed portion of that function.

Related