Need help with NRF24L01

Hi there, I'm making a monitoring system for small 2 stroke rc engines.

I'm using a program called SimpleDyno to do this, this program came with some code to make it work.

Now I want to make it wireless. I'm using 2 Arduino uno's with two NRF24l01.

I already tried a lot but I cant figure out what i'm doing wrong so I decided to start all over again.

I've listed the code below, can someone help me to get this wireless.

How it now works is it's needs to print Allresult in the serial and the program reads that. I need to recreate this exactly but then sending Allresult to the other Arduino and then printing it. I haven’t found any easy way to do this.

 const int NumPortsToRead = 6;
  int AnalogResult[NumPortsToRead];
  volatile unsigned long TimeStamp = 0;
  volatile unsigned long time1 = 0;
  volatile unsigned long time2 = 0;
  volatile unsigned long Oldtime1 = 0;
  volatile unsigned long Oldtime2 = 0;
  volatile unsigned long TempTime1 = 0;
  volatile unsigned long TempTime2 = 0;
  String AllResult = "";

void setup() {
  // Initialize serial communication
  // Ensure that Baud rate specified here matches that selected in SimpleDyno
  // Availailable Baud rates are:
  // 9600, 14400, 19200, 28800, 38400, 57600, 115200
  Serial.begin(9600);
  // Initialize interupts (Pin2 is interrupt 0 = RPM1, Pin3 in interrupt 1 = RPM2)
  attachInterrupt
  (0,channel1,FALLING);
  attachInterrupt(1,channel2,FALLING);

}

void loop() {
  AllResult = "";
  AllResult += micros();
  AllResult += ",";
  AllResult += TempTime1;
  AllResult += ",";
  AllResult += time1;
  AllResult += ",";
  AllResult += TempTime2;
  AllResult += ",";
  AllResult += time2;
  for (int Looper = 0; Looper < NumPortsToRead;Looper++){
    AnalogResult[Looper] = analogRead(Looper);
    AllResult += ",";
    AllResult += AnalogResult[Looper];
  }
Serial.println (AllResult);
   Serial.flush();
      delay(1);
}

//Interrupt routine for RPM1
void channel1(){
  TempTime1 = micros();
  time1 = TempTime1-Oldtime1;
  Oldtime1 = TempTime1;
}

//Interrupt routine for RPM2
void channel2(){
    TempTime2 = micros();
  time2 = TempTime2-Oldtime2;
  Oldtime2 = TempTime2;
}

How many bytes is the AllResult String once all of the data is concatenated with it, bearing in mind that NRF24 can only transmit and receive a maximum of 32 byte packets ?

About 30 so this should be no problem.

Using the String class that way can lead to memory problems. See the evils of Strings.

I suggest that you get the radios working by themselves first using the example code from Robin2's simple rf24 tutorial. Then you will have more knowledge on how they work and it will be easier to integrate into your existing code.

If you read and, closely, follow Robin2's simple rf24 tutorial you should be able to get them working. That tutorial sure helped me. Run the CheckConnection.ino (look in reply #30) to verify the physical wiring between the radio module and its processor (Arduino).

Make sure the rf24 power supply can provide enough current. This is especially true for the high power (external antenna) modules. I use homemade adapters like these. They are powered by 5V and have a 3.3V regulator on the board. Robin2 also has suggested trying with a 2 AA cell battery pack.

If using the high powered radios make sure to separate them by a few meters. They may not work too close together. Try the lower power settings.

Reset the radios by cycling power to them after uploading new code. I have found that to help. They do not reset with the Arduino.

Switch to 1MB data rate to catch the not so cloned clones.

radio.setDataRate( RF24_1MBPS );

Thank you for your reply, I already followed the tutorial but I still cant figure it out. I've already taken care of the power supply. I used to change ''Allresult''---> DataFromRC and then in the receiver Serial.print(DataFromRC). I fooled around with this a lot but never got the right data in the serial.

Post your transmit and receive codes.

