Problem using nRF24L01 radios to send and receive an array of data

Hi everyone,

I am trying to use nRF24L01 radios to send data between two Arduino boards. I would like to send one array of data from one uno which is attached to the computer (I will call him the receiver) to another uno (I will call him the transmitter), I would also like to send an array of data from 'the transmitter' uno back to the computer based uno.

The transmitter has attached 2 analogue sensors and 2 buttons, the data of which is sent to the receiver.
The receiver needs to send 3 pieces of information to the transmitter to set the controls for a haptic motor, which I want to be able to change dynamically.

I have the set-up working up to the point of two-way communication, in that I have the transmitter sending what I need to the receiver. I am now trying to send the other data back to the transmitter and have become stuck.

I have lots of nRF24 libraries including mirf, maniacbug and tmrh240 and I have tried scouring forums and examples to help me achieve the above but to no avail.

I thought this last post on here was promising but I couldn't quite make it happen.

I have tried using the above linked forum post to create the skeleton of what i need (might be offering up an xy problem here so sorry if i am!)

So here is the code I adapted from that but all I get are zeros.

The receiver code

/*
http://www.bajdi.com
Receive and transmit analog values RECEIVER
https://forum.arduino.cc/index.php?topic=97026.0
*/

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

int joystick[4];
int current[3];   // Array with the 4 motor current values, to sent to remote control

int apin[] = { 
  A0, A1, A2 };  // analog pin array

RF24 radio(9,10);
const uint64_t pipes[2] = { 
  0xF0F0F0F0E1LL, 0xF0F0F0F0D2LL };

void setup(void)
{
  Serial.begin(9600);
  radio.begin();
  radio.openWritingPipe(pipes[1]);
  radio.openReadingPipe(1,pipes[0]);
  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( &joystick, sizeof(joystick) );
    }
  }

  radio.stopListening();
  
  // 4 analog readings from motor controller = motor current
  for (int i=0; i<3; i++)
  {
    current[i] = analogRead( apin[i] );
  }

  bool ok = radio.write( &current, sizeof(current) );

  radio.startListening();
  
  Serial.print(joystick[0]);
  Serial.print(" ");
  Serial.println(joystick[1]);
}

The transmitter

/*
http://www.bajdi.com
Receive and transmit analog values TRANSMITTER
https://forum.arduino.cc/index.php?topic=97026.0
*/

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

int current[3];
int joystick[4];   // Array with the 4 motor current values, to sent to remote control

int apin[] = { 
  A0, A1, A2, A3 };  // analog pin array

RF24 radio(9,10);
const uint64_t pipes[2] = { 
  0xF0F0F0F0E1LL, 0xF0F0F0F0D2LL };

void setup(void)
{
  Serial.begin(9600);
  radio.begin();
  radio.openWritingPipe(pipes[1]);
  radio.openReadingPipe(1,pipes[0]);
  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( &current, sizeof(current) );
    }
  }

  radio.stopListening();
  
  // 4 analog readings from motor controller = motor current
  for (int i=0; i<4; i++)
  {
    joystick[i] = analogRead (apin[i]) ;
  }

  bool ok = radio.write( &joystick, sizeof(joystick) );

  radio.startListening();
  
  Serial.print(current[0]);
  Serial.print(" ");
  Serial.println(current[1]);
}

Any help would be very greatly appreciated!

Thanks,

Asha

Have a look at this Simple nRF24L01+ Tutorial. Some of the examples send data from arrays.

...R

Thanks Robin,

I had seen your tutorial but couldn't quite get my head around it yesterday. I have had better luck today and so below are the modified transmitter and receiver to just be sending two sensor readings (from 2 analogue inputs) from each arduino to the other.

I have commented out some things (serial prints mainly) but also part of the void updateReplyData() and was wondering if you think this would cause problems?

I have also took the txIntervalMillis down to 10ms as I need the speed. This did cause a few "acknowledge but no data" instances but they are negligible for my purposes and a serial port crash but that might have been coincidental.

Thanks for the great tutorial and the help.

Asha

code for transmitter

// SimpleTxAckPayload - the master or the transmitter

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


#define CE_PIN   9
#define CSN_PIN 10

const byte slaveAddress[5] = {'R','x','A','A','A'};

