Sending Array via Nrf24l01

Hi guys.
I want to send an array via nrf24l01 to arduino due from arduino uno. This array is for Joystick. So it has 2 sets of value. x and y. The problem is when I send it, the receiver gets the data but it writes the array[0] to receivedarray[0] and receivedarray[1]. Sometimes it writes array[1] to both receivedarray[0] and receivedarray[1]. How can i fix it? Any ideas? It's urgent.

I have:

1 Arduino Uno
1 Arduino Due
2 Nrf24L01

Verici_v2.3 is my Transmitter Code,
Receiver_v2.3 is my Receiver Code.
I'm a newbie to arduino so all helps will be appriciated.
Thanks.

Verici_v2.3.ino (2.25 KB)

Receiver_v2.3.ino (998 Bytes)

  for(int i = 0; i<2;i++){
  radio.write(&joystick[i], sizeof(joystick[i]));delay(30);}

It does not make sense to use an array, and then send one element at a time. The delay() between sending values does not make sense.

  radio.write(joystick, sizeof(joystick));
  for(int i = 0; i<2;i++){
  radio.read(&movement[i], len);delay(45);}

It does not make sense to use an array, and then read one element at a time. The delay() between reading values does not make sense.

  radio.read(movement, 2);

PaulS:

  for(int i = 0; i<2;i++){

radio.write(&joystick[i], sizeof(joystick[i]));delay(30);}



It does not make sense to use an array, and then send one element at a time. The delay() between sending values does not make sense.




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







for(int i = 0; i<2;i++){
 radio.read(&movement[i], len);delay(45);}



It does not make sense to use an array, and then read one element at a time. The delay() between reading values does not make sense.



radio.read(movement, 2);

Thanks for your response. I did what you said, now when i move joystick right or left it gets the values. But still it changes both x and y at the same time. And it doesnt get the y values. Do you have an example for an array send? Thanks again. Here is the serial screen result when I move joystick right:
x: 200
y: 200
left:
x: 0
y: 0

It should be:
Right:
x: 200
y: 100
Left:
x: 0
y: 100

Here is the serial screen result when I move joystick right:

Is that from the sender or the receiver?

PaulS:
Is that from the sender or the receiver?

receiver ofcourse.
Transmitter serial shows this values for right:
x: 200
y: 100

Left:
x: 0
y: 100

Up:
x: 100
y: 200

Down:
x: 100
y: 0

You should post your modified code, so we can make sure you changed things correctly.

PaulS:
You should post your modified code, so we can make sure you changed things correctly.

Oh okey, sorry. I'm new to forums too :slight_smile:

Verici_v2.3.ino (2.21 KB)

Receiver_v2.3.ino (893 Bytes)

If you are going to compare apples to apples, you should print what you send, not what you think you are sending:

  Serial.print("joystick[0]: "); Serial.println(joystick[0]);
  Serial.print("joystick[1]: "); Serial.println(joystick[1]);
  radio.read(&movement, 2);

Why is the & there?

PaulS:
If you are going to compare apples to apples, you should print what you send, not what you think you are sending:

  Serial.print("joystick[0]: "); Serial.println(joystick[0]);

Serial.print("joystick[1]: "); Serial.println(joystick[1]);






radio.read(&movement, 2);



Why is the & there?

I saw some examples using &, when i try it now it doesn't make any difference. Any other suggestions?

Any other suggestions?

What I would be looking at is how much data is available to be read when radio.read() is called. How much data does it actually read?

Another thing I'd try is sending more data, like "ABCDEFG", and see if that is handled correctly.

PaulS:
What I would be looking at is how much data is available to be read when radio.read() is called. How much data does it actually read?

Another thing I'd try is sending more data, like "ABCDEFG", and see if that is handled correctly.

That idea made me think. If byte is in between 0-255, in my array it should be 200+200 = 400. So i tried mapping the value between 0-100, nothing changes. I think the only problem is, radio.read() doesnt take the data seperately. I mean, it takes first data of array and stops. Is there really no example at all to send an array with RF24 library? That really sucks :confused:
P.S: i tried sending "ABCDEFG" as a char array. The same problem continues. this is the changes i made:
Transmitter:

 char a[] = "ABCDEFG";
  radio.write(a, sizeof(a));

Receiver:

char a[7];
radio.read(&a,sizeof(a));
//& is necessary for char i guess. Didn't work without &

And the outcome is:
a[0]: A
a[1]: A
same for 7 value.

This proves that the radio.read() writes the first payload it gets to every single index of array.
Is there a method that lets us keep 2 sets of payload?

Something like the following should work better.

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#define CE_PIN 7
#define CSN_PIN 8

const uint64_t pipe = 0xE8E8F0F0E1LL;
RF24 radio(CE_PIN, CSN_PIN);
byte movement[2];

void setup() {
  radio.begin();
  radio.openReadingPipe(1, pipe);
  pinMode(13, OUTPUT);
  radio.powerUp();
  Serial.begin(9600);
  radio.enableDynamicPayloads();
  radio.setDataRate(RF24_250KBPS);
  radio.printDetails();
  radio.startListening();
}