Does that mean that you got some data just not what you expected, or no data at all? If you got some data post an example of what was sent and what was received.

I get data but it's completeley wrong.

This is the data I get:

This is how it needs to look:

Transmitter:

#include <nRF24L01.h>
#include <printf.h>
#include <RF24.h>
#include <RF24_config.h>

RF24 radio(7, 8); // CE, CSN

const byte address[6] = "00001";


const int NumPortsToRead = 6;
int AnalogResult[NumPortsToRead];
volatile unsigned long time1 = 0;
volatile unsigned long time2 = 0;
volatile unsigned long Oldtime1 = 0;
volatile unsigned long Oldtime2 = 0;
volatile unsigned long TempTime1 = 0;
volatile unsigned long TempTime2 = 0;
String AllResult = "";

 
int DataFromRC[11];

void setup() {


  Serial.begin(9600);
  // Initialize interupts (Pin2 is interrupt 0 = RPM1, Pin3 in interrupt 1 = RPM2)
  attachInterrupt(0, channel1, FALLING);
  attachInterrupt(1, channel2, FALLING);

  radio.begin();
  radio.openWritingPipe(address);
  radio.setPALevel(RF24_PA_MIN);
  radio.setDataRate( RF24_1MBPS ); /// this will be needed im sure with all the data we want to send
  radio.stopListening();
}


void loop() {



  for (int Looper = 0; Looper < NumPortsToRead; Looper++) {  
    DataFromRC[Looper] = analogRead(Looper);
  }

  DataFromRC[0] = analogRead(A0);
  DataFromRC[1] = analogRead(A1);
  DataFromRC[2] = analogRead(A2);
  DataFromRC[3] = analogRead(A3);
  DataFromRC[4] = analogRead(A4);
  DataFromRC[5] = analogRead(A5);
  DataFromRC[6] = micros();
  DataFromRC[7] = TempTime1;
  DataFromRC[8] = time1;
  DataFromRC[9] = TempTime2;
  DataFromRC[10] += time2;

  radio.write( &DataFromRC, sizeof(DataFromRC) );
  

}

//Interrupt routine for RPM1
void channel1() {
  TempTime1 = micros();
  time1 = TempTime1 - Oldtime1;
  Oldtime1 = TempTime1;
}

//Interrupt routine for RPM2
void channel2() {
  TempTime2 = micros();
  time2 = TempTime2 - Oldtime2;
  Oldtime2 = TempTime2;
}

Reciever:

#include <nRF24L01.h>
#include <printf.h>
#include <RF24.h>
#include <RF24_config.h>

RF24 radio(7, 8); // CE, CSN

const byte address[6] = "00001";


int DataFromRC[11];


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

void loop() {
 if (radio.available()) {
    radio.read(&DataFromRC, sizeof(DataFromRC));
    Serial.print(DataFromRC[0]);Serial.print(",");   
    Serial.print(DataFromRC[1]);Serial.print(",");
    Serial.print(DataFromRC[2]);Serial.print(",");
    Serial.print(DataFromRC[3]);Serial.print(",");
    Serial.print(DataFromRC[4]);Serial.print(",");
    Serial.print(DataFromRC[5]);Serial.print(",");
    Serial.print(DataFromRC[6]);Serial.print(",");
    Serial.print(DataFromRC[7]);Serial.print(",");
    Serial.print(DataFromRC[8]);Serial.print(",");
    Serial.print(DataFromRC[9]);Serial.print(",");
    Serial.println(DataFromRC[10]);
    
  }
    
  

}

micros() returns an 'unsigned long'. Your 'time' variables are 'unsigned long'. How do expect to fit each of those into a single element of an 'int' array?

Your transmit code is sending the analog input data first and the time data second. That does not match what the desired result is.

When you post the as is and desired data, please copy and paste the text, not screenshots.

I suggest that you use a struct to send and receive the data. Then you can send the analog input data as int data type and the time data as unsigned long.

