Sending multiple values with NRF24L01

Hello, I am using NRF24L01 modules with Nanos and the TMRh20 library. I am trying to send four potentiometer values from one Nano to the other, one way. If it is important, each of these values is between 0 and 255, so one byte each. I am new to Arduino and the coding language, so I am just looking for a fast, simple way to do this. Thanks for any input!

I would use an array, and this bare-bones implementation will work, but won’t have smoothing for the potentiometer line, which can be pretty noisy sometimes:

const int num = 4;  // Declare array size
int Array[num];  // Declare array as global variable

void setup(){
  [i]Do setup stuff here....[/i]
}

void loop(){

  Array[0] = analogRead(A0);  
  Array[1] = analogRead(A1);
  Array[2] = analogRead(A2);  
  Array[3] = analogRead(A3);

  if (!wirelessSPI.write( &Array, sizeof(Array) )){  
    Serial.println("packet delivery failed");
  }

  delay(1000);

}

If you want to smooth the data from the pot, then I would recommend putting a small cap between data-line and ground, then take multiple readings and average for a cleaner read:

// Define how many entries in array, and how many times to samples pot readings
  const int num = 4, numReadings = 10;  

// Define 2-dimension array.  Values are stored in first col, corresponding pin in 2nd col, which is entered by hand
  int Array[num][2]{  
    Array[0][1] = A0,
    Array[1][1] = A1,
    Array[2][1] = A2,
    Array[3][1] = A3};

void setup(){
  [i]Do setup stuff here....[/i]
}

void loop(){

// For-loop ticks through each row of array and sums multiple readings in the first column from the pin given in 
// corresponding second column of same row.  Then the summed value is divided by number of readings and 
// average is stored in array.  

  for (byte i=0; i<num; i++){
    int avg = 0;
    for (byte k=0; k<numReadings; k++){
      avg += analogRead(Array[i][1]);
      delay(10);
    }
    avg = avg / numReadings;
    Array[i][0] = avg;
  }

// Transmit array thru NRF, which has max of 16 bytes - 2x this array size.

  if (!wirelessSPI.write(&Array, sizeof(Array))){  
    Serial.println("packet delivery failed");
  }

  delay(1000);
}

Thanks for your reply. I tried this code for the transmitter:

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

RF24 radio(8, 9);
const byte address[6] = "00001";

byte Array[4];

void setup() {
 radio.begin();
 radio.openWritingPipe(address);
 radio.setPALevel(RF24_PA_MIN);
 radio.stopListening();
 Serial.begin(9600);
}

void loop() {
 Array[0] = analogRead(A0);  
 Array[1] = analogRead(A1);
 Array[2] = analogRead(A2);  
 Array[3] = analogRead(A3);

 radio.write(&Array, sizeof(Array));
 Serial.println("Sending");
 delay(20);
}

…and this code for the receiver:

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

RF24 radio(9, 10);
const byte address[6] = "00001";

void setup() {
  radio.begin();
  radio.openReadingPipe(0, address);
  radio.setPALevel(RF24_PA_MIN);
  radio.startListening();
  Serial.begin(9600);
}

void loop() {
  if (radio.available()) {
    byte Array[4];
    radio.read(&Array, sizeof(Array));
    Serial.print(Array[0]);
    Serial.println();
  }
}

This code is meant to simply transmit the four bytes, and then print the value of the first byte, to test if it worked. However, the receiver just prints out a ton of zeros, then random values, and then stops. Am I doing something wrong in the code?

Try this code, and double-check your pin declarations to make sure they match what you have hooked up (I noticed CE and CSN are different for your tx vs rx):

Receiver:

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

const int pinCE = 9; 
const int pinCSN = 10; 
int gotArray[4]; 

RF24 wirelessSPI(pinCE, pinCSN);  
const uint64_t pAddress = 0xB00B1E5000LL;  

void setup()   
{
 Serial.begin(9600);  
 wirelessSPI.begin();  
 wirelessSPI.setAutoAck(1);             
 wirelessSPI.enableAckPayload();        
 wirelessSPI.setRetries(5,15);        
 wirelessSPI.openReadingPipe(1,pAddress);   
 wirelessSPI.startListening();      
 wirelessSPI.printDetails();     
}

void loop()  
{   
  while(wirelessSPI.available()){ 
    wirelessSPI.read( &gotArray, sizeof(gotArray) ); 
    Serial.print("Recieved array:"); 
    for (byte i=0; i<4; i++){
      Serial.println(gotArray[i]);
    }
    Serial.println();
   }
  
 delay(100);    
}

Transmitter:

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

const int pinCE = 8; 
const int pinCSN = 9; 
int Array[4];

RF24 wirelessSPI(pinCE, pinCSN); 
const uint64_t pAddress = 0xB00B1E5000LL;       

void setup()  
{
 Serial.begin(9600);       
 wirelessSPI.begin();          
 wirelessSPI.setAutoAck(1);                
 wirelessSPI.enableAckPayload();         
 wirelessSPI.setRetries(5,15);            
 wirelessSPI.openWritingPipe(pAddress);   
 wirelessSPI.stopListening();
 wirelessSPI.printDetails();  
}

