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

NRF24L01+ACK Payload stops acking

Been playing with NRF24L01+ for a while and mostly they work as I expect. Now, I'm trying to use an ACK payload, but whenever I try to set up the receiver to put a payload in the ack, the transmitter stops seeing acks.

My Init code working w/o an ack payload:


(Do you have code tags here?)
	NRFWriteRegister(RG_CONFIG,ModeBits);
	NRFWriteRegister(RG_EN_AA,3);				// Enable auto ack on pipes 0 and 1
	NRFWriteRegister(RG_EN_RXADDR,3);			// Enable Rx on pipes 0 and 1
	NRFWriteRegister(RG_SETUP_AW,3);			// 5 byte addresses
	NRFWriteRegister(RG_SETUP_RETR,255);		// 8 retries
	NRFWriteRegister(RG_RF_CH,2);				// channel 2 NO HIGHER THAN 83 in USA!
	//NRFWriteRegister(RG_RF_SETUP,0b00100110);   // 250Kbps, 0db output
	//NRFWriteRegister(RG_RF_SETUP,0b00000110);   // 1Mbps
	//NRFWriteRegister(RG_RF_SETUP,0b00001110);	// 2Mbps

	NRFWriteRegister(RG_RF_SETUP,pSpeed);


	NRFWriteRegister(RG_DYNPD,3);				// Dynamic packet length on pipes 0 and 1
	//NRFWriteRegister(RG_FEATURE,0b111);		    // Enable dynamic payload, payload in the ack and  W_TX_PAYLOAD_NOACK
	NRFWriteRegister(RG_FEATURE,0b100);
	NRFWriteRegister(RG_RX_PW_P0,32);			// Receive 32 byte packets
	NRFWriteRegister(RG_RX_PW_P1,32);

To enable the payload on ack, I change the RG_FEATURE register to 0b111.

My load ack payload code:


void NRFSetAckPayload(uint8_t *Packet, uint8_t Length)
{
	CHIPSELECT { spi(CMD_FLUSH_TX); };

	CHIPSELECT
	{
		spi(CMD_WR_TX_PLOAD);
		for (uint8_t i = 0; i<Length; i++) spi(Packet[i]);
	};
	
	CHIPSELECT{ spi(CMD_W_ACK_PAYLOAD);};	
}

My send packet code:


	CELOW;
	NRFModeTX();		// Make sure in TX mode
	NRFWriteRegister(RG_EN_AA,3);				// Enable auto ack on pipes 0 and 1
	NRFSetTxAddress(ToAddress);

	CHIPSELECT
	{
		spi(CMD_FLUSH_TX);
	};

	CHIPSELECT
	{
		spi(CMD_WR_TX_PLOAD);
		for (uint8_t i = 0; i<Length; i++) spi(Packet[i]);
	};

	CEHIGH;
	_delay_us(15) ; // At least 10 us
	CELOW;

	uint8_t st = 0;
	while ((st & ((1<<5) | (1<<4)))==0) st = NRFReadRegister(RG_STATUS); // Packet acked or timed out
	NRFWriteRegister(RG_STATUS,st & ((1<<5) | (1<<4))); // Clear the bit

And my receive code:


uint8_t NRFReceivePacket( uint8_t * Packet)
{

	if ((NRFReadRegister(RG_STATUS)&(1<<6))==0) return 0;
	CELOW ;
	CHIPSELECT
	{
		spi(CMD_R_RX_PL_WID);
		pw = spi(0);
	}

	if (pw>32)
	{
		CHIPSELECT
		{
			spi(CMD_FLUSH_RX);
		}
		NRFWriteRegister(RG_STATUS,(1<<6)) ;
		return 0;
	}

	CHIPSELECT
	{
		spi(CMD_RD_RX_PLOAD);
		for(uint8_t i = 0; i<pw; i++) Packet[i] = spi(0);
	}
	NRFWriteRegister(RG_STATUS,(1<<6)) ; // Clear the RX_DR interrupt
	CEHIGH ;
	return 1;
}

It seems the transmitter stops getting acks when I set the RG_Feature register to 0b111.

Related