Okay, I tried something diffent.
The problem is that I now don't get data at the reciever side...

Also could I put micros(); at the reciever side and then print it infront?

Transmitter

#include <nRF24L01.h>
#include <printf.h>
#include <RF24.h>
#include <RF24_config.h>

RF24 radio(7, 8); // CE, CSN

const byte address[6] = "00001";
  
  
  const int NumPortsToRead = 6;
  int AnalogResult[NumPortsToRead];
  volatile unsigned long TimeStamp = 0;
  volatile unsigned long time1 = 0;
  volatile unsigned long time2 = 0;
  volatile unsigned long Oldtime1 = 0;
  volatile unsigned long Oldtime2 = 0;
  volatile unsigned long TempTime1 = 0;
  volatile unsigned long TempTime2 = 0;
  String AllResult = "";

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

void setup() {
  // Initialize serial communication
  // Ensure that Baud rate specified here matches that selected in SimpleDyno
  // Availailable Baud rates are:
  // 9600, 14400, 19200, 28800, 38400, 57600, 115200
  Serial.begin(9600);
  // Initialize interupts (Pin2 is interrupt 0 = RPM1, Pin3 in interrupt 1 = RPM2)
  attachInterrupt
  (0,channel1,FALLING);
  attachInterrupt(1,channel2,FALLING);

}

void loop() {
  Array[0] = "";
  Array[1] += micros();
  Array[2] += ",";
  Array[3] += TempTime1;
  Array[4] += ",";
  Array[5] += time1;
  Array[6] += ",";
  Array[7] += TempTime2;
  Array[8] += ",";
  Array[9] += time2;
  for (int Looper = 0; Looper < NumPortsToRead;Looper++){
    AnalogResult[Looper] = analogRead(Looper);
    Array[10] += ",";
    Array[11] += AnalogResult[Looper];
  }
 radio.write(&Array, sizeof(Array));
 Serial.println("Sending");
 delay(1);
}

//Interrupt routine for RPM1
void channel1(){
  TempTime1 = micros();
  time1 = TempTime1-Oldtime1;
  Oldtime1 = TempTime1;
}

//Interrupt routine for RPM2
void channel2(){
    TempTime2 = micros();
  time2 = TempTime2-Oldtime2;
  Oldtime2 = TempTime2;
}

Reciever

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

RF24 radio(7, 8);
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[11];
    radio.read(&Array, sizeof(Array));
    Serial.print(Array[0]);

                                        
   
  }
}

You are still trying to stuff long data types into ints.

Here is tested code that shows how to use the struct structure to make up the packet. A struct is like an array, but can hold different data types. This code was successfjully tested on my setup so the CE and CSN pins will need to be changed to match your setup and I used 2 button switches to simulate you RPM inputs. Change the txIntervalMillis to suit your needs.

Transmit code:

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

const byte CE_PIN = 9;
const byte CSN_PIN = 10;

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

RF24 radio(CE_PIN, CSN_PIN); // Create a Radio

volatile unsigned long time1 = 0;
volatile unsigned long time2 = 0;
volatile unsigned long Oldtime1 = 0;
volatile unsigned long Oldtime2 = 0;
volatile unsigned long TempTime1 = 0;
volatile unsigned long TempTime2 = 0;

struct DataFromRC
{
   unsigned long TempTime1;
   unsigned long time1;
   unsigned long TempTime2;
   unsigned long time2;
   int analog[6];
};

DataFromRC data;

unsigned long txIntervalMillis = 1000;

void setup()
{
   Serial.begin(115200);
   Serial.println("Transmitter Starting");
   // buttons for test only
   pinMode(2, INPUT_PULLUP);
   pinMode(3, INPUT_PULLUP);

   attachInterrupt (0, channel1, FALLING);
   attachInterrupt(1, channel2, FALLING);

   radio.begin();
   radio.setChannel(76);  //76 library default
   //RF24_PA_MIN, RF24_PA_LOW, RF24_PA_HIGH and RF24_PA_MAX
   radio.setPALevel(RF24_PA_LOW);
   radio.setDataRate( RF24_250KBPS );
   radio.setRetries(3, 5); // delay, count
   radio.openWritingPipe(slaveAddress);
}

