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

Comms Between NRF52 Dev Kits using NRF24L01+ modules

Hello, this is a continuation from a different question I previously had answered: https://devzone.nordicsemi.com/f/nordic-q-a/40452/nrf24l01-spi-communication-with-nrf52-dk

I am using two NRF52 Dev Kits and two NRF24L01+ modules to try and communicate wirelessly without needing to use the NRF52832's radio as I would like to leave open the option of also using a soft device and BLE in the future when working with these products. I am using the Nordic SDK 14.2.0 and have started from some base code written by a Nordic engineer from the previous question: link . My end goal is to have two NRF52832s writing to/ reading from NRF24L01+ modules to communicate with each other custom 5B addresses with auto acknowledgement, 2B CRC, 2Mbps data rate, and ideally also dynamic payload length but for now static is fine as well.

I can read and write from the modules over SPI seemingly successfully: I have compared against the datasheet and everything is set as expected. All the functions from the example set up given to me appear to work correctly as I can set any specific register to whatever values I need it to be easily in my NRF24L_init. I have taken out most of the settings I plan on using in the future (RF channels, data rates, custom addresses, etc.) and have left the init mostly empty to leave the modules on as default the settings as I can get them since I keep reading that they should be pretty good to go from just powering up. Here are the settings for my two units set in their init functions:

//PRX
#define PAYLOAD_WIDTH 32    //1-32B

#define SPI_INSTANCE  0     //enabled in config & using EASY DMA, 6 IRQ priority, 8MHz
static const nrf_drv_spi_t spi = NRF_DRV_SPI_INSTANCE(SPI_INSTANCE);    //SPI instance

l01_instance_t NRF24L;
l01_config_t NRF24L_config = L01_MODULE_CONFIG(SPI_INSTANCE, CE_PIN, CSN_PIN, SPI_SCK_PIN,
                                               SPI_MOSI_PIN, SPI_MISO_PIN, IRQ_PIN);

void NRF24L_init(void)
{
    NRF24L.spi_instance = spi;
    NRF24L.pin_ce = CE_PIN;
    NRF24L.pin_irq = IRQ_PIN;   //GPIOTE 6 IRQ priority
    NRF24L.pin_csn = CSN_PIN;

    hal_nrf_nrf52_init(&NRF24L, &NRF24L_config, NRF24L_irq_handler); //Hardware prepared

    nrf_delay_ms(100);                        //delay 100ms for coming online after power loss
    hal_nrf_set_power_mode(HAL_NRF_PWR_DOWN); //power down internals, entering power down mode
    nrf_delay_us(1500);                       //wait 1.5ms to settle
    hal_nrf_set_power_mode(HAL_NRF_PWR_UP);   //power up internals, entering standby mode I
    nrf_delay_us(1500);                       //wait 1.5ms to ensure in standby mode I

    hal_nrf_clear_irq_flags_get_status(); //clear all IRQ flags in case any are set
    hal_nrf_flush_rx(); //empty out everything in RX FIFO in case they contain data
    hal_nrf_flush_tx(); //empty out everything in TX FIFO in case they contain data

    for(uint8_t i = 0; i < 6; i++){
        hal_nrf_set_rx_payload_width(i, PAYLOAD_WIDTH); //sets payload witdh for all rx pipes (0-5)
    }

    hal_nrf_set_operation_mode(HAL_NRF_PRX);  //Set as receiver
    hal_nrf_chip_enable(CE_ENABLE); //Enter Rx mode
    nrf_delay_ms(10);
}
//PTX
#define PAYLOAD_WIDTH 32    //1-32B

#define SPI_INSTANCE  0     //enabled in config & using EASY DMA, 6 IRQ priority, 8MHz
static const nrf_drv_spi_t spi = NRF_DRV_SPI_INSTANCE(SPI_INSTANCE);    //SPI instance

l01_instance_t NRF24L;
l01_config_t NRF24L_config = L01_MODULE_CONFIG(SPI_INSTANCE, CE_PIN, CSN_PIN, SPI_SCK_PIN,
                                               SPI_MOSI_PIN, SPI_MISO_PIN, IRQ_PIN);