void loop()  
{
   Array[0] = analogRead(A0);  
   Array[1] = analogRead(A1);
   Array[2] = analogRead(A2);  
   Array[3] = analogRead(A3);
   
   Serial.println("Now sending data... "); 
   
   if (!wirelessSPI.write( &Array, sizeof(Array))){ 
      Serial.println("delivery failed"); 
      Serial.println();     
  }
  else { 
      Serial.println("Send successful.");
      Serial.println();
  }
   delay(1000);
}

After posting this I realized that analogRead() returns an int, not a byte, and that will cause problems. So I changed the byte variables to int, and that would need to be changed in the code I posted earlier as well {Edit: done}. You can do a conversion by mapping the int variable to a value of 0-255 and store it as a byte variable.

In the code you posted I notice that the transmitter is sending a value every 20 milliseconds, and that will cause a rapid print-out of received values. Why it stopped, I can’t say.

Do you have a 10 uF capacitor soldered between VCC and GND on the NRF?

Sending the array is the correct thing to do.

Have a look at this Simple nRF24L01+ Tutorial.

...R

silly_cone, I just tried your code. Also, I double-checked the CE and CSN pins on my Arduinos. In the serial monitor, the transmitter printed "Send Successful." However, the receiver just printed zeros, with an occasional random number. Also, it "received" data much faster than the transmitter sent it. Any ideas?

hmmm, I left my programmer at home today, so once I get off work I’ll load it and see what I get. I’ll update you in about 3 hours…

Edit:

I’ve got the stuff with me to program some NodeMCU boards, so I changed the code above to assign incremented values to the array, then send since NodeMCU only has a single analog pin.

This code is confirmed to work and will work equally well on arduino as NodeMCU, so if you’re still getting issues that would suggest some hardware issue.

Tx:

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

const int pinCE = 2; 
const int pinCSN = 15; 
int Array[4];
int counter = 0;

RF24 wirelessSPI(pinCE, pinCSN); 
const uint64_t pAddress = 0xB00B1E5000LL;       

void setup()  
{
 Serial.begin(9600);       
 wirelessSPI.begin();          
 wirelessSPI.setAutoAck(1);                
 wirelessSPI.enableAckPayload();         
 wirelessSPI.setRetries(5,15);            
 wirelessSPI.openWritingPipe(pAddress);   
 wirelessSPI.stopListening();
 wirelessSPI.printDetails();  
}

void loop()  
{
   for (int i=0; i<4; i++){
     Array[i] = counter;  
     counter++;
   }
   
   Serial.println("Now sending data... "); 
   
   if (!wirelessSPI.write( &Array, sizeof(Array))){ 
      Serial.println("delivery failed"); 
      Serial.println();     
  }
  else { 
      Serial.println("Send successful.");
      Serial.println();
  }
   delay(1000);
}

Rx:

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

const int pinCE = 2; 
const int pinCSN = 15; 
int gotArray[4]; 

RF24 wirelessSPI(pinCE, pinCSN);  
const uint64_t pAddress = 0xB00B1E5000LL;  

void setup()   
{
 Serial.begin(9600);  
 wirelessSPI.begin();  
 wirelessSPI.setAutoAck(1);             
 wirelessSPI.enableAckPayload();        
 wirelessSPI.setRetries(5,15);        
 wirelessSPI.openReadingPipe(1,pAddress);   
 wirelessSPI.startListening();      
 wirelessSPI.printDetails();     
}

void loop()  
{   
  while(wirelessSPI.available()){ 
    wirelessSPI.read( &gotArray, sizeof(gotArray) ); 
    Serial.print("Recieved array:"); 
    for (byte i=0; i<4; i++){
      Serial.println(gotArray[i]);
    }
    Serial.println();
   }
  
 delay(100);    
}

Do you get the correct output from the printDetails function? Can you post your serial output and pictures of your setup?

Here is the serial output on the receiver from the code above:

ȤlìÉã¬l$øÀ$:hþøüSTATUS		 = 0x0e RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=7 TX_FULL=0
RX_ADDR_P0-1	 = 0xb00b1e5000 0xb00b1e5000
RX_ADDR_P2-5	 = 0xc3 0xc4 0xc5 0xc6
TX_ADDR		 = 0xb00b1e5000
RX_PW_P0-6	 = 0x20 0x20 0x00 0x00 0x00 0x00
EN_AA		 = 0x3f
EN_RXADDR	 = 0x02
RF_CH		 = 0x4c
RF_SETUP	 = 0x07
CONFIG		 = 0x0f
DYNPD/FEATURE	 = 0x03 0x06
Data Rate	 = 1MBPS
Model		 = nRF24L01+
CRC Length	 = 16 bits
PA Power	 = PA_MAX

Recieved array:
0
1
2
3

Recieved array:
4
5
6
7

Recieved array:
8
9
10
11

Just found the problem: my Arduinos switched port numbers, so I had the wrong values for the CE and CSN pins. I don't know what happened, because they are plugged into the same USB ports as earlier today when it was working, but I guess they switched when I turned my computer off and then on again. Thanks for the help, and your code for sending arrays works now!

that would do it; glad it's working now!

Silly cone, what Arduino ports are each of your antenna ports plugged into?