NRF24L01 only transmits once

I set up a single nrf24l01 receiver and 2 transmitters. The way the transmission works is as follows:

  1. Power the nrf24l01 using a GPIO pin (HIGH) on an ATTINY84
  2. Send a message e.g. "A" as a fixed size payload of 32 bits (4 bytes)
  3. Power off the transmitting nrf24l01 by changing the GPIO pin to LOW
  4. Sleep ATTINY84
  5. Interrupt on digital pin (button press) wakes up the ATTINY84 and then it repeats

So essentially, every button press the attiny wakes up and sends a single message to the receiver and goes back to sleep again.

The problem now is that when the transmitter sends once then goes to sleep, the receiver only receives the first transmission but then does not receive anything. However, If I transmit a message from a different transmitter, the receiver receives it but it is also able to receive a message from the 1st transmitter. Basically, I cannot send consecutive messages rather I have to take turns transmitting from different transmitters in order to send multiple messages from the same transmitter.

FYI this issue didn't exist and I was able to send consecutive messages before but I am not sure what I did exactly to make it happen.

NOTE that when I give constant power to the nrf24l01 transmitter, I am able to send consecutive messages without an issue (as opposed to powering the GPIO ON when transmitting and OFF when sleeping)

#define CE_PIN 2
#define CSN_PIN 9 
#define PIN_BTN 7
#define PIN_RFPOWER 8

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#include <avr/sleep.h>
#include <avr/interrupt.h>

RF24 radio(CE_PIN, CSN_PIN);

const uint16_t address = 0xE0E0;
char msg[32] = "A";

void setup() {
  pinMode(PIN_BTN,INPUT);
  pinMode(PIN_RFPOWER,OUTPUT);
  digitalWrite(PIN_RFPOWER,HIGH);
  radioInit();
}

void loop(void){
  
    radio.flush_tx(); // Not sure why I
    radio.flush_rx(); // added these tbh 

    radio.write(&msg, sizeof(unsigned long));
  
  while(digitalRead(PIN_BTN) == HIGH){
    // Prevents multiple messages from being sent when button is held down
  }
  delay(1000);
  sleep();
  radioInit();
//  delay(1000);  // I tried giving the nrf time to initialise but that didn't help
}

void radioInit(){
  digitalWrite(PIN_RFPOWER,HIGH);
  radio.begin(); // Start up the radio
  radio.setAutoAck(true); // Ensure autoACK is enabled
  radio.setRetries(15,15); // Max delay between retries & number of retries
  radio.openWritingPipe(address); // Write to device address 'SimpleNode'
  radio.setPALevel(RF24_PA_MIN);
  radio.stopListening();
}

void sleep() {
    GIMSK |= _BV(PCIE0);                     // Enable Pin Change Interrupts
    PCMSK0 |= _BV(PCINT7);                   // Use PB7 as interrupt pin
    ADCSRA &= ~_BV(ADEN);                   // ADC off
    set_sleep_mode(SLEEP_MODE_PWR_DOWN);    // replaces above statement
    digitalWrite(PIN_RFPOWER,LOW);
    sleep_enable();                         // Sets the Sleep Enable bit in the MCUCR Register (SE BIT)
    sei();                                  // Enable interrupts
    sleep_cpu();                            // sleep

    cli();                                  // Disable interrupts
    PCMSK0 &= ~_BV(PCINT7);                  // Turn off PB3 as interrupt pin
    sleep_disable();                        // Clear SE bit
//    ADCSRA |= _BV(ADEN);                    // ADC on

    sei();                                  // Enable interrupts
    } // sleep

ISR(PCINT0_vect) {
    // This is called when the interrupt occurs, but I don't need to do anything in it
    }

Any ideas on how I can get consecutive messages to be transmitted and received by the receiver?

Your problem is the single constant message you are sending.

The second packet will be regarded duplicate,
because it has the same internal 2 bit id and CRC.

You only send one packet after power-up, so the id is always zero.

You could

  • ensure that each packet is different (counter in EEPROM, even some random value)
  • send more than one packet

You do some strange things with the pipe address.
What will be read from RAM address 0xE0E0?

Why don't you care, whether send got an acknowledgment?
(It would not help in this case, dropped dups will be seen as successful writes,
and will get a normal acknowledgment, but it is good practice to check for errors.)

I would not trust the power supply by a pin.

Hello!

Thank you for your response and your patience, I have been very busy at work so I couldn't test.

msg[1] = random(0,127); // random ascii character in 2nd index of char array

I just tried changing the 2nd character in the 'msg[32]' variable before each transmit so it seems different to the receiver and it worked! I'm not sure why I have to do this though, I thought the auto ack would take care of this.

0xE0E0 is just the address for the receiver which the transmitter sends to. It was previously a string 'SimpleNode' but I was testing hex and I just left it as it is.

Checking for errors is not my priority right now because I was just trying to get it to work first. Also, I'm not exactly sure how I can do that.
Regarding the pin powering the transceiver, I tried it and it works fine. The only reason I am doing this is to save power because switching the pin LOW means 0 current and this is required since the device is battery powered.

No, 0xE0E0 is the address of the address, it works out of pure luck.

bool success = radio.write(msg, 4);

Packet Identity (PID) and CRC used by Enhanced ShockBurst TM
Each packet contains a two bit wide PID field to detect if the received packet is new
or resent. The PID will prevent that the PRX device presents the same payload more
than once to the microcontroller. This PID field is incremented at the TX side for each
new packet received via the SPI interface. The PID and CRC field is used by the PRX
device to determine whether a packet is resent or new. When several data is lost on
the link, the PID fields may in some cases become equal to last received PID. If a
packet has the same PID as the previous packet, nRF24L01 will compare the CRC
sums from both packets. If they also are equal, the last received packet is considered
as a copy of the previous and is discarded.

The PRX device compares the received PID with the last PID. If the PID fields are
different, the packet is considered to be new. If the PID is equal to last received PID,
the received packet might be the same as last time. The receiver must check if the
CRC is equal to the previous CRC. If the CRC is equal to the previous one, the packet
is probably the same, and will be discarded.

Sending the same packet twice would also work, but uses more energy.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.