void NRF24L_init(void)
{
    NRF24L.spi_instance = spi;
    NRF24L.pin_ce = CE_PIN;
    NRF24L.pin_irq = IRQ_PIN;   //GPIOTE 6 IRQ priority
    NRF24L.pin_csn = CSN_PIN;

    hal_nrf_nrf52_init(&NRF24L, &NRF24L_config, NRF24L_irq_handler); //Hardware prepared

    nrf_delay_ms(100);                        //delay 100ms for coming online after power loss
    hal_nrf_set_power_mode(HAL_NRF_PWR_DOWN); //power down internals, entering power down mode
    nrf_delay_us(1500);                       //wait 1.5ms to settle
    hal_nrf_set_power_mode(HAL_NRF_PWR_UP);   //power up internals, entering standby mode I
    nrf_delay_us(1500);                       //wait 1.5ms to ensure in standby mode I

    hal_nrf_clear_irq_flags_get_status(); //clear all IRQ flags in case any are set
    hal_nrf_flush_rx(); //empty out everything in RX FIFO in case they contain data
    hal_nrf_flush_tx(); //empty out everything in TX FIFO in case they contain data

    for(uint8_t i = 0; i < 6; i++){
        hal_nrf_set_rx_payload_width(i, PAYLOAD_WIDTH); //sets payload witdh for all rx pipes (0-5)
    }

    hal_nrf_set_operation_mode(HAL_NRF_PTX);  //Set as receiver

    nrf_delay_ms(10);
}

My previous setup with this works when I replace the transmitter NRF24L01+ module with an NRF52 Dev Kit running a slightly modified ESB Tx example from the proprietary RF folder, including custom addresses, address widths, payload widths, RF channels, data rates, transmitting powers, 2B CRC, auto ACKs, basically everything EXCEPT dynamic payload lengths, which was breaking it for some reason.

I've been experiencing some anomalies when leaving the transmitter and receiver both running for several minutes where in the PTX will detect a successful transmission (TX data sent IRQ read from status register in the interrupt handler) in a sea of failures to transmit (max retransmits hit without an acknowledge). When debugging the receiver the PRX will trigger a data received interrupt properly (RX data received IRQ) and most of the data is correct, but in seemingly random spots the values will change randomly. I could not find any rhyme or reason to the change; I tried repeatedly sending a 32B array with value 0 in the first index incrementing up to 31 in the final index as constants and additionally incrementing index 1 every time. I have checked on the transmitter side and the data being sent is as expected:

Packet No. | 0 | 1 | 2 | 3 | ... | 31
     0     | 0 | 1 | 2 | 3 | ... | 31
     1     | 0 | 2 | 2 | 3 | ... | 31
     2     | 0 | 3 | 2 | 3 | ... | 31
     etc.

I've tried changing settings one at a time with this setup and thus far I've found is RF channels need to be the same for this to occur (obvious) and enabling dynamic payload length or disabling auto acknowledges break it. The only significant change I noticed was when changing the CRC, but this only confused me further since my results are contradictory to what I understand about CRC.

  • No CRC [ hal_nrf_set_crc_mode(HAL_NRF_CRC_OFF); ] => no successful packets are sent
  • 1B CRC [ hal_nrf_set_crc_mode(HAL_NRF_CRC_8BIT); ] => periodic "successful" packets sent, one every couple of seconds
  • 2B CRC [ hal_nrf_set_crc_mode(HAL_NRF_CRC_16bit); ] => rarely "successful" packets sent, one maybe every 30 seconds to a minute

At this point I'm fairly confident I do not have any errors with my wiring (SPI & IRQ seem to work correct for both reading & writing + interrupt triggers properly) or power supply since I often read that adding capacitance by the modules helps stabilize them: both modules have a 0.1uF ceramic cap & 100uF electrolytic cap nearby and there doesn't appear to be much ripple on the voltage seen on an oscilloscope. I've also tested with multiple modules to ensure that the units I had weren't damaged and even fresh ones I hadn't touched before behave in the same manner.

My understanding of how these modules works is as follows:

Set PTX's TX_ADDR address to match whatever receiving pipe is used on PRX as that is the address the PRX will transmit to for sending an ack
Match the PTX's pipe 0 address to match the TX_ADDR before sending a packet, this will be scanned after transmitting for any incoming ack
If no ack is received after a set delay reattempt this process for the set number of retransmit attempts until either receive an ack or hit the max limit
Generate an interrupt appropriate for whether data was sent proper or not on PTX & generate a data received interrupt on PRX when a non-repeat packet is received

All the documentation, threads, and articles I've read on this seem to be pretty clear on how things must be set up (though it's unfortunate a lot of Arduino related stuff refer to "reading pipes" & "writing pipes" when most nothing else I found does) and I believe that I am correctly setting things up, especially since I am able to use an NRF24L01+ as a receiver when using my NRF52 Dev Kit running ESB as the transmitter. The settings for everything should be basically identical on both the PTX and PRX modules except for the PRIM_RX bit in the configuration register (Reg 0x00) as that controls whether it is acting as a PTX or PRX. To send data, use the W_TX_PAYLOAD SPI command then send the data bytes over SPI continuously to write a packet into the TX FIFO and then pulse the CE pin high for at least 10us to begin transmitting following the flow chart from page 33. For receiving, set the device as a PRX & set the CE pin high to enter receiving mode where it will continuously check the air for incoming packets following the flow chart from page 35.

If I have something basic wrong in here, PLEASE let me know. We have quite a few of these modules on hand at the moment and we would like to use these in various projects but just can't get the darn things to work!