void loop()
{
   static unsigned long timer = 0;
   if (millis() - timer >= txIntervalMillis)
   {
      timer = millis();
      for (byte n = 0; n < sizeof(data.analog) / sizeof(data.analog[0]); n++)
      {
         data.analog[n] = analogRead(n);
      }
      data.TempTime1 = TempTime1;
      data.time1 = time1;
      data.TempTime2 = TempTime2;
      data.time2 += time2;
      printAll();
      send();
   }
}

void send()
{
   radio.write( &data, sizeof(data) );
}

void printAll()
{
   Serial.print("TempTime1 = ");
   Serial.println(data.TempTime1);
   Serial.print("time1 = ");
   Serial.println(data.time1);
   Serial.print("TempTime2 = ");
   Serial.println(data.TempTime2);
   Serial.print("time2 = ");
   Serial.println(data.time2);
   for (byte n = 0; n < sizeof(data.analog) / sizeof(data.analog[0]); n++)
   {
      Serial.print("analog channel ");
      Serial.print(n);
      Serial.print(" = ");
      Serial.println(data.analog[n]);
   }
}

//Interrupt routine for RPM1
void channel1()
{
   TempTime1 = micros();
   time1 = TempTime1 - Oldtime1;
   Oldtime1 = TempTime1;
}

//Interrupt routine for RPM2
void channel2()
{
   TempTime2 = micros();
   time2 = TempTime2 - Oldtime2;
   Oldtime2 = TempTime2;
}

Receive code:

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


const byte CE_PIN = 9;
const byte CSN_PIN = 10;

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


RF24 radio(CE_PIN, CSN_PIN); // Create a Radio

struct DataFromRC
{
   unsigned long TempTime1;
   unsigned long time1;
   unsigned long TempTime2;
   unsigned long time2;
   int analog[6];
};

DataFromRC data;

bool newData = false;

void setup()
{
   Serial.begin(115200);
   Serial.println("Receiver Starting");

   radio.begin();
   radio.setChannel(76);  //76 library default
   //RF24_PA_MIN, RF24_PA_LOW, RF24_PA_HIGH and RF24_PA_MAX
   radio.setPALevel(RF24_PA_HIGH);
   radio.setDataRate( RF24_250KBPS );
   radio.openReadingPipe(1, thisSlaveAddress);
   radio.startListening();
}

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

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

void showData()
{
   if (newData == true)
   {
      Serial.print("TempTime1 = ");
      Serial.println(data.TempTime1);
      Serial.print("time1 = ");
      Serial.println(data.time1);
      Serial.print("TempTime2 = ");
      Serial.println(data.TempTime2);
      Serial.print("time2 = ");
      Serial.println(data.time2);
      for (byte n = 0; n < sizeof(data.analog) / sizeof(data.analog[0]); n++)
      {
         Serial.print("analog channel ");
         Serial.print(n);
         Serial.print(" = ");
         Serial.println(data.analog[n]);
      }
      newData = false;
   }
}

Transmitted data:

TempTime1 = 17058084
time1 = 7331092
TempTime2 = 19589508
time2 = 63124576
analog channel 0 = 6
analog channel 1 = 1023
analog channel 2 = 356
analog channel 3 = 343
analog channel 4 = 339
analog channel 5 = 319

Received data:

TempTime1 = 17058084
time1 = 7331092
TempTime2 = 19589508
time2 = 63124576
analog channel 0 = 6
analog channel 1 = 1023
analog channel 2 = 356
analog channel 3 = 343
analog channel 4 = 339
analog channel 5 = 319

First of all I want to thank you how much you help me.

Sadly it still isn’t working. I get this in the serial:

Transmitter

Traanalog channel 3 = 282
analog channel 4 = 303
analog channel 5 = 322
 0 = 0
