NRF24l01+ and Mirf library

Hi!

I’m working on a project where two Arduinos need to communicate over radio using the NRF24l01+ card. I’m using the Mirf library, and my problem is quite simple. When a button is pressed, I send a packet from one of the Arduinos (let’s call it A), containing 32 bytes of data. This part works well, and I can perform some actions (move a robot) on the receiving Arduino (B). However, when B has processed the data sent from A, it should send a reply. This reply is never received on A.

Below are some relevant excerpts of my code:

Receiving code on Arduino A:

#include <SPI.h>
#include <Mirf.h>
#include <nRF24L01.h>
#include <MirfHardwareSpiDriver.h>

void setup() {
  Serial.begin(9600);
  Mirf.spi = &MirfHardwareSpi;
  Mirf.init();
  Mirf.setRADDR((byte *) "cmdce");
  Mirf.channel = 90;
  Mirf.payload = 32;
  Mirf.config();
}

void loop() {
  if (!Mirf.isSending() && Mirf.dataReady()) {
    byte packet[32];
    Mirf.getData((byte*) &packet);
    delay(50);
    
    if (packet[0] == 254 && packet[2] == 255) {
      message = packet[1];

      if (message = 7) {
        Serial.print(0); //Used to stop program
        digitalWrite(compileLedPin, HIGH);
        digitalWrite(stopLedPin, LOW);
      }

    } else {
      Serial.print("Wrong data received: "); //This part never runs
      Serial.print(packet[0]);
      Serial.print(packet[1]);
      Serial.println(packet[2]);
    }
  }

...Button handling etc. omitted
}

Arduino B

#include <SPI.h>
#include <Mirf.h>
#include <nRF24L01.h>
#include <MirfHardwareSpiDriver.h>

void setup() {

  Serial.begin(9600);
  Mirf.spi = &MirfHardwareSpi;
  Mirf.init();
  Mirf.setRADDR((byte *) "robot");
  Mirf.channel = 90;
  Mirf.payload = 32;
  Mirf.config();

  Serial.println("Enter Commands...");
}

void loop() {

  handleTransmission(0); //Check for data sent from A and determine that it is correct

  if (foundHeader && foundTail) { //The data is correct
    programLength = tailPosition - 1;
    Serial.println(F("Starting program interpretation..."));
    runProgram(program, 0, programLength); //Run robot commands
  }
}

//This function is called from inside runProgram when the program is finished.  
void reset() {
  foundHeader = false;
  foundTail = false;
  moreToReceive = false;
  tailPosition = 1;
  programLength = 0;
  sendMsg(7);
}

//Send reply back to Arduino A
void sendMsg(byte message) {
  messageStruct str;
  str.head = 254;
  str.message[0] = message;
  str.message[1] = 255;

  Mirf.setTADDR((byte *) "cmdce"); // Transmitting adress

  Mirf.send((byte *) &str);
  while (Mirf.isSending()) {
    Serial.println("Sending...");
    delay(10);
  } // Changed to receive mode

  delay(100);
  Serial.println("Sending complete");
}

Any help would be fantastic!

I am not familiar with that library. The examples in this Simple nRF24L01+ Tutorial use the the TMRh20 RF24 library

…R

Thanks for your quick reply!

Unfortunately, I tried using that library before but couldn't get it to work. Maybe I should try again. The example you linked seem quite informative.

I am also not familiar with that library but I know the module quite well.
You need to be aware that you can only be in transmission or receiving mode, not both at the same time. If you want two-way communication you need to switch between receiving and transmitting mode all the time OR you can use ACK-payloads, then the switching between the modes is done by the module but you can only send data from the receiving node once you receive a message and you need to pre-load that message into the module beforehand.

DedeHai:
You need to be aware that you can only be in transmission or receiving mode, not both at the same time.

Thanks, this might actually be a key to getting it to work!

DedeHai:
...you need to pre-load that message into the module beforehand.

Does that mean that I can only reply with a single, static message using this method?

roblox:
Does that mean that I can only reply with a single, static message using this method?

You can load any message you like into the ackPayload buffer. But it must be loaded before the RX receives a message because it will be sent automatically as part of the regular acknowledge process.

It is a very convenient way to achieve 2-way communication. My second example illustrates the ackPaylod process. And my examples have worked for others.

...R