Parents
  • Hi Andy

    I helped you with the last case, and will handle this one as well ;)

    One thing we should check first is a known issue that can occur of you have a bit error in the length field of the packet that makes the packet look larger than 32 bytes. 

    To avoid this issue it is necessary to check the length of the incoming packet before reading it out, and flush the RX FIFO if the problem is detected. 

    1. Wait for the RX interrupt to occur

    2. Read the length of the next packet in the RX FIFO using the hal_nrf_read_rx_payload_width() function.

    3. If the payload length is longer than the max payload length that you expect, flush the RX fifo

    4. If the payload length is as expected, proceed to read out the packet as normal. 

    One thing worth noting is that I am a bit unsure if the implementation of the hal_nrf_read_rx_payload_width() function is correct. 

    Please give me a try and let me know what it returns. Tomorrow I will set up a small test myself to verify if it is correctly implemented. 

    Best regards
    Torbjørn

  • Hi again Ovrebekk,

    Here is the code I have on the PRX side that's reading the payload and printing it out now. An oddity I'm seeing is the early data in it (B31 & B0 to ~B9) seem to never be corrupted, at least in the hundreds of "successes" I've checked through so far, and the late data (~B24 - B30) seem to near always be corrupted in some manner.

    void NRF24L_irq_handler(void)
    {
        irq_hit++;
        test_LED_toggle();  //toggles pin 20, connected to Dev Kit LED4
    
        uint8_t temp_flags = hal_nrf_get_clear_irq_flags();
        if(temp_flags & (1 << HAL_NRF_MAX_RT)){
            printf("\tirq = max retransmit\n");
            flag_max_rt = true;
        }
        if(temp_flags & (1 << HAL_NRF_TX_DS)){
            printf("\tirq = tx data sent\n");
            flag_tx_ds = true;
        }
        if(temp_flags & (1 << HAL_NRF_RX_DR)){
            printf("\tirq = rx data received\n");
            flag_rx_dr = true;
            
            uint8_t temp_len = hal_nrf_read_rx_payload_width();
            if(temp_len == PAYLOAD_WIDTH){
                printf("packet size: %d\n", temp_len);   //check packet size
    
                hal_nrf_read_rx_payload(rx_data); //reads 1 packet from RX FIFO
    
                for(uint8_t i = 0; i < PAYLOAD_WIDTH; i++){
                    printf("\ti%d", i); //prints out index count to make columns with
                }
                printf("\n");
    
                NRF24L_rx_last_byte_swap(rx_data);  //undoes LSB First
    
                for(uint8_t i = 0; i < PAYLOAD_WIDTH; i++){
                    printf("\t%d", rx_data[i]); //prints out each byte of data
                }
                printf("\n");
    
                printf("\t1: %d", rx_data[1]);  //singles out the byte incrementing on PTX side
    
                for(uint8_t i = 2; i < PAYLOAD_WIDTH; i++){
                    if(rx_data[i] != i){
                        testing_flag = true;
                    }
                }
               if(rx_data[0] != 0){
                    testing_flag = true;
                }
    
                if(testing_flag){
                    printf("\tData mismatch!!\n");  //all data doesn't match expected values
                }
                else{
                    printf("\t Data matches\n");    //all data does match expected values
                }
    
                for(uint8_t i = 0; i < PAYLOAD_WIDTH; i++){
                    rx_data[i] = 0;  //rewrites old data
                }
    
                irq_hit_total += irq_hit;
                printf("irqs-%d (%d)\n", irq_hit_total, (uint8_t)irq_hit_total);    //# of IRQs hit
                irq_hit = 0;
            }
            else{
                printf("Wrong width!\n");
            }
        }
    }

    The payload width doesn't seem to be a problem here, my setup is still only receiving packets randomly every couple of seconds and all of them are printing out that they are the correct width (32B). I'm going to keep experimenting with different ideas in the mean time, and I hope your test comes up with something useful!

    edit: Some of the testing I've done so far has just been really weird and I'm reconsidering if I have my SPI working 100% correctly. By default I've been transmitting on the PTX to address 0xE7E7E7E7E7 & expecting packets on its pipe 0 from there which corresponds with the PRX's pipe 0. I started to check the rx data source and payload length values that are returned from the function hal_nrf_read_rx_payload and I was getting pipe 0 and a length of 32B as expected. I changed the PTX addresses to be 0xC2C2C2C2C2, which should correspond to the default address of pipe 1 on the PRX but it the value returned said it received from pipe 2. I set the PTX addresses to 0xC2C2C2C2C3 to match the PRX's default for pipe 2 and I didn't get a single packet across. I'm not sure what might be causing this at all.

    edit's edit: I'm a goofball, I didn't check to see that all the rx data pipes were being enabled properly when doing that testing. By default only pipes 0 and 1 are enabled so after calling "hal_nrf_open_pipe(HAL_NRF_ALL, true);" in my PRX init I was able to receive data (still intermittently every few seconds and corrupted further and further into the payload) on all six channels as expected. Targeting address 0 claimed the RX source was pipe 0, address 1 pipe 1, address 2 pipe 4, etc. which looks like it's just an oddity in how the hal_nrf_read_rx_payload function returns the rx source and payload length. It returns a 16 bit value with the payload length in the low byte and rx source pipe in the high byte. Shifting and ANDing easily separates the values and payload length can be read by just typecasting as 8 bit or ANDing 0x00FF to remove the high byte. Shifting or using an 8 bit pointer to separate the pipe number takes a little more effort though as the returned value is actually just the status register's value received by calling a NOP masked with 0x0E to remove any bits not related to the pipe source. This leave 0b 0000 XXX0 though, which is shifted left once and hence all the numbers are doubled. At no point was I actually receiving from the wrong pipe thankfully. Back to testing.

    last edit I swear: In testing this I believe I'm seeing an issue similar to what you described with incorrect payload widths being registered as Rx successes. When I transmit to pipes 0, 1, 2, and 3 I read the correct pipe and correct payload length of 32B but when transmitting to pipes 4 and 5 I still get the correct pipe number returned but the payload is length 0 and the data remains the same from the last reception that had data. Part of my testing I had actually commented out the code that overwrites the RX data at the end of the IRQ and I forgot to add it back in, hence why I overlooked it earlier. Power cycling the PRX side and/ or re-adding the old data clearing results in nothing being written to the data array. I do not know why this would only be affecting pipes 4 and 5 since I am trying to set everything up to be the same for every pipe apart from default addresses.

  • Hi Ovrebekk,

    I think I found something in testing that could point to some kind of collision or error in timing for retransmits or acknowledges occurring. I've tested with changing the rate at which I'm sending packets; that's changing a compare value checked in a timer that's just continuously running. Here's the code on my PTX side where I transmit the packets, the TIMER_#MS is a define I've been changing to change the transmit period

    void timer_handler(nrf_timer_event_t event_type, void* p_context)
    {
        global_timer++;
        timer_event++;
        if(timer_event == TIMER_500MS){ //occurs every 100ms
            timer_event = 0;
            timer_seconds++;
    
            hal_nrf_flush_tx();
            test_LED_on();  //clears pin 20, turns Dev Kit LED4 on
    
            hal_nrf_write_tx_payload(tx_data, PAYLOAD_WIDTH); //write data to TX FIFO
    
            hal_nrf_chip_enable(CE_PULSE);  //set CE high for at least 10us to begin transmitting data
    
            while(flag_max_rt == false && flag_tx_ds == false && flag_rx_dr == false){} //blocking until IRQ occurs
    
            test_LED_off();  //sets pin 20, turns Dev Kit LED4 off
    
            irq_hit_total += irq_hit;
            printf("\ttotal-%d (%d) success-%d\n\n", irq_hit_total, (uint8_t)irq_hit_total, irq_success_total);
            irq_hit = 0;
    
            flag_max_rt = flag_tx_ds = flag_rx_dr = false;
        }
    }

    Increasing the frequency of transmissions seems to significantly increase the amount of RX interrupts that get triggered without really having any impact on how corrupt the data becomes.

    I also messed around with changing the payload width on both sides to see if anything weird would occur. With the receiver set to 32B and the transmitter set to 10B I was still able to receive corrupted packets where the early data was correct but deeper into the payload (started closer to ~8B this time) the data would become more and more corrupted. Setting the PTX to 25B instead of 10B also had false positives on the PRX with the data corrupting a bit before the 25th data byte, and these RX interrupts trigger more frequently the larger the PTX payload width.

    Decreasing the payload width on the PRX side seems to decrease how often false positives occur. At a payload width of 20B packets are fairly rare occurrences (~1 ever 20 seconds at best) and when brought down to 10B I saw a single false positive when left running for several minutes (3+ min). The data at ~20B also appeared a bit less corrupted often starting to change from 0 later and not by much, though this is a very subjective take that might be placebo, I'll keep testing on how the data changes late into my packets.

    Something very bizarre I found in testing is when I changed the data I was transmitting from an incrementing array to all 0s. The early parts of data were all 0 as expected would corrupt late into the payload as usual but generally staying at/ around the values 170 and 85 in decimal, or 0xAA and 0x55 in hex. That's the same as the preamble for incoming packets that the receiver first looks for in PRX mode; I feel this is very relevant to what's going wrong with my setup in some way.

  • Hi Andy

    Are you able to share your code projects with me?

    Then I can run your code on some regular nRF24L01+ dongles and see if I can reproduce the issue. 

    Best regards
    Torbjørn

