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

Enhanced ShockBurst (ESB) strange behaviour

Hi,

I am developing an application with to 7 transmitters (peripheral) and one receiver (central = nrf52DK), all NRF52832.

I have 1 question and one problem to solved: 

Question:  all receiver are sending collected data's at the same time at 20 - 40Hz frequency (in testing).  ESB transmission is set to

tx_payload.noack = true; 

to prevent central overload and crash.

One of the transmitter is connected to the nrf52DK in order to follow nrf_log in debug mode.  When transmitting the data,
"TX FAILED EVENT"are log from time to time.  Since noack is set to true, I don't understand why.  This does not seems to cause an issue.

Problem : I am using the nrf52DK as a central. Through the computer, i am sending to the central a command is relay to each active peripheral. For exemple, key = 4 start data collection at 40 Hz, z will reset some parameter. This is working fine most of the time, about 9 over 10 time. Sometime if press key z , the receiver will get the command z but also the previous one , 4. It seem that at the central, the TX buffer was not erase correctly, it could be something else.
using the following code in the central
 (void) nrf_esb_flush_tx();
 (void) nrf_esb_start_tx();

before sending new command does not help.

Any suggestion would be appreciate.

Parents
  • Hi,

     

    Which version of the SDK are you using?

    Is this something that looks to be happening on all PTX devices?

    If this happens 9 out of 10 times, it can be a memory related issue. Could you share code on how you handle this specific key input ("4" and "z") on the PTX side?

     

    Kind regards,

    Håkon

  • Hi Håkon,

    I am using SDK16.

    This is the section of the code that handle the key input character.  I have simplified the code and removed what is not in used for now.

    I start the data acquisition (peripheral) by sending  key 1 to 6 according to frequency (10Hz to 60Hz).  I don't use z anymore.    Same problem as before  as an exemple : if I send a 3,   and next time a 4,   a receiver ( not all) will get 1/10 time a 4 follow by a 3.  The problem persist after the first occurance.  Have to reset the central to correct the problem.    

    I am now certain but the problem might occur more frequently when the central is sending a command and the receiver is not listening, occupied sending is data through - RX is disable at that time.  I will do more testing with that.

    while (true) 
      {      
         while (app_uart_get(&cr) == NRF_SUCCESS)   // check for input character or if
                {              
                   
                   nrf_gpio_pin_clear(19);//led
                //   NRF_LOG_INFO("%c", cr);
                   printf("Keypressed : %c\n", cr);
    
                 //  app_uart_flush();       // < ========================= NEW not working
    
                   if  (( (cr >= '1') && ( cr <='6') ) || (cr == 'u')|| (cr == 'c')|| (cr == 'C'))  printnow = true;
                   else if  (cr == 'z') 
                     {printnow = false;
                      (void) nrf_esb_flush_tx(); //test
                     (void) nrf_esb_start_tx();}//test
    
    
                   
                   if ((cr != 'y') && (cr != 'd'))   // send command to all available sensor/pipe      
                      {  nrf_esb_stop_rx();  //test
                         rx_mute = true;     //test
    
                       (void) nrf_esb_flush_tx();
                       (void) nrf_esb_start_tx();
    
                       
                         NRF_LOG_INFO("send CR to all available pipe");
                        
                        
                       //  rx_mute = true ;
                         
                         for (uint8_t i = 0; i <= 7 ; i++)
                         { //printf("Sending command... \n");
                        
                            if (pipe_active[i])
                              {  tx_pipe = i;                      
    
                                
                                 printf("Sending command '%c'to %d\n",cr, tx_pipe);// reset central timer 
                                  NRF_LOG_INFO("Sending command '%c'to %d",cr, tx_pipe);
                                 tx_payload.length =  2;  //payload lenght+1   // can use  n
                                 sprintf(tx_payload.data, "%c", cr);                          
                                 tx_payload.pipe = tx_pipe;
                                 nrf_esb_write_payload(&tx_payload);
                                 
                    
                          
                               }
                       }   rx_mute = false ;  //test
                         nrf_esb_start_rx();  //test
                       
                       
                       }
    
               
               
                }  // app_uart_get
    
    

  • Hi,

     

    On your receiver side, do you have any other interrupts running? If yes, which priority are they running on?

    Its important that the radio runs on priority "0" (highest), and isn't blocked by other interrupts. Other interrupts should run at priority <= 1.

     

    Kind regards,

    Håkon

  • Hi

    This is the default ESB confing from nerf_esb.h .  its says 

    .radio_irq_priority     = 1,                                
    .event_irq_priority     = 2,  

    is thaï OK,

    In the sdk_config.h file.  All the other irq_priority are set to 6,

    #define NRF_ESB_DEFAULT_CONFIG {.protocol               = NRF_ESB_PROTOCOL_ESB_DPL,         \
                                    .mode                   = NRF_ESB_MODE_PTX,                 \
                                    .event_handler          = 0,                                \
                                    .bitrate                = NRF_ESB_BITRATE_2MBPS,            \
                                    .crc                    = NRF_ESB_CRC_16BIT,                \
                                    .tx_output_power        = NRF_ESB_TX_POWER_0DBM,            \
                                    .retransmit_delay       = 250,                              \
                                    .retransmit_count       = 3,                                \
                                    .tx_mode                = NRF_ESB_TXMODE_AUTO,              \
                                    .radio_irq_priority     = 1,                                \
                                    .event_irq_priority     = 2,                                \
                                    .payload_length         = 32,                               \
                                    .selective_auto_ack     = false    

    You have not answer my question above:

    Question:  all receiver are sending collected data's at the same time at 20 - 40Hz frequency (in testing).  ESB transmission is set to

    tx_payload.noack = true; 

    to prevent central overload and crash.

    One of the transmitter is connected to the nrf52DK in order to follow nrf_log in debug mode.  When transmitting the data, events
    "TX FAILED EVENT"are log from time to time.  Since noack is set to true, I don't understand why. Any ideas ?    this does not seems to cause problems.

  • Hi,

     

    Do you set the field .selective_auto_ack to true on all your PRX and PTX devices?

    This is the flag that enables the .noack field, as per the comment in the header:

    bool                    selective_auto_ack;     //!< Enable or disable selective auto acknowledgement. When this feature is disabled, all packets will be acknowledged ignoring the noack field.

     

    Kind regards,

    Håkon

Reply Children
  • Hi,

    This is the setting for the ESB transmitter.  

        nrf_esb_config.selective_auto_ack       = false;



    uint32_t esb_init( void )
    {
        uint32_t err_code;
        uint8_t base_addr_0[4] = {0xE7, 0xE7, 0xE7, 0xE7};
        uint8_t base_addr_1[4] = {0xC2, 0xC2, 0xC2, 0xC2};
        uint8_t addr_prefix[8] = {0xE7, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8 };
    
        nrf_esb_config_t nrf_esb_config         = NRF_ESB_DEFAULT_CONFIG;
        nrf_esb_config.protocol                 = NRF_ESB_PROTOCOL_ESB_DPL;   // dynamic payload length
        nrf_esb_config.payload_length           = 64;//SL  max lenght for nrf52  is 255  // use 80 min
        nrf_esb_config.retransmit_delay         = 600;
        nrf_esb_config.bitrate                  = NRF_ESB_BITRATE_2MBPS;
        nrf_esb_config.event_handler            = nrf_esb_event_handler;
        nrf_esb_config.mode                     = NRF_ESB_MODE_PTX;
        nrf_esb_config.selective_auto_ack       = false;
        nrf_esb_config.tx_output_power          = NRF_ESB_TX_POWER_NEG12DBM;  //  _NEG12DB default 0DBM  min neg30   30 = 2pi  12DBM = 30 pi
        //developer.nordicsemi.com/.../nrf_esb.html
        
        tx_payload.noack = false;
    
        err_code = nrf_esb_init(&nrf_esb_config);
    
        VERIFY_SUCCESS(err_code);
    
        err_code = nrf_esb_set_base_address_0(base_addr_0);
        VERIFY_SUCCESS(err_code);
    
        err_code = nrf_esb_set_base_address_1(base_addr_1);
        VERIFY_SUCCESS(err_code);
    
        err_code = nrf_esb_set_prefixes(addr_prefix, NRF_ESB_PIPE_COUNT);
        VERIFY_SUCCESS(err_code);
    
        tx_payload.pipe = MYPIPE;     //  the pipe adress used for transmitting  fist declaration
    
        return err_code;

  • Hi,

     

    Can you set the .selective_auto_ack = true? This must be set in order for the devices to use NO ACK feature.

     

    Kind regards,

    Håkon

  • Hi Håkon,

    .selective_auto_ack = true  did solve one problem.  I don't have transmission error anymore with acknowledge off. 

    My program send each second  battery_level mainly to keep communication with the central and receive command trought acknowledge.  Of course _noackn set to false during that time.  When I want to get motion data from the sensors (7), I turn acknowledge off for alleviate the workload of the central.  

    Setting    .selective_auto_ack = true  all the time does not seems to cause an issue. Is there any advantage to turn it off ?  I look at the nrf_esb.h file and it does not say too much.

    About the issue receiving the command twice, the behaviour have change.  

    With .selective_auto_ack = false, I was sending a command like 5   and later another command like 4.  the central on occasion send 5 and 4 one after the other to the receiver. 

    With .selective_auto_ack = true, the receiver get the same command twice now, for exemple , 5 a 5, all the time. Unlike previously, resetting the central does not correct the issue.   I should be related to the previous issues but it could also be a problem at the receiver.

    As a short term solution I can just rewrite the receiver code to ignore the second occurrence.

    Sylvain

  • I just notice that with .selective_auto_ack = false or true,   noack=true work with my development board plug on the nrf52DK but does not work with my other peripheral device.  

    The peripheral device work on battery and have exactly the same program except for the pipe number,  but they also use the DFU program to update the device by the air.  With those board, acknowledge is always on even when it should not.. The devices accept commands all the time during data collection but it should not since acknowledge is suppose to be disable.

     

  • I believe that the problem is related to a memory issue.  I have delete some unused variable to liberate some memory space and that seems to have solve the no_acknowledge issue.

Related