RF24 radio modules and sending two payloads of information.

I have two nrf24L01 transceiver modules and need help with programming issues. All I want is to be able to send both the state of a button, and the value of a potentiometer from the transmitter over to the receiver. I can successfully do both separately, but when I try to send both simultaneously, it does not work. I’ve tried experimenting with two separate pipes but have had no luck.
Please help a noob, Thanks in advance.

Here is my transmitter sketch:

/*

This sketch transmits 2 analog values through an nRF24L01 wireless module.
*/

#include <SPI.h>
#include “nRF24L01.h”
#include “RF24.h”

int joystick[2];
int button[1];

RF24 radio(9,10);

const uint64_t pipe = 0xE8E8F0F0E1LL;

void setup(void)
{
Serial.begin(9600);
radio.begin();
radio.openWritingPipe(pipe);
}

void loop(void)
{
radio.stopListening();

joystick[0] = analogRead(A0);
joystick[1] = analogRead(A1);
Serial.println(joystick[0]);

radio.write( joystick, sizeof(joystick) );

button[0] = digitalRead(4);
Serial.println(button[0]);
radio.write( button, sizeof(button) );

}

Receiver Sketch:

#include <SPI.h>
#include “nRF24L01.h”
#include “RF24.h”
#include <Servo.h>

int joystick[2];
int button[1];

RF24 radio(9, 10);
const uint64_t pipe = 0xE8E8F0F0E1LL;

void setup(void)
{
Serial.begin(9600);
radio.begin();
radio.openReadingPipe(1,pipe);
radio.startListening();

}

void loop(void)
{
if ( radio.available() )
{
// Dump the payloads until we’ve gotten everything
bool done = false;
while (!done)
{
// Fetch the payload, and see if this was the last one.
done = radio.read( button, sizeof(button) );
done = radio.read( joystick, sizeof(joystick) );
}

}

Serial.println(button[0]);
}

IneedHelp:
it does not work

Did you see the sticky at the top of this section of the forum? “It does not work” hardly gives us much to go on.

Just looking at the design of your sketch I can see that your receiver logic is flawed in lots of ways. You don’t check whether there is a second payload available before trying to receive it. You expect to receive payloads in the reverse order that they were sent. You assume that every payload that is sent is received. You assume that you will receive both payloads in a single execution of loop(), which is pretty unlikely given how slow the radio is. Your message fgrmat doesn’t give you any way to work out what type of message you have received.

An array of size one for the button states seems somewhat pointless too, but perhaps you’re planning to extend that.

You can resolve all of these issues by defining a single message format that contains all the data you want to send, and then sending all your data in a single call to radio.write(). For example you could just put the button state as the third element of your message array, or you could define an struct containing the joystick data and the button data.

As an aside, the call to stopListening() is redundant since you never start listening, and you ought to be checking the return status from radio.write() and logging any failures that occur.

Wow, thanks PeterH , your the best! I did exactly what you said by putting the values in to one output message and it worked! As for some of the stuff you had mentioned, I was in a hurry when I made the post and realize now that there were many flaws, but you were very helpful in telling me what I did wrong, so I’m very appreciative.

I’m actually not sure how else to send the button state over without using an array but maybe that’s something I can edit in the future. For now, everything is running great!

Here is my updated transmitter sketch:

#include <SPI.h>
#include “nRF24L01.h”
#include “RF24.h”

int joystick[2];
int button[1];

RF24 radio(9,10);

const uint64_t pipe = 0xE8E8F0F0E1LL;

void setup(void)
{
Serial.begin(9600);
radio.begin();
radio.openWritingPipe(pipe);
}

void loop(void)
{
joystick[0] = analogRead(A0);
button[0] = digitalRead(4);
joystick[1] = button[0];
Serial.println(joystick[0]);
Serial.println(joystick[1]);

radio.write( joystick, sizeof(joystick) );

}

And my updated Receiver sketch:

int joystick[2];
int button[1];

RF24 radio(9, 10);
const uint64_t pipe = 0xE8E8F0F0E1LL;

void setup(void)
{
Serial.begin(9600);
radio.begin();
radio.openReadingPipe(1,pipe);
radio.startListening();

esc.attach(5);
pinMode(led, OUTPUT);
}

void loop(void)
{
if ( radio.available() )
{
// Dump the payloads until we’ve gotten everything
bool done = false;
while (!done)
{
// Fetch the payload, and see if this was the last one.
done = radio.read( joystick, sizeof(joystick) );
}

}

Thanks again for my first ever success on this Arduino forum!

If you only have a single button state to send, sending it as a byte or int is reasonable. If you need to send the state of multiple buttons, you could consider storing each button state as a single bit inside an int (the bitWrite() and bitRead() functions provide a convenient way to access individual bits). It makes the code a little more complex but makes the message smaller, which might become important if you need to support a lot of pins - the radio communication is more reliable for shorter messages and especially doesn't work well for long sequences of 'all ones' or 'all zeroes' in the message. If you were going anywhere with this sketch, you could also clean it up by putting your analog and digital pin numbers in arrays and using a for loop to read the state and store it into your message.