Reply Children
  • Hello Ovrebekk,

    I'm very thankful for you helping me with these modules, but unfortunately for the next few days I will be out of the office and out of town. I will still check here and be researching around for possible solutions to my problems but I won't have any hardware on hand to test with until I return next Tuesday.

    In the meantime, I fiddled around more with the code I have and found this seems to be working more stable than my previous build: NRF24L Testing2 Electric Boogaloo.zip . It keeps track of how many bytes in the received packets on the PRX side differ from their expected values and prints them all out. On the PTX side, since when a Max Retransmit IRQ is triggered the TX payload in the TX FIFO is not removed I enable CE to begin writing and remain blocking until a TX Data Sent IRQ is triggered before disabling CE. I commented out the print statements for hitting TX Max Retransmits because it hits a LOT of them very quickly, but this has made my setup get (still corrupted) packets across much more consistently it seems. I don't know if this is bad practice or a misuse of these modules but results are results. I've also experimented with changing data rates, RF channels, target addresses, etc. and they all seem to function correctly. I also increased the time between transmissions because I realized times as low as 10-20ms could be short enough that with 15 retries and a 4ms auto retry delay more time could be spent waiting for a successful ACK back than should be.

    I've ordered replacement RF modules from a different seller that do not include the PA+LNA on the output just to check if the modules I have might actually be bad after all. I'll post a quick update once I get back and test with those; should just be soldering on the headers and swapping them with the old modules in my fitting board. I also noticed the LED1 is faintly flickering at times on each of my Dev Kits and I suspect this is because the pin is in some manner tied to P0.17 which is the IRQ pin for both my setups. The behavior of LED1 seems to match more or less what I'm expecting for the IRQ on the PRX, but it seems much less stable and random on the PTX side. My guess is there's some major error I'm making on the PTX side that's causing packets to not really transmit correctly but the rate & volume I'm transmitting at is enough to flood the PRX into thinking it got a packet that just gets garbled at the end somehow (though I've had many guesses as to why I'm not able to get these working yet though and more often than not I've been wrong with these).

    Sorry for the delay on this and thank you for your help.

  • Hi Andy

    It is odd that you are seeing so many lost packets (MAX_RT hitting). Seems to indicate some problem with the configuration. 

    I am a bit confused by your address configuration. It seems you are using one of the default radio addresses, but configuring it on a different pipe than normal. Could you try to simply send data on the default 0xE7E7E7E7E7 address, without making any changes to the address registers?

    Any reason you use a 4ms auto retry delay? 

    The default 250us is long enough in most cases (unless you use the ACK payload feature in 250kbps mode), and will make retransmission a lot more efficient. 

    I got your code to run, but was a bit unsure how to interpret the results. I think I will have to spend a bit more time with it. 

    P0.17-P0.20 is assigned to the LED's, so this is to be expected. If you look at the back of your DK all the default pin assignments should be listed. 

    Myself I use P0.11-P0.16 for the nRF24L01+ connection. 

    Best regards
    Torbjørn

  • Hey Ovrebekk,

    I'm back! The addresses I'm using aren't really important right now I don't believe. I've tested with both the default settings as well as (as you've seen) changing them around to different pipes, using different pipes than the default, and using different addresses than the defaults. I'm getting the same behavior from my setup regardless of these settings so I believe the address is behaving properly as there is no connection when there is an address mismatch.

    I was working under the assumption that a longer delay on the auto-retry would give me a better chance of actually catching a packet. I don't believe it needs to be that long but since they were the maximum limits I just went with 15 retries and 4ms delay. Testing this now with the values set back to default on both sides produces very similar behavior; the TX side will stay blocking for a while and miss a lot of packets until one gets through finally, but the received packet is largely corrupted.

    Since it seems to be working I'm going to guess the LEDs being tied to the same pins as the lines for the RF modules isn't a problem so I'll leave my setup as is for now. I also have the new modules without the power amplifier on the output so I'll begin testing with that as well.

    Thanks, 

    Andy

    Edit: A quick update on how the different modules worked and two quick odd things I've noticed. The NRF24L01+ modules without the Power Amplifier and Low Noise Amplifier stages seem to work worse in my current setup than my previous ones. I suspect this is because of their reduced output power making transmissions harder to detect in my sort-of working scenario. With the PA+LNA modules, a dBm setting of 0dBm or -6dBm seems to work fine but at -12dBm communications drop dramatically and at -18dBm they completely cut out. I haven't moved them yet while testing but they are maybe 0.75m - 1m on the desk so I'm highly skeptical that this is their max range for -6dBm. The non-PA+LNA modules would work even less consistently than the PA+LNA ones set to -12dBm.

    First oddity I noticed is that the power supply on the transmitter side seems particularly picky on when it will and won't work for transmissions. When I connect it up to a power supply set to 2.85V, it barely works even at 0dBm (I've ensured there's common ground connections, measured voltages with a multimeter, and checked ripple with an oscilloscope and nothing seems abnormal to me). When I try to use 5V connected to a 3.3V linear regulator and connect use that to power the transmitter side it worked even less consistently than before. Thankfully it seems to work best (from what I've seen) when connected to the same Vdd as on the NRF52 Dev Kit that's controlling it. I'm not sure if maybe there's a problem with the voltage difference between the Dev Kit and the module or the regulator I used; from page 19/75 in the datasheet these levels should be within the digital input range no problem. I also only seem to encounter this problem on the PTX side, I've tested the PRX side being powered from all 3 sources (power supply, linear regulator, Dev Kit Vdd) and all seem to work more or less the same where as only the PTX side only Dev Kit Vdd seems to give decent results.

    Second oddity I found was the datasheet makes mention on page 72/75 that "If the PTX device shall receive acknowledge, configure data pipe 0 to receive the ACK packet." but I'm not sure exactly what they mean. I do know that with ESB the unit will immediately after transmitting switch to RX mode and check pipe 0 for any incoming ACK packet and hence on the PTX both the TX address and pipe 0 address need to match. What I'm unsure of is what other settings explicitly need to be setup in order to ensure that the ACK will be received correctly every time. I figure that the pipe must be enabled for reception as well as have auto-acknowledge enabled. I'm not trying to send any payload with my acknowledge so from my understanding the packet should contain 0 bytes of data, but in testing I've found that setting the PTX's pipe 0 to 32B (same as the transmission payload length) and 0B (the default length) both give me the same results. With my current setup I've checked and it seems to be an average of about 17 MAX_RT interrupts triggered for each 1 TX_DS, ranging anywhere from getting it successful on the first try as well as taking 60+ attempts. I've also fiddled more with the code (changing to default addresses again, changing RF power, reducing retransmit delay to 750us from 4ms, disabling CE after successful ACK reception on PTX) and now I have the data corruption significantly reduced albeit still present. When I was getting anywhere from 10B-20B as incorrect values prior I am now typically seeing between 1B-8B changed, and instead of resembling the preamble (0x55 or 0xAA) they now seem to only include 1-2 bit flips (ie. 0x05 -changed to-> 0x69).Here is my most up to date code: NRF24L Testing3 The RFs Revenge.zip

  • Hi Ovrebekk,

    Sorry for the message spam but I've recently gotten my setup into a mostly functional state that may meet my needs. I remembered needing to change some things in the nrf5dk_l01 files so I checked them again and made a few more changes as I saw fit while checking the results to make sure everything was writing/ being read correctly. A few things (flush_tx, flush_rx, hal_nrf_nop I recall) worked fine when changed back to how they were in the original library you provided me and I needed to slightly change how reading the receiving pipe source while trying to read payload data. I assume dark magic is at play.

    I enabled dynamic payload lengths, 16 bit CRC, dynamic ACKs (not using them), and ACK payloads (not using them) and instead of breaking communication it actually works pretty well now! The result thus far is that I am able to rapidly send packets with payload lengths of up to ~10B-12B with few if any errors. The only data corruption I've seen has been mostly near the very ends of packets anyway in the form of 1-2 bit flips; when left running it took over 10,000 successful transmissions before finding even a single bit error and the average number of transmit attempts needed to send the packet stayed very close to 1.

    Sending packets with payloads greater than ~10B-12B often results in the large number of missed packets and long transmission periods that I was experiencing earlier, with payload lengths of 32B sending anywhere from the first try to several hundred over a minute later. I've noticed that the longer it takes for a transmission to be sent, the more likely there is for an error to be present in the packet that does get passes and the longer the payload the more likely multiple bytes of data will be corrupted. The footnotes on p. 59-60 of the datasheet mention that the Auto Retransmit Delay may need to be increased in length with larger payloads. My setup has 15 retries with a 750us delay at 2Mbps with a payload length between 1B to 12B; I don't know if these values might need to change again to make communication run more smoothly. Setting a payload width of 2B for some reason doesn't work: the PRX gets caught in some kind of infinite loop in the SPI driver so I've simply avoided using that length.

    I cannot stress enough my thanks to you for your patience in helping me operate these modules, slow and steady will win this race. Here is the code I am currently working with for both my PTX and PRX, including the modified nrf5dk_l01 library (effectively obsoleting previous attachments in this thread): NRF24L Testing4 End It.zip

Related