analog channel 1 = 170
analog channel 2 = 240
analog channel 3 = 282
analog channel 4 = 303
analog channel 5 = 322
e⸮X6<F⸮D⸮⸮.⸮,⸮N'Y,	2R&⸮]|T⸮⸮N'⸮x⸮Y3⸮i1⸮⸮N'⸮|⸮#&⸮_⸮0x⸮N'⸮|9Y#⸮_⸮1⸮/⸮N'X,	2R&⸮]|T⸮⸮N'Xl⸮#&⸮_|T⸮⸮N'⸮|⸮!&⸮_-⸮⸮⸮UH!&⸮]⸮e⸮N'X,	2R&⸮]-i⸮⸮U2B⸮<⸮]⸮xTN'⸮|9Y#⸮_|T⸮⸮'UH#&⸮]-⸮⸮N'Xl⸮#&⸮]-⸮⸮⸮U2B⸮<⸮]⸮⸮1⸮

Reciever

Receiver Starting

analog channel 4 = 344
analog channel 5 = 372
 0 = 0
analog channel 1 = 184
analog channel 2 = 265
analog channel 3 = 315
analog channel 4 = 344
analog channel 5 = 372
 0 = 0
analog channel 1 = 184
analog channel 2 = 265
analog channel 3 = 315
analog channel 4 = 344
analog channel 5 = 372
⸮⸮⸮⸮$⸮"⸮d⸮EN']$⸮DD@L⸮X⸮X\⸮R&⸮|⸮<⸮|⸮⸮⸮⸮⸮”””””⸮UU⸮Ji1⸮1xT⸮⸮N'MIDDD@⸮N'MIDD@@⸮N⸮MM⸮⸮⸮⸮⸮N']$R⸮D@@L⸮⸮⸮8m⸮<⸮	⸮DJ'Y,⸮D⸮⸮z⸮:⸮:⸮⸮md⸮(⸮8⸮(⸮⸮⸮UU⸮J⸮⸮i1xT⸮h⸮⸮}⸮=⸮}⸮=⸮}⸮⸮⸮8⸮<⸮	⸮D⸮⸮-d⸮(⸮x⸮h⸮⸮H⸮
4"(R⸮.⸮.⸮.⸮

Transmitter

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

const byte CE_PIN = 7;
const byte CSN_PIN = 8;

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

RF24 radio(7, 8); // Create a Radio



volatile unsigned long time1 = 0;
volatile unsigned long time2 = 0;
volatile unsigned long Oldtime1 = 0;
volatile unsigned long Oldtime2 = 0;
volatile unsigned long TempTime1 = 0;
volatile unsigned long TempTime2 = 0;

struct DataFromRC
{
   unsigned long TempTime1;
   unsigned long time1;
   unsigned long TempTime2;
   unsigned long time2;
   int analog[6];
};

DataFromRC data;

unsigned long txIntervalMillis = 1000;

void setup()
{
   Serial.begin(115200);
   Serial.println("Transmitter Starting");
   // buttons for test only
  // pinMode(2, INPUT_PULLUP);
  // pinMode(3, INPUT_PULLUP);

   attachInterrupt (0, channel1, FALLING);
   attachInterrupt(1, channel2, FALLING);

   radio.begin();
   radio.setChannel(76);  //76 library default
   //RF24_PA_MIN, RF24_PA_LOW, RF24_PA_HIGH and RF24_PA_MAX
   radio.setPALevel(RF24_PA_LOW);
   radio.setDataRate( RF24_250KBPS );
   radio.setRetries(3, 5); // delay, count
   radio.openWritingPipe(slaveAddress);
}

void loop()
{
   static unsigned long timer = 0;
   if (millis() - timer >= txIntervalMillis)
   {
      timer = millis();
      for (byte n = 0; n < sizeof(data.analog) / sizeof(data.analog[0]); n++)
      {
         data.analog[n] = analogRead(n);
      }
      data.TempTime1 = TempTime1;
      data.time1 = time1;
      data.TempTime2 = TempTime2;
      data.time2 += time2;
      printAll();
      send();
   }
}

