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

NRF24L01+ PIPE SETTINGS

Hello,

i just want setup 1Tx and 1 RX using NRF24L01+ chips. but i am confused what should be Transmitter side Tx & Rx and what should be in Rx Tx & RX ? in order to use auto-ack feature.

which addresses sould be kept in Transmitter and Receiver side ? could you please explain with some example as i am not able to understand...

Please help

Thanks

  • Hi,

    You set which role the nRF24L01+ has in the CONFIG register, bit 0 (field called "PRIM_RX"). This controls if the device is a Primary Receiver (PRX) or a Primary Transmitter (PTX).

    All the other configurations can be left untouched for a simple functional test. Now you can upload payloads (3 bytes length by default) to the FIFO. When you then pulse pin "CE" for >10us, the radio will start to transmit the payload over-the-air.

    Check out the "nRFgo SDK" (enhanched_shockburst_examples) if you want to see the flow: www.nordicsemi.com/.../nRFgo-SDK

    It's written for our nRF24L-series SoC-parts, but the radio interface is basically the same.

    Best regards Håkon

  • Hi Hakon,

    As per your instructions i did program my both the chips still led on the receiver is not getting ON. please check whats wrong with it ? any suggestions ?

    please help :(

    Transmitter Code

    
    #include <xc.h>
    #include <htc.h>
    
    __CONFIG(FOSC_HS & WDTE_OFF & PWRTE_OFF & MCLRE_OFF & BOREN_OFF & LVP_OFF & CPD_OFF & CP_OFF);
    #define	_XTAL_FREQ	20000000
    
    
    #include "stdint.h"
    /* Memory Map */
    #define CONFIG      0x00
    #define EN_AA       0x01
    #define EN_RXADDR   0x02
    #define SETUP_AW    0x03
    #define SETUP_RETR  0x04
    #define RF_CH       0x05
    #define RF_SETUP    0x06
    #define STATUS      0x07
    #define OBSERVE_TX  0x08
    #define CD          0x09
    #define RX_ADDR_P0  0x0A
    #define RX_ADDR_P1  0x0B
    #define RX_ADDR_P2  0x0C
    #define RX_ADDR_P3  0x0D
    #define RX_ADDR_P4  0x0E
    #define RX_ADDR_P5  0x0F
    #define TX_ADDR     0x10
    #define RX_PW_P0    0x11
    #define RX_PW_P1    0x12
    #define RX_PW_P2    0x13
    #define RX_PW_P3    0x14
    #define RX_PW_P4    0x15
    #define RX_PW_P5    0x16
    #define FIFO_STATUS 0x17
    #define DYNPD       0x1C
    
    /* Bit Mnemonics */
    
    /* configuratio nregister */
    #define MASK_RX_DR  6
    #define MASK_TX_DS  5
    #define MASK_MAX_RT 4
    #define EN_CRC      3
    #define CRCO        2
    #define PWR_UP      1
    #define PRIM_RX     0
    
    /* enable auto acknowledgment */
    #define ENAA_P5     5
    #define ENAA_P4     4
    #define ENAA_P3     3
    #define ENAA_P2     2
    #define ENAA_P1     1
    #define ENAA_P0     0
    
    /* enable rx addresses */
    #define ERX_P5      5
    #define ERX_P4      4
    #define ERX_P3      3
    #define ERX_P2      2
    #define ERX_P1      1
    #define ERX_P0      0
    
    /* setup of address width */
    #define AW          0 /* 2 bits */
    
    /* setup of auto re-transmission */
    #define ARD         4 /* 4 bits */
    #define ARC         0 /* 4 bits */
    
    /* RF setup register */
    #define PLL_LOCK    4
    #define RF_DR_HIGH  3
    #define RF_PWR      1 /* 2 bits */
    
    /* general status register */
    #define RX_DR       6
    #define TX_DS       5
    #define MAX_RT      4
    #define RX_P_NO     1 /* 3 bits */
    #define TX_FULL     0
    
    /* transmit observe register */
    #define PLOS_CNT    4 /* 4 bits */
    #define ARC_CNT     0 /* 4 bits */
    
    /* fifo status */
    #define TX_REUSE    6
    #define FIFO_FULL   5
    #define TX_EMPTY    4
    #define RX_FULL     1
    #define RX_EMPTY    0
    
    /* dynamic length */
    #define DPL_P0      0
    #define DPL_P1      1
    #define DPL_P2      2
    #define DPL_P3      3
    #define DPL_P4      4
    #define DPL_P5      5
    
    /* Instruction Mnemonics */
    #define R_REGISTER    0x00 /* last 4 bits will indicate reg. address */
    #define W_REGISTER    0x20 /* last 4 bits will indicate reg. address */
    #define REGISTER_MASK 0x1F
    #define R_RX_PAYLOAD  0x61
    #define W_TX_PAYLOAD  0xA0
    #define FLUSH_TX      0xE1
    #define FLUSH_RX      0xE2
    #define REUSE_TX_PL   0xE3
    #define ACTIVATE      0x50
    #define R_RX_PL_WID   0x60
    #define NOP1          0xFF
    
    #define nrf24_CONFIG ((1 << MASK_RX_DR)|(1<<EN_CRC)|(0<<CRCO))
    
    /// hardware spi pin defined
    #define LED_PIN      PORTAbits.RA1 // led test
    #define CS_Pin       PORTBbits.RB0//          //set port as output
    #define CE_Pin       PORTBbits.RB4         //set port as output
    #define SCK_Pin      PORTBbits.RB1        //set port as output
    #define Mosi_Pin     PORTBbits.RB2         //set port as output
    #define Miso_Pin     PORTBbits.RB3        //set port as input
    #define HIGH         1
    #define LOW          0
    
    
    
    void nrf24_ce_digitalwrite(uint8_t state)
    {
    if (state)
    {
    CE_Pin = 1;
    }
    else
    {
    CE_Pin = 0;
    }
    }
    
    
    void nrf24_csn_digitalwrite(uint8_t state)
    {
    if (state)
    {
    CS_Pin = 1;
    }
    else
    {
    CS_Pin = 0;
    }
    }
    
    
    void nrf24_sck_digitalwrite(uint8_t state)
    {
    if (state)
    {
    SCK_Pin = 1;
    }
    else
    {
    SCK_Pin = 0;
    }
    }
    
    
    void nrf24_mosi_digitalwrite( uint8_t state)
    {
    if (state)
    {
    Mosi_Pin = 1;
    }
    else
    {
    Mosi_Pin = 0;
    }
    }
    
    
    
    /* software spi routine */
    uint8_t spi_transfer(uint8_t tx)
    {
         uint8_t i = 0;
         uint8_t rs = 0;
    
        nrf24_sck_digitalwrite(LOW);
    
        for(i=0;i<8;i++)
        {
    
            if(tx & 0x80) // msbit first spi standard
            {
                nrf24_mosi_digitalwrite(HIGH);
            }
            else
            {
                nrf24_mosi_digitalwrite(LOW);
            }
    
            nrf24_sck_digitalwrite(HIGH);
    
            tx = tx << 1;
            if(Miso_Pin == 1)
            {
                rs |= 0x01;
            }
            nrf24_sck_digitalwrite(LOW);
        }
        return rs;
    }
    
    
    /* send and receive multiple bytes over SPI */ // checked with mirf
    void nrf24_transferSync(uint8_t  *dataout,uint8_t *datain,uint8_t len)
    {
        uint8_t i;
    
        for(i=0;i<len;i++){
           datain[i] = spi_transfer(dataout[i]);
        }
    }
    
    
    //send multiple bytes over SPI // checked with mirf
    void nrf24_transmitSync(uint8_t *dataout,uint8_t len)
    {
        uint8_t i;
    
        for(i=0;i<len;i++){
          spi_transfer(dataout[i]);
        }
    }
    
    void nrf24_configRegister(uint8_t reg, uint8_t value)
    {
        nrf24_csn_digitalwrite(LOW);
        spi_transfer(W_REGISTER | (REGISTER_MASK & reg));
        spi_transfer(value);
        nrf24_csn_digitalwrite(HIGH);
    }
    
    void nrf24_powerUpTx() // checked with mirf
    {
       // PTX = 1;
    	
        nrf24_configRegister(CONFIG,nrf24_CONFIG|((1<<PWR_UP)|(0<<PRIM_RX)));
    
    }
    
    void nrf24_init()
    {
    	TRISB = 0b00001000;
    	TRISA = 0b00000000;
        CMCON  |= 7;
        nrf24_ce_digitalwrite(LOW);
        nrf24_csn_digitalwrite(HIGH);
    }
    
    
    void nrf24_send(uint8_t* value)   // check with mirf
    {
        /* Go to Standby-I first */
        nrf24_ce_digitalwrite(LOW);
    
        /* Set to transmitter mode , Power up if needed */
        nrf24_powerUpTx();
    	nrf24_csn_digitalwrite(LOW);
    	spi_transfer(FLUSH_TX);
    	nrf24_csn_digitalwrite(HIGH);
       
    
        /* Pull down chip select */
        nrf24_csn_digitalwrite(LOW);
    
        /* Write cmd to write payload */
        spi_transfer(W_TX_PAYLOAD);
    
        /* Write payload */
        nrf24_transmitSync(value,3);
    
        /* Pull up chip select */
        nrf24_csn_digitalwrite(HIGH);
    
        /* Start the transmission */
        nrf24_ce_digitalwrite(HIGH);
    
    }
    
    uint8_t data_array[3];
    
    void main()
    {
    
    nrf24_init();
    nrf24_powerUpTx();
    
    nrf24_csn_digitalwrite(LOW);
    spi_transfer(FLUSH_TX);
    nrf24_csn_digitalwrite(HIGH);
    
    
    
    
    
    while(1)
    {
    data_array[0] = 0x6F;
    data_array[1] = 0X12;
    data_array[2] = 0x12;
    
    
    nrf24_send(data_array);
    __delay_us(15); // wait some time
    }
    
    
    }
    
    
    
    

    Receiver Code

    
    #include <xc.h>
    #include <htc.h>
    
    __CONFIG(FOSC_HS & WDTE_OFF & PWRTE_OFF & MCLRE_OFF & BOREN_OFF & LVP_OFF & CPD_OFF & CP_OFF);
    #define	_XTAL_FREQ	20000000
    
    
    #include "stdint.h"
    /* Memory Map */
    #define CONFIG      0x00
    #define EN_AA       0x01
    #define EN_RXADDR   0x02
    #define SETUP_AW    0x03
    #define SETUP_RETR  0x04
    #define RF_CH       0x05
    #define RF_SETUP    0x06
    #define STATUS      0x07
    #define OBSERVE_TX  0x08
    #define CD          0x09
    #define RX_ADDR_P0  0x0A
    #define RX_ADDR_P1  0x0B
    #define RX_ADDR_P2  0x0C
    #define RX_ADDR_P3  0x0D
    #define RX_ADDR_P4  0x0E
    #define RX_ADDR_P5  0x0F
    #define TX_ADDR     0x10
    #define RX_PW_P0    0x11
    #define RX_PW_P1    0x12
    #define RX_PW_P2    0x13
    #define RX_PW_P3    0x14
    #define RX_PW_P4    0x15
    #define RX_PW_P5    0x16
    #define FIFO_STATUS 0x17
    #define DYNPD       0x1C
    
    /* Bit Mnemonics */
    
    /* configuratio nregister */
    #define MASK_RX_DR  6
    #define MASK_TX_DS  5
    #define MASK_MAX_RT 4
    #define EN_CRC      3
    #define CRCO        2
    #define PWR_UP      1
    #define PRIM_RX     0
    
    /* enable auto acknowledgment */
    #define ENAA_P5     5
    #define ENAA_P4     4
    #define ENAA_P3     3
    #define ENAA_P2     2
    #define ENAA_P1     1
    #define ENAA_P0     0
    
    /* enable rx addresses */
    #define ERX_P5      5
    #define ERX_P4      4
    #define ERX_P3      3
    #define ERX_P2      2
    #define ERX_P1      1
    #define ERX_P0      0
    
    /* setup of address width */
    #define AW          0 /* 2 bits */
    
    /* setup of auto re-transmission */
    #define ARD         4 /* 4 bits */
    #define ARC         0 /* 4 bits */
    
    /* RF setup register */
    #define PLL_LOCK    4
    #define RF_DR_HIGH  3
    #define RF_PWR      1 /* 2 bits */
    
    /* general status register */
    #define RX_DR       6
    #define TX_DS       5
    #define MAX_RT      4
    #define RX_P_NO     1 /* 3 bits */
    #define TX_FULL     0
    
    /* transmit observe register */
    #define PLOS_CNT    4 /* 4 bits */
    #define ARC_CNT     0 /* 4 bits */
    
    /* fifo status */
    #define TX_REUSE    6
    #define FIFO_FULL   5
    #define TX_EMPTY    4
    #define RX_FULL     1
    #define RX_EMPTY    0
    
    /* dynamic length */
    #define DPL_P0      0
    #define DPL_P1      1
    #define DPL_P2      2
    #define DPL_P3      3
    #define DPL_P4      4
    #define DPL_P5      5
    
    /* Instruction Mnemonics */
    #define R_REGISTER    0x00 /* last 4 bits will indicate reg. address */
    #define W_REGISTER    0x20 /* last 4 bits will indicate reg. address */
    #define REGISTER_MASK 0x1F
    #define R_RX_PAYLOAD  0x61
    #define W_TX_PAYLOAD  0xA0
    #define FLUSH_TX      0xE1
    #define FLUSH_RX      0xE2
    #define REUSE_TX_PL   0xE3
    #define ACTIVATE      0x50
    #define R_RX_PL_WID   0x60
    #define NOP1          0xFF
    
    #define nrf24_CONFIG ((1 << MASK_RX_DR)|(1<<EN_CRC)|(0<<CRCO))
    
    /// hardware spi pin defined
    #define LED_PIN      PORTAbits.RA1 // led test
    #define CS_Pin       PORTBbits.RB0//          //set port as output
    #define CE_Pin       PORTBbits.RB4         //set port as output
    #define SCK_Pin      PORTBbits.RB1        //set port as output
    #define Mosi_Pin     PORTBbits.RB2         //set port as output
    #define Miso_Pin     PORTBbits.RB3        //set port as input
    #define HIGH         1
    #define LOW          0
    
    
    
    void nrf24_ce_digitalwrite(uint8_t state)
    {
    if (state)
    {
    CE_Pin = 1;
    }
    else
    {
    CE_Pin = 0;
    }
    }
    
    
    void nrf24_csn_digitalwrite(uint8_t state)
    {
    if (state)
    {
    CS_Pin = 1;
    }
    else
    {
    CS_Pin = 0;
    }
    }
    
    
    void nrf24_sck_digitalwrite(uint8_t state)
    {
    if (state)
    {
    SCK_Pin = 1;
    }
    else
    {
    SCK_Pin = 0;
    }
    }
    
    
    void nrf24_mosi_digitalwrite( uint8_t state)
    {
    if (state)
    {
    Mosi_Pin = 1;
    }
    else
    {
    Mosi_Pin = 0;
    }
    }
    
    
    
    /* software spi routine */
    uint8_t spi_transfer(uint8_t tx)
    {
         uint8_t i = 0;
         uint8_t rs = 0;
    
        nrf24_sck_digitalwrite(LOW);
    
        for(i=0;i<8;i++)
        {
    
            if(tx & 0x80) // msbit first spi standard
            {
                nrf24_mosi_digitalwrite(HIGH);
            }
            else
            {
                nrf24_mosi_digitalwrite(LOW);
            }
    
            nrf24_sck_digitalwrite(HIGH);
    
            tx = tx << 1;
            if(Miso_Pin == 1)
            {
                rs |= 0x01;
            }
            nrf24_sck_digitalwrite(LOW);
        }
        return rs;
    }
    
    
    
    
    /* send and receive multiple bytes over SPI */ // checked with mirf
    void nrf24_transferSync(uint8_t  *dataout,uint8_t *datain,uint8_t len)
    {
        uint8_t i;
    
        for(i=0;i<len;i++){
           datain[i] = spi_transfer(dataout[i]);
        }
    }
    
    
    //send multiple bytes over SPI // checked with mirf
    void nrf24_transmitSync(uint8_t *dataout,uint8_t len)
    {
        uint8_t i;
    
        for(i=0;i<len;i++){
          spi_transfer(dataout[i]);
        }
    }
    
    void nrf24_configRegister(uint8_t reg, uint8_t value)
    {
        nrf24_csn_digitalwrite(LOW);
        spi_transfer(W_REGISTER | (REGISTER_MASK & reg));
        spi_transfer(value);
        nrf24_csn_digitalwrite(HIGH);
    }
    
    void nrf24_powerUpTx() // checked with mirf
    {
       // PTX = 1;
    
        nrf24_configRegister(CONFIG,nrf24_CONFIG|((1<<PWR_UP)|(0<<PRIM_RX)));
        
    }
    
    
    void nrf24_powerUpRx() // checked with mirf
    {
       // PTX = 0;
    	
        nrf24_configRegister(CONFIG,nrf24_CONFIG|((1<<PWR_UP)|(1<<PRIM_RX)));
    	
    }
    
    void nrf24_init()
    {
    	TRISB = 0b00001000;
    	TRISA = 0b00000000;
        CMCON  |= 7;
        nrf24_ce_digitalwrite(LOW);
        nrf24_csn_digitalwrite(HIGH);
    }
    
    
    void nrf24_send(uint8_t* value)   // check with mirf
    {
        /* Go to Standby-I first */
        nrf24_ce_digitalwrite(LOW);
    
        /* Set to transmitter mode , Power up if needed */
        nrf24_powerUpTx();
    	nrf24_csn_digitalwrite(LOW);
    	spi_transfer(FLUSH_TX);
    	nrf24_csn_digitalwrite(HIGH);
       
    
        /* Pull down chip select */
        nrf24_csn_digitalwrite(LOW);
    
        /* Write cmd to write payload */
        spi_transfer(W_TX_PAYLOAD);
    
        /* Write payload */
        nrf24_transmitSync(value,3);
    
        /* Pull up chip select */
        nrf24_csn_digitalwrite(HIGH);
    
        /* Start the transmission */
        nrf24_ce_digitalwrite(HIGH);
    
    }
    
    /* Read single register from nrf24 */
    void nrf24_readRegister(uint8_t reg,uint8_t *value,uint8_t len) //checked with mirf
    {
        nrf24_csn_digitalwrite(LOW);
        spi_transfer(R_REGISTER | (REGISTER_MASK & reg));
        nrf24_transferSync(value,value,len);
        nrf24_csn_digitalwrite(HIGH);
    	}
    
    
    
    uint8_t nrf24_getStatus()    // checked with mirf
    {
        uint8_t rv;
        nrf24_readRegister(STATUS,&rv,1);
        return rv;
    }
    
    
    uint8_t nrf24_dataReady() // check with mirf
    // checks if data is available for reading
    
    {
        // See note in getData() function - just checking RX_DR isn't good enough
        uint8_t status = nrf24_getStatus();
    
     // We can short circuit on RX_DR, but if it's not set, we still need
        // to check the FIFO for any pending packets
       return status & (1 << RX_DR);
    }
    
    
    /* Reads payload bytes uint8_to data array */
    uint8_t nrf24_getData(uint8_t *data1)  // check with mirf
    {
        /* Pull down chip select */
        nrf24_csn_digitalwrite(LOW);
    
        /* Send cmd to read rx payload */
        spi_transfer(R_RX_PAYLOAD);
    
        /* Read payload */
        nrf24_transferSync(data1,data1,3);
    
        /* Pull up chip select */
        nrf24_csn_digitalwrite(HIGH);
    
        /* Reset status register */
        nrf24_configRegister(STATUS,(1<<RX_DR));
    }
    
    /*
    uint8_t wl_module_data_ready ( )  
    / / checks if data is available for reading 
    { 
        if  ( PTX )  return  0 ; 
        uint8_t status ; 
        / / Read wl_module status 
        wl_module_CSN_lo ;                                 / / Pull down chip select 
        status = spi_fast_shift ( NOP ) ;                / / Read status register 
        wl_module_CSN_hi ;                                 / / Pull up chip select 
        return status &  ( 1 << RX_DR ) ; 
    }
    
    */
    
    
    
    
    void main()
    {
    uint8_t data_array[3];
    uint8_t temp; // return status
    uint8_t count = 0;
    nrf24_init();
    nrf24_powerUpRx();
    
    nrf24_csn_digitalwrite(LOW);
    spi_transfer(FLUSH_RX);
    nrf24_csn_digitalwrite(HIGH);
    
    
    
    
    
    while(1)
    {
    while(nrf24_dataReady());
    nrf24_getData(data_array); 
    
    if(data_array[0] == 0x6F)
    {
    LED_PIN = HIGH;
    }
    else
    {
    LED_PIN = LOW;
    }
    }
    }
    
    
    
  • Can you add a bit more information about what is going wrong? Don't you get any data on the PRX?

    Can you verify that your PTX is actually sending? It seems that you do not clear interrupts or handle them in any way. You are pushing packets to the radio every 20 us or so. You should rather check the FIFO_STATUS register to see if you can actually push packets to the FIFO.

    You can check if the PTX sends by probing pin "VDD_PA". It will go high just before a transmission is triggered, and then go low again when it's ended. Checking the current consumption of the radio will also give you an indication on what state it is in.

    Best regards Håkon

  • Hi Hakon,

    I just want to check the communication test so as per your Guidelines i have just configured required settings and i have left all other uncheck. Is it compulsory to clear the interrupts to get data reflected ? or transmitter properly ?

    I have successfully compile the code and i have check SPI using debugger it is sending payload 0x6F 0x70 0x71 (3 bytes).

    for TX side on pin 11 VDD_PA i am getting continuous high to low pulses @ 1.34 KHZ. i checked with oscilloscope.

    so what could be the issue now ?

    on receiver side what could be the interrupt that i can trace and put LED to light if data available ?

  • Hi,

    Normal procedure is to wait until the interrupt is finished before triggering a new transmission:

    
    hal_nrf_write_tx_payload(tx_payload, sizeof(tx_payload));
    CE_PULSE();
    radio_busy = true;
    // Wait for radio operation to finish
    while (radio_busy); // Set false when interrupt occurs
    

    The pulsing on VDD_PA indicates that your PTX is sending, however you should check the interrupt to see if this is "TX_DS" or "MAX_RT". You can also check VDD_PA pin on PRX as it will send an ACK over-the-air.

    Best regards Håkon

Related