Skip to main content
Visitor II
September 30, 2023
Question

nRF24L01+ receiver problems

  • September 30, 2023
  • 6 replies
  • 9894 views

Hello,

I am currently using a custom-built board designed to the nRF24L01+ specification and using the same exact circuit provided in their datasheet. It is connected to my STM32F103 through SPI. I am currently using this library to test out this board: https://github.com/elmot/nrf24l01-lib/tree/master

The board is able to successfully verify that it is connected to the NRF chip using the nRF24_Check() function. Furthermore, the nRF is returning back that a packet (without AA) has been sent successfully and subsequently clears the TX FIFO. On my receiver device, the RX FIFO does not get populated nor any interrupts triggered by the nRF which leads me to the assumption that there is a problem somewhere with the wireless transmission of the packet. If I were to enable AA, and also put my receiver device on the ESB RX example, then the nRF would return that the maximum number of transmissions has occurred.

It is my first time attempting to debug a wireless device that I have made so I would appreciate any help or suggestions on where to look and what to verify. 

    This topic has been closed for replies.

    6 replies

    Graduate
    September 30, 2023

    I would have to see the code. I'm very familiar with that radio and have written my own library.  It seems to be spi bus specific. Post your spi bus initialization code and bus speed. 

    I'd look at spi bus settings first, then addressing. Then line pull ups on the 2 select gpio lines.

    Graduate
    September 30, 2023

    You have 2 lines on the NRF24L01, CSN and CE.

    /*Configure GPIO pin Output Level */
    // Start both HIGH
    HAL_GPIO_WritePin(NRF_CE_GPIO_Port, NRF_CE_Pin, GPIO_PIN_SET); 
    HAL_GPIO_WritePin(NRF_CSN_GPIO_Port, NRF_CSN_Pin, GPIO_PIN_SET);
    
    /*Configure GPIO pin : NRF_CE_Pin */
    GPIO_InitStruct.Pin = NRF_CE_Pin;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(NRF_CE_GPIO_Port, &GPIO_InitStruct);
    
    /*Configure GPIO pin : NRF_CSN_Pin */
    GPIO_InitStruct.Pin = NRF_CSN_Pin;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(NRF_CSN_GPIO_Port, &GPIO_InitStruct);
    
    

    And make sure your SPI bus is no faster than 5MHz. Anything faster will result in unpredictable behavior.

    Visitor II
    October 1, 2023

    SPI Init

    hspi2.Instance = SPI2;
     hspi2.Init.Mode = SPI_MODE_MASTER;
     hspi2.Init.Direction = SPI_DIRECTION_2LINES;
     hspi2.Init.DataSize = SPI_DATASIZE_8BIT;
     hspi2.Init.CLKPolarity = SPI_POLARITY_LOW;
     hspi2.Init.CLKPhase = SPI_PHASE_1EDGE;
     hspi2.Init.NSS = SPI_NSS_SOFT;
     hspi2.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16;
     hspi2.Init.FirstBit = SPI_FIRSTBIT_MSB;
     hspi2.Init.TIMode = SPI_TIMODE_DISABLE;
     hspi2.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
     hspi2.Init.CRCPolynomial = 10;
     if (HAL_SPI_Init(&hspi2) != HAL_OK)
     {
     Error_Handler();
     }

    GPIO Init

    /Configure GPIO pin : NRF_CE_Pin/
     GPIO_InitStruct.Pin = NRF_CE_Pin;
     GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
     GPIO_InitStruct.Pull = GPIO_NOPULL;
     GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
     HAL_GPIO_Init(NRF_CE_GPIO_Port, &GPIO_InitStruct);
    
     /Configure GPIO pin : NRF_CS_Pin/
     GPIO_InitStruct.Pin = NRF_CS_Pin;
     GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
     GPIO_InitStruct.Pull = GPIO_NOPULL;
     GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
     HAL_GPIO_Init(NRF_CS_GPIO_Port, &GPIO_InitStruct);

     

    Graduate
    October 2, 2023

    I don't have any familiarity with that library, and can't see why it wouldn't work. I did notice one thing. According to the datasheet of the NRF24L01, when sending a packet, you need to "pulse" the CE line for at least 10us to clock in the transmission. I didn't see that happening in the library.

     

    /**
     * Pulses the CE to nRF24L01 for at least 10 us
     */
    #define CE_PULSE() do { \
     uint8_t count; \
     count = 20; \
     CE_HIGH(); \
     while(count--) \
     ; \
     CE_LOW(); \
     } while(0)


    This is in the Nordic library for that radio:

    void radio_send_packet( uint8_t *packet, uint8_t length )
    {
    	hal_nrf_write_tx_pload( packet, length ); // load message into radio
    
    	CE_PULSE( ); // send packet
    
    	radio_set_status( RF_BUSY ); // trans. in progress; RF_BUSY
    }

    And this is in your library:

    void nRF24_WriteAckPayload(nRF24_RXResult pipe, char *payload, uint8_t length) {
    	nRF24_CSN_L();
    	nRF24_LL_RW(nRF24_CMD_W_ACK_PAYLOAD | pipe);
    	while (length--) {
    		nRF24_LL_RW((uint8_t) *payload++);
    	}
    	nRF24_CSN_H();
    }

    Is this a library you have tested before?

    Visitor II
    October 2, 2023

    Not a library I have tested before, I tried with multiple libraries now and I am still not seeing any positive results. I tried lowering the clock speed and pulsing the CE but still no results. 

    Graduate
    October 3, 2023

    I've included the modified Nordic NRF24L01 library that I've added all the low-level functions for STM32 HAL. 

    /* Include radio and radio_<mode> */
    #include "radio.h"
    #include "radio_esb.h"
    
    // Global space
    // Radio
    static const uint8_t address[HAL_NRF_AW_5BYTES] = {
    		0x33,
    		0x44,
    		0x55,
    		0x66,
    		0x01
    };
    
    extern uint8_t pload[RF_PAYLOAD_LENGTH]; // Declared in the NRF24L01 Library
    
    // In your main
    radio_esb_init(address, HAL_NRF_PRX); // Address of the device and Primary RX or TX 
    
    
    // Super loop
    radio_irq();
    radio_status = radio_get_status();
    uint8_t rx_data[20];
    
    // Data received
    if(radio_status == RF_RX_DR)
    {
     memcpy((void*)rx_data, (void*)pload, sizeof(PACKET_SIZE));
    }
    
    // Interrupt is enabled by default
    void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
    {
     if(GPIO_Pin == NRF_IRQ_Pin)
     {
    	HAL_GPIO_TogglePin(LED_GREEN_GPIO_Port, LED_GREEN_Pin);
     }
    }
    

     

    Super User
    October 2, 2023

    >then the nRF would return that the maximum number of transmissions has occurred.

    iirr maybe the nrf24 is right - depending on mode each transmission gets acknowledge back , if not, it retries transmission up to max.number. So this just shows: receiver got no valid packet.

    did you set the packet "ID" on both ?

    const uint64_t pipe = 0xAFFEAFFE1111; // Needs to be the same for communicating between 2 NRF24L01

     

    Visitor II
    October 2, 2023

    I switched to a completely new example, no cigar. I realized in my circuit that I wired the IREF incorrectly to 3.3v instead of to ground. I removed the resistor and let IREF float and there was no change. I then wired IREF properly over a 22k to GND and still nothing on both devices. I tried hooking an oscilloscope to the output of the antenna to see if I could see at least some signal, however, it appeared as if it was being pulled to ground. I verified that the circuit has no problem reading and writing registers to the NRF, and that there is active SPI communication. On the receiver, I verified that the CS and CE pins were both low while it was receiving. I am running out of things to test without trying to get a spectrum analyzer to see if anything is actually being transmitted.

    Super User
    October 2, 2023

    i used mini module , about 1 $ ->

    https://de.aliexpress.com/item/32914543301.html

    just connect it and it was working fine .

    maybe you should start with 2 of them, to check your software etc. , then go for using your onboard design.

     

    Visitor II
    January 12, 2024

    It sounds like the reciever is not being set up correctly, thus never sending the acknowledgement back to the sender. Make sure the TX and RX addresses are the same on both devices.

    Perhaps compare the implementations. This works perfectly for full duplex communication with ACK in the STM8

    https://github.com/nicogutz/NRF24_STM8_Library

    Be careful because the endianness of the STM8 and the STM32 is different.