void send()
{
   radio.write( &data, sizeof(data) );
}

void printAll()
{
   Serial.print("TempTime1 = ");
   Serial.println(data.TempTime1);
   Serial.print("time1 = ");
   Serial.println(data.time1);
   Serial.print("TempTime2 = ");
   Serial.println(data.TempTime2);
   Serial.print("time2 = ");
   Serial.println(data.time2);
   for (byte n = 0; n < sizeof(data.analog) / sizeof(data.analog[0]); n++)
   {
      Serial.print("analog channel ");
      Serial.print(n);
      Serial.print(" = ");
      Serial.println(data.analog[n]);
   }
}

//Interrupt routine for RPM1
void channel1()
{
   TempTime1 = micros();
   time1 = TempTime1 - Oldtime1;
   Oldtime1 = TempTime1;
}

//Interrupt routine for RPM2
void channel2()
{
   TempTime2 = micros();
   time2 = TempTime2 - Oldtime2;
   Oldtime2 = TempTime2;
}

Reciever

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


const byte CE_PIN = 7;
const byte CSN_PIN = 8;

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


RF24 radio(7, 8); // Create a Radio


struct DataFromRC
{
   unsigned long TempTime1;
   unsigned long time1;
   unsigned long TempTime2;
   unsigned long time2;
   int analog[6];
};

DataFromRC data;

bool newData = false;

void setup()
{
   Serial.begin(115200);
   Serial.println("Receiver Starting");

   radio.begin();
   radio.setChannel(76);  //76 library default
   //RF24_PA_MIN, RF24_PA_LOW, RF24_PA_HIGH and RF24_PA_MAX
   radio.setPALevel(RF24_PA_HIGH);
   radio.setDataRate( RF24_250KBPS );
   radio.openReadingPipe(1, thisSlaveAddress);
   radio.startListening();
}

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

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

void showData()
{
   if (newData == true)
   {
      Serial.print("TempTime1 = ");
      Serial.println(data.TempTime1);
      Serial.print("time1 = ");
      Serial.println(data.time1);
      Serial.print("TempTime2 = ");
      Serial.println(data.TempTime2);
      Serial.print("time2 = ");
      Serial.println(data.time2);
      for (byte n = 0; n < sizeof(data.analog) / sizeof(data.analog[0]); n++)
      {
         Serial.print("analog channel ");
         Serial.print(n);
         Serial.print(" = ");
         Serial.println(data.analog[n]);
      }
      newData = false;
   }
}

Did you fix:

Is that output from the code that I posted? I know that the code that I posted works and outputs the data as shown in my post. So there is something different about your setup or the code that you uploaded. What did you change? Post the exact code that generated the data in your reply #12.

1 Like

posted!

Code still works on my setup except that the time data is all zeros because the buttons don't work (pionModes commented).

It is not writing the time data so garbage gets put into those places, but I don't know why not. Garbage sent, garbage received. I used buttons to simulate the data by generating interrupts so there is time data.

Transmit output from my setup (only changed CE_PIN and CSN_PIN values) using your code from reply #12.

TempTime1 = 0
time1 = 0
TempTime2 = 0
time2 = 0
analog channel 0 = 0
analog channel 1 = 1022
analog channel 2 = 372
analog channel 3 = 353
analog channel 4 = 347
analog channel 5 = 327

Receive output

TempTime1 = 0
time1 = 0
TempTime2 = 0
time2 = 0
analog channel 0 = 0
analog channel 1 = 1022
analog channel 2 = 372
analog channel 3 = 353
analog channel 4 = 347
analog channel 5 = 327

I really don't get why it's not working

Need to figure out why it is not putting the 4 long time values into the struct. What is connected to pins 2 and 3?

I really don't know, I bought a PCB what is made for the original program at the top of this post.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.