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

nrf24l01+: ack payload length > 1 on PRX TX'ed => Same data as first byte RX'ed on PTX.

I have two NRF24L01+ modules - I am not sure if they are fake?

One node acts as PTX and another as PRX.

On both devices i have the features auto_ack and ack_payload enabled.

I can send data between PTX and PRX with no problem.

If i use the PRX ack payload with 1 byte i have no problem in receiving this on PTX. I change the value of the payload with CMD_W_ACK_PAYLOAD command.

if i have a ack payload length > 1 byte, lets say 10 bytes - and change the data with CMD_W_ACK_PAYLOAD on the PRX i get 10 bytes back on PTX.. but all bytes are identical to first byte...

Does this make sense?

Can i read the content of the ack payload on the PRX to verify my data?

  • Hi ApaX,

    Have you made sure you enable dynamic payload length on both sides ? You need to set EN_DPL besides EN_ACK_PAY. You also need to set the DPL_Px matches with which pipe you used.

    Have you made sure you received 10 bytes when you have RX_DR interrupt (with R_RX_PL_WID ) ?

    EDIT:

    Example:

    ptx - ACKPayload.rar

    prx - ACKPayload.rar

  • Hello Hung,

    I am not using an interrupt i poll the data.

    This is my code:

    #include "stm32f10x.h"
    #include "stm32f10x_rcc.h"
    #include "stm32f10x_gpio.h"
    #include "main.h"
    #include <nrf24.h>
    #include <gpio.h>
    #include <font.h>
    #include <delay.h>
    
    #define LED_Port        GPIOC
    #define LED_Pin         GPIO_Pin_13
    #define LED_ON()        GPIO_WriteBit(LED_Port, LED_Pin, Bit_RESET)
    #define LED_OFF()       GPIO_WriteBit(LED_Port, LED_Pin,Bit_SET)
    
    
    #define nRF_CHANNEL     70
    #define nRF_isTX_DEMO   1       
    #define nRF_PaketLen    32      
    
    
    
    uint8_t Addr[] = {0x01, 0x02, 0x03, 0x04, 0x05};
    
    #ifdef nRF_isTX_DEMO
    uint8_t Buff[] = {
      0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
      0x11, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
      0x21, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
      0x31, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08
    };
    
    uint8_t Recieved[32];
    #else
    uint8_t send[] = {
      0x01, 0x02, 
    };
    uint8_t Buff[32];
    #endif
    
    uint8_t Pipe        = 0;  
    uint8_t Len         = 0;  
    uint32_t Counter    = 0;  
    uint32_t TryCounter = 0;  
    uint32_t Err        = 0;  
    
    void main()
    {
      SystemInit();
    
      gpio_PortClockStart(LED_Port);
      gpio_SetGPIOmode_Out(LED_Port, LED_Pin);
      
      nrf24_init(SPI2, nRF_CHANNEL);
     
      nrf24_RxPipe_Setup(0, Addr, nRF_PaketLen);      
    
    
    
      nrf24_AckPayload_OnOff(1);
      nrf24_DynPayload_OnOff(1);
    
      
    #if (nRF_isTX_DEMO)
      Len = nRF_PaketLen;
      while (1)
      {
        LED_ON();
        
        int8_t TryNum = nrf24_Send(Addr, Buff, Len);      
    
        if (TryNum >= 0)            
        {
          Counter++;                
          uint8_t nrf24_ReadState();
    
          nrf24_Read_RxPayload(&Recieved[0], 2);
    
        }    
        else
          Err++;                   
        
        delay_ms(50);
      }
    #else
    
      while (1)
      {
         Len = nrf24_Recv(&Pipe, Buff);      
        if (Len)    
        {
          delay_ms(10);
          nrf24_write_ackpayload(send, 2);
      
          Counter++;
        }
      }
    #endif
    }
    
    
    uint8_t nrf24_Recv(uint8_t *pPipe, uint8_t *pBuff)
    {
      uint8_t status = nrf24_ReadState();
      uint8_t Len = 0;
    
      if (status & NRF24_bTX_DS_Mask)
        nrf24_ResetStateFlags(NRF24_bTX_DS_Mask);
    
      if (status & NRF24_bRX_DR_Mask)       
      {
    
        *pPipe = (status >> 1) & 0x07;
        
      
        if (RxPipes[*pPipe].bDynPayLoad)
          Len = nrf24_getDynLen();
        else
          Len = RxPipes[*pPipe].PayLoadLen;
        
        nrf24_Read_RxPayload(pBuff, Len);
        
    
        nrf24_ResetStateFlags(NRF24_bRX_DR_Mask);
      }
      
      return Len;
    }
    
    
    void nrf24_AckPayload_OnOff(uint8_t Enable)
    {
    #if (NRF24_MODEL == NRF24_MODEL_L01)
      nrf24_activate(nrf24_SPIx);
    #endif
      
      
      tNrf24Reg1Dh RegValue;
      nrf24_read_regs(nrf24_SPIx, NRF24_REG_FEATURE, (uint8_t *) &RegValue, 1);
      RegValue.bEN_DPL = 1;
      RegValue.bEN_ACK_PAY = (Enable) ? 1 : 0;
      nrf24_write_regs(nrf24_SPIx, NRF24_REG_FEATURE, (uint8_t *) &RegValue, 1);
    
      // Enable dynamic payload on pipes 0 & 1
      nrf24_write_reg(nrf24_SPIx, NRF24_REG_DYNPD, (1 << 0) | (1 << 1));
    }
    
    void nrf24_DynPayload_OnOff(uint8_t Enable)
    {
    #if (NRF24_MODEL == NRF24_MODEL_L01)    
      nrf24_activate(nrf24_SPIx);
    #endif
    
      tNrf24Reg1Dh RegValue;
      nrf24_read_regs(nrf24_SPIx, NRF24_REG_FEATURE, (uint8_t *)  &RegValue, 1);
      RegValue.bEN_DPL = (Enable) ? 1 : 0;
      nrf24_write_regs(nrf24_SPIx, NRF24_REG_FEATURE, (uint8_t *)  &RegValue, 1);
    }
    
    uint8_t nrf24_write_ackpayload(uint8_t *pBuff, uint8_t Len)
    {
      if (Len > 32)
        Len = 32;
      return nrf24_write(nrf24_SPIx, NRF24_CMD_W_ACK_PAYLOAD, pBuff, Len);
    }
    
  • @ApaX: I would need to see how you do nrf24_Read_RxPayload

    I attached in my answer above an example. It's for the nRF24LE1 but the radio and the register are the same with nRF24L01. You can compile the example using the nRFGo SDK here.

    I can see that you are expecting 2 bytes from the ack payload ?

  • Thank you for your answer.

    Yes i've changed it from 10 bytes to 2. Just for simplicity. My code is working just fine with one ACK-payload-length. But with more than one ack-payload-length, the first ack payload is copied to the entire length.

    uint8_t nrf24_Read_RxPayload(uint8_t *pBuff, uint8_t Len)
    {
      if (Len > 32)
        Len = 32;
      return nrf24_read(nrf24_SPIx, NRF24_CMD_R_RX_PAYLOAD, pBuff, Len);
    }
    
    
    
    uint8_t nrf24_read(SPI_TypeDef* SPIx, uint8_t Cmd, uint8_t *pBuff, uint8_t Len)
    {
      NRF24_CSN_LOW();
    
    
      uint8_t State = SPI_SendRecvByte(SPIx, Cmd);
    
      SPI_recv8b(SPIx, pBuff, Len);
      
      NRF24_CSN_HIGH();
    
      return State;
    }
    

    General question: Is it possible to have more than one ACK-payload byte sent (as auto response) via. Enhanced ShockBurst?

  • Yes, it is possible to send more than one byte. You can have a look in the example I attached, there are 3 bytes sending as ACK payload.

Related