RF24 radio(CE_PIN, CSN_PIN); // Create a Radio
int sen1 = 0;
int sen2 = 0;
int set1 = 0;
int set2 = 0;
int dataToSend[2];
char txNum = '0';
int ackData[2] = {set1, set2}; // to hold the two values coming from the slave
bool newData = false;

unsigned long currentMillis;
unsigned long prevMillis;
unsigned long txIntervalMillis = 10; // send once per second

//===============

void setup() {

    Serial.begin(9600);
    Serial.println(F("Source File /mnt/sdb1/SGT-Prog/Arduino/ForumDemos/nRF24Tutorial/SimpleTxAckPayload.ino"));
    Serial.println("SimpleTxAckPayload Starting");

    radio.begin();
    radio.setDataRate( RF24_250KBPS );

    radio.enableAckPayload();

    radio.setRetries(3,5); // delay, count
    radio.openWritingPipe(slaveAddress);
}

//=============

void loop() 


{
  dataToSend [0] = analogRead(A0);
  dataToSend [1] = analogRead(A1);
  
    currentMillis = millis();
    if (currentMillis - prevMillis >= txIntervalMillis) {
        send();
    }
    showData();
}


//================

void send() {

    bool rslt;
    rslt = radio.write( &dataToSend, sizeof(dataToSend) );
        // Always use sizeof() as it gives the size as the number of bytes.
        // For example if dataToSend was an int sizeof() would correctly return 2

 //   Serial.print("Data Sent ");
 //   Serial.print(dataToSend);
    if (rslt) {
        if ( radio.isAckPayloadAvailable() ) {
            radio.read(&ackData, sizeof(ackData));
            newData = true;
        }
        else {
          //  Serial.println("  Acknowledge but no data ");
        }
        updateMessage();
    }
    else {
        Serial.println("  Tx failed");
    }

    prevMillis = millis();
 }


//=================

void showData() {
    if (newData == true) {
        //Serial.print("  Acknowledge data ");
        Serial.print(ackData[0]);
        Serial.print(" ");
        Serial.println(ackData[1]);
        newData = false;
    }
}

//================

void updateMessage() {
        // so you can see that new data is being sent
    txNum += 1;
    if (txNum > '9') {
        txNum = '0';
    }
    dataToSend[8] = txNum;
}

code for receiver

// SimpleRx - the slave or the receiver

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

#define CE_PIN   9
#define CSN_PIN 10

const byte thisSlaveAddress[5] = {'R','x','A','A','A'};

RF24 radio(CE_PIN, CSN_PIN);

int dataReceived[2]; // this must match dataToSend in the TX
int ackData[2]; // the two values to be sent to the master
bool newData = false;

//==============

void setup() {

    Serial.begin(9600);

    Serial.println("SimpleRxAckPayload Starting");
    radio.begin();
    radio.setDataRate( RF24_250KBPS );
    radio.openReadingPipe(1, thisSlaveAddress);

    radio.enableAckPayload();
    radio.writeAckPayload(1, &ackData, sizeof(ackData)); // pre-load data

    radio.startListening();

     ackData [0] = analogRead(A0);
     ackData [1] = analogRead(A1);
}

//==========

void loop() {
    getData();
    showData();
}

//============

void getData() {
    if ( radio.available() ) {
        radio.read( &dataReceived, sizeof(dataReceived) );
        updateReplyData();
        newData = true;
    }
}

//================

void showData() {
    if (newData == true) {
       // Serial.print("Data received ");
        Serial.print(dataReceived[0]);
       // Serial.print("Data received ");
        Serial.print(" ");
        Serial.println(dataReceived[1]);
      //  Serial.print(" ackPayload sent ");
      //  Serial.print(ackData[0]);
      //  Serial.print(", ");
      //  Serial.println(ackData[1]);
        newData = false;
    }
}

//================

void updateReplyData() {
  
    ackData[0] = analogRead(A0);
    ackData[1] = analogRead(A1);
  /*  if (ackData[0] < 100) {
        ackData[0] = 109;
    }
    if (ackData[1] < -4009) {
        ackData[1] = -4000;
    }*/
    radio.writeAckPayload(1, &ackData, sizeof(ackData)); // load the payload for the next time
}