void loop() {
  if (radio.available()) {
    radio.read(movement, sizeof(movement));
    Serial.print(F("x: "));
    Serial.print(movement[0]);
    Serial.print(F(" y: "));
    Serial.println(movement[1]);
  }
}

Do not read from the chip when there is no data.
Do not read more data than available (even if the chip repeats the last byte in that case).

1 Like

Whandall:
Something like the following should work better.

#include <SPI.h>

#include <nRF24L01.h>
#include <RF24.h>
#define CE_PIN 7
#define CSN_PIN 8

const uint64_t pipe = 0xE8E8F0F0E1LL;
RF24 radio(CE_PIN, CSN_PIN);
byte movement[2];

void setup() {
  radio.begin();
  radio.openReadingPipe(1, pipe);
  pinMode(13, OUTPUT);
  radio.powerUp();
  Serial.begin(9600);
  radio.enableDynamicPayloads();
  radio.setDataRate(RF24_250KBPS);
  radio.printDetails();
  radio.startListening();
}

void loop() {
  if (radio.available()) {
    radio.read(movement, sizeof(movement));
    Serial.print(F("x: "));
    Serial.print(movement[0]);
    Serial.print(F(" y: "));
    Serial.println(movement[1]);
  }
}



Do **not** read from the chip when there is no data.
Do **not** read more data than available (even if the chip repeats the last byte in that case).

I wrote that exactly the same, now it doesnt even enter the "if" command.I put an else to make sure.
It says no radio available now. Its not possible because without the radio.available() method i was able to send data.
Even if it does enter the if command it gets 255 value that not even related to the one i send

So you probaby still have the & in the send part. Try this or something like this

#include <JoystickShield.h>

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

RF24 radio(9, 10);
JoystickShield joystickShield;
const uint64_t rxAddr = 0xE8E8F0F0E1LL;

void setup()
{
  Serial.begin(9600);
  joystickShield.calibrateJoystick();
  radio.begin();
  radio.setRetries(15, 15);
  radio.openWritingPipe(rxAddr);
  radio.powerUp();
  radio.setDataRate(RF24_250KBPS);
  radio.enableDynamicPayloads();
}

void loop()
{
  joystickShield.processEvents();
  byte joystick[2];
  joystick[0] = map(joystickShield.xAmplitude(), -100, 100, 0, 200);
  joystick[1] = map(joystickShield.yAmplitude(), -100, 100, 0, 200);

  radio.write(joystick, sizeof(joystick));
  Serial.print(F("x "));
  Serial.print(joystick[0]);
  Serial.print(F(" y "));
  Serial.println(joystick[1]);

  if (joystickShield.isUp()) {
    Serial.println(F("Up"));
  }
  if (joystickShield.isRightUp()) {
    Serial.println(F("RightUp"));
  }
  if (joystickShield.isRight()) {
    Serial.println(F("Right"));
  }
  if (joystickShield.isRightDown()) {
    Serial.println(F("RightDown"));
  }
  if (joystickShield.isDown()) {
    Serial.println(F("Down"));
  }
  if (joystickShield.isLeftDown()) {
    Serial.println(F("LeftDown"));
  }
  if (joystickShield.isLeft()) {
    Serial.println(F("Left"));
  }
  if (joystickShield.isLeftUp()) {
    Serial.println(F("LeftUp"));
  }
  if (joystickShield.isJoystickButton()) {
    Serial.println(F("Joystick Clicked"));
  }
  if (joystickShield.isUpButton()) {
    Serial.println(F("Up Button Clicked"));
  }
  if (joystickShield.isRightButton()) {
    Serial.println(F("Right Button Clicked"));
  }
  if (joystickShield.isDownButton()) {
    Serial.println(F("Down Button Clicked"));
  }
  if (joystickShield.isLeftButton()) {
    Serial.println(F("Left Button Clicked"));
  }
  // new eventfunctions
  if (joystickShield.isEButton()) {
    Serial.println(F("E Button Clicked"));
  }
  if (joystickShield.isFButton()) {
    Serial.println(F("F Button Clicked"));
  }
  if (joystickShield.isNotCenter()) {
    Serial.println(F("NotCenter"));
  }
  delay(500);
}
1 Like

Whandall:
So you probaby still have the & in the send part. Try this or something like this

#include <JoystickShield.h>

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

RF24 radio(9, 10);
JoystickShield joystickShield;
const uint64_t rxAddr = 0xE8E8F0F0E1LL;

void setup()
{
  Serial.begin(9600);
  joystickShield.calibrateJoystick();
  radio.begin();
  radio.setRetries(15, 15);
  radio.openWritingPipe(rxAddr);
  radio.powerUp();
  radio.setDataRate(RF24_250KBPS);
  radio.enableDynamicPayloads();
}

void loop()
{
  joystickShield.processEvents();
  byte joystick[2];
  joystick[0] = map(joystickShield.xAmplitude(), -100, 100, 0, 200);
  joystick[1] = map(joystickShield.yAmplitude(), -100, 100, 0, 200);

radio.write(joystick, sizeof(joystick));
  Serial.print(F("x "));
  Serial.print(joystick[0]);
  Serial.print(F(" y "));
  Serial.println(joystick[1]);

if (joystickShield.isUp()) {
    Serial.println(F("Up"));
  }
  if (joystickShield.isRightUp()) {
    Serial.println(F("RightUp"));
  }
  if (joystickShield.isRight()) {
    Serial.println(F("Right"));
  }
  if (joystickShield.isRightDown()) {
    Serial.println(F("RightDown"));
  }
  if (joystickShield.isDown()) {
    Serial.println(F("Down"));
  }
  if (joystickShield.isLeftDown()) {
    Serial.println(F("LeftDown"));
  }
  if (joystickShield.isLeft()) {
    Serial.println(F("Left"));
  }
  if (joystickShield.isLeftUp()) {
    Serial.println(F("LeftUp"));
  }
  if (joystickShield.isJoystickButton()) {
    Serial.println(F("Joystick Clicked"));
  }
  if (joystickShield.isUpButton()) {
    Serial.println(F("Up Button Clicked"));
  }
  if (joystickShield.isRightButton()) {
    Serial.println(F("Right Button Clicked"));
  }
  if (joystickShield.isDownButton()) {
    Serial.println(F("Down Button Clicked"));
  }
  if (joystickShield.isLeftButton()) {
    Serial.println(F("Left Button Clicked"));
  }
  // new eventfunctions
  if (joystickShield.isEButton()) {
    Serial.println(F("E Button Clicked"));
  }
  if (joystickShield.isFButton()) {
    Serial.println(F("F Button Clicked"));
  }
  if (joystickShield.isNotCenter()) {
    Serial.println(F("NotCenter"));
  }
  delay(500);
}

Still doesn't work. This is making me crazy. Is there any working example of array sending ? Might due cause this sickness?

Whandall:
So you probaby still have the & in the send part. Try this or something like this

#include <JoystickShield.h>

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

RF24 radio(9, 10);
JoystickShield joystickShield;
const uint64_t rxAddr = 0xE8E8F0F0E1LL;

void setup()
{
  Serial.begin(9600);
  joystickShield.calibrateJoystick();
  radio.begin();
  radio.setRetries(15, 15);
  radio.openWritingPipe(rxAddr);
  radio.powerUp();
  radio.setDataRate(RF24_250KBPS);
  radio.enableDynamicPayloads();
}

void loop()
{
  joystickShield.processEvents();
  byte joystick[2];
  joystick[0] = map(joystickShield.xAmplitude(), -100, 100, 0, 200);
  joystick[1] = map(joystickShield.yAmplitude(), -100, 100, 0, 200);

radio.write(joystick, sizeof(joystick));
  Serial.print(F("x "));
  Serial.print(joystick[0]);
  Serial.print(F(" y "));
  Serial.println(joystick[1]);

if (joystickShield.isUp()) {
    Serial.println(F("Up"));
  }
  if (joystickShield.isRightUp()) {
    Serial.println(F("RightUp"));
  }
  if (joystickShield.isRight()) {
    Serial.println(F("Right"));
  }
  if (joystickShield.isRightDown()) {
    Serial.println(F("RightDown"));
  }
  if (joystickShield.isDown()) {
    Serial.println(F("Down"));
  }
  if (joystickShield.isLeftDown()) {
    Serial.println(F("LeftDown"));
  }
  if (joystickShield.isLeft()) {
    Serial.println(F("Left"));
  }
  if (joystickShield.isLeftUp()) {
    Serial.println(F("LeftUp"));
  }
  if (joystickShield.isJoystickButton()) {
    Serial.println(F("Joystick Clicked"));
  }
  if (joystickShield.isUpButton()) {
    Serial.println(F("Up Button Clicked"));
  }
  if (joystickShield.isRightButton()) {
    Serial.println(F("Right Button Clicked"));
  }
  if (joystickShield.isDownButton()) {
    Serial.println(F("Down Button Clicked"));
  }
  if (joystickShield.isLeftButton()) {
    Serial.println(F("Left Button Clicked"));
  }
  // new eventfunctions
  if (joystickShield.isEButton()) {
    Serial.println(F("E Button Clicked"));
  }
  if (joystickShield.isFButton()) {
    Serial.println(F("F Button Clicked"));
  }
  if (joystickShield.isNotCenter()) {
    Serial.println(F("NotCenter"));
  }
  delay(500);
}

PaulS:
If you are going to compare apples to apples, you should print what you send, not what you think you are sending:

  Serial.print("joystick[0]: "); Serial.println(joystick[0]);

Serial.print("joystick[1]: "); Serial.println(joystick[1]);






radio.read(&movement, 2);



Why is the & there?

Thank you both for your helps! It finally worked. Whandall last code you sent worked actually. I was so mad I forgot to check the cable connections. :slight_smile: thanks a lot again. I'm uploading the working versions of my codes so that someone could have the same problem. I hope this helps.

Verici_v2.4.ino (2.06 KB)

Receiver_v2.3.ino (734 Bytes)

1 Like