Beginning of this year I bought my first nRF24L01 wireless modules. I did not have a clue back then how they worked and if I was going to get them to work with Arduino. I had found a couple of libraries for the modules so I thought of giving it a try. I spent hours trying to make them work, it took me hours to sent a simple integer from one Arduino to the other. Some time ago I have made my own remote control using a nRF24L01 module. I’ve written sketches for it so it can remote control my hexapod or my Rover 5. My Rover 5 has become my development platform. I’ve used it try out lots of different sensors. I’ve played with the encoders, tried out several libraries for the ultrasonic sensor.
When you have an Arduino on your desk you can use the serial monitor to see what is going on. But with a robot that is driving around that becomes a bit more difficult. My remote control has a 4×20 characters LCD, it is very handy to display the readings of the various sensors on the robot and display them on the LCD in my remote control.
In the beginning I just used an array of integers to sent over the wireless link. I recently wanted to sent an array of integers and an array of floats. Since you can not put different types in one array (?) I needed a different solution. I know very little about C++ so I started searching for a solution, the answer to my problem was a typedef struct. So I made the following sketches to try it out. I’ve also borrowed a couple of lines of code from the example sketches that come with the RF24 library. One Arduino has a bool “timout”, when it is true it will light a led. So you know when there is something wrong with the communication. It’s pretty handy with a robot, I shut down the motors on my robots if the link is lost.
Here are the sketches:
Arduino 1
// http://www.bajdi.com // Sending a struct with the nRF24L01 module // Data to be sent is the reading of 2 analog pins // Data received is the analog reading of 2 pins on the other Arduino #include <SPI.h> #include "nRF24L01.h" #include "RF24.h" RF24 radio(1,2); // make sure this corresponds to the pins you are using const uint64_t pipes[2] = { 0xF0F0F0F0E1LL, 0xF0F0F0F0D2LL }; const int led = 0; typedef struct{ int A; int B; float C; float D; } A_t; typedef struct{ int W; int X; float Y; float Z; } B_t; A_t duino1; B_t duino2; void setup() { Serial.begin(57600); pinMode(led, OUTPUT); radio.begin(); radio.openWritingPipe(pipes[0]); radio.openReadingPipe(1,pipes[1]); } void loop(void) { // we need data to sent... duino2.W = analogRead(A0); duino2.X = analogRead(A1); duino2.Y = analogRead(A0)/102.3; duino2.Z = analogRead(A1)/102.3; // end of analog reading // radio stuff radio.stopListening(); bool ok = radio.write( &duino2, sizeof(duino2) ); radio.startListening(); unsigned long started_waiting_at = millis(); bool timeout = false; while ( ! radio.available() && ! timeout ) if (millis() - started_waiting_at > 250 ) timeout = true; if ( timeout ) { Serial.println("Failed, response timed out."); digitalWrite(led, HIGH); } else { radio.read( &duino1, sizeof(duino1) ); digitalWrite(led, LOW); } // end of radio stuff // serial print received data Serial.print("duino1.A = "); Serial.println(duino1.A); Serial.print("duino1.B = "); Serial.println(duino1.B); Serial.print("duino1.C = "); Serial.println(duino1.C); Serial.print("duino1.D = "); Serial.println(duino1.D); // end of serial printing }
Arduino 2
// http://www.bajdi.com // Sending a struct with the nRF24L01 module // Data to be sent is the reading of 2 analog pins // Data received is the analog reading of 2 pins on the other Arduino #include <SPI.h> #include "nRF24L01.h" #include "RF24.h" typedef struct{ int A; int B; float C; float D; } A_t; typedef struct{ int W; int X; float Y; float Z; } B_t; A_t duino1; B_t duino2; RF24 radio(8,9); // make sure this corresponds to the pins you are using const uint64_t pipes[2] = { 0xF0F0F0F0E1LL, 0xF0F0F0F0D2LL }; void setup() { Serial.begin(57600); radio.begin(); radio.openWritingPipe(pipes[1]); radio.openReadingPipe(1,pipes[0]); radio.startListening(); } void loop(void) { // we need data to sent... duino1.A = analogRead(A0); duino1.B = analogRead(A1); duino1.C = analogRead(A0)/102.3; duino1.D = analogRead(A1)/102.3; // end of analog reading // radio stuff if ( radio.available() ) { bool done = false; while (!done) { done = radio.read( &duino2, sizeof(duino2) ); } radio.stopListening(); radio.write( &duino1, sizeof(duino1) ); radio.startListening(); } // end of radio stuff // serial print received data Serial.print("duino2.W = "); Serial.println(duino2.W); Serial.print("duino2.X = "); Serial.println(duino2.X); Serial.print("duino2.Y = "); Serial.println(duino2.Y); Serial.print("duino2.Z = "); Serial.println(duino2.Z); // end of serial printing }
Hello!
What if you would like to send the analog values from potentiometer to another arduino? Do you have to do it using float? I’m struggling to send the values and provide it to the servo.
Thanks!
Hello,
thanks for the idea. I’m trying to make this work between Arduino and Raspberry Pi (with RF24 ported). The data send from Arduino to Raspberry gets through ok, but vice versa I have some issues with the struct contruct. It seems like some of the struct data gets mixed up.
Anyway, I came back to this post to see if I didn’t miss anything important. Rereading the source, I don’t understand, why you created two structs – the A_t and the B_t. Wouldn’t just one type be enough? Then of course make two variables duino1 and duino2, but both of the same one type?
Yes that should work. Which fork of the library are you using? I’ll try to do some Arduino – RPi wireless communication in the future 🙂
@Vaclav, remember that representation of some variable types like float can be represented differently in memory on arduino and raspberry pi so it’s better to send them like integers (multiple by 100 for example)
Many thank’s for the example… after many days of research and test with different sketch found on other page without results I found yours…..
Now I’m able to send wireless from one arduino to the other data like temperature, pressure, UV etc.
Ciao
Hi.
I’m also working on getting my RPi Setup to recieve data structs, sending them from my arduino setup is easy thanks to this blog.
Can anyone help with getting the RPi code working using https://github.com/stanleyseow/RF24 Fork?
Thanks
Ddea
Hi, i have a question about nrf24l01. So, i want to sending measured gas ratio,temp.,humidity,day,month,..,clock information. And i tried some library but i didn’t get result yet. How to edit your code for my request ? Can you help me for this ?
Thanks. Success in your works.
Greetings from Turkey.
You can sent a maximum of 32 bytes at once. Post your code on the Arduino forums if you have trouble.
thank you sooooooo much.
Hi
i have been using structs and send data between arduinos.
But are struggling a bit related to sending 2 different structs from one Ardu to another.
I have never got any think through yet, during my attempts with sending 2 different structs.
Presumably it can be done with sending this struct by pipeA and that struct by pipeB and receiving mode by PipeC. The other Ardu will have RX pipeA and RX pipeB and TX pipeC.
This below i have not tried, but it must be possible as well.
Or actually just using one struct, with float and ints and bytes and so on, and having one byte for packet allocation. so when the RX are getting the message it check the allocation byte and than copy the package to a specific data map, and if its different allocation number it copies to another data map. So than Dates, temperature, and whatever you are sending will be copied to the correct variables.
[…] sending a payload containing a structure of data (A guide on how to implement this can be found here). In this structure I have the “transmission pathway” which is the relay node addresses […]
Problem with power down.
If VCC of radio or goes down and rises back again the program loop can’t find radio again. Same problem is when distance of devices grows too long.
How to reset Arduinos in those cases or how to get radio contact again?
[…] How to send dataobjects over the air and this […]
hi sir, i have to control the robot car project. Where the rear wheels in the form of a dc motor is controlled with flex sensors and front wheels in the form of a servo motor controlled by the accelerometer sensor. Robot controller with a car connected with nrf24l01. if one of the sensors to control I can. but if it combines both to control I can not. Both sensors transmit data simultaneously . dc motors and servo motors confused receive data so that its movement is chaotic. How should I fix this? can you help me.? Can I send my program to you and you see.? Please.
I’m sorry but I’m new to nRF24 modules and I love how simple the code is arranged, but I would like to see a diagram of how the wires are connected… Of course I don’t need VCC and GND, but the rest would be nice to have.
Here are the connection details for Arduino and Raspberry Pi.
Arduino
Arduino Pin 11 to RF Module Pin 6 ( MOSI)
Arduino Pin 12 to RF Module Pin 7 ( MISO )
Arduino Pin 13 to RF Module Pin 5 ( SCK )
Arduino Pin 7 to RF Module Pin 4 ( CSN )
Arduino Pin 8 to RF Module Pin 3 ( CE )*** RF Module can only take 3.3V
Arduino GND to RF Module Pin 1 ( GND )
RF Module Pin 8 (IRQ) is not connected
Raspberry Pi
RPi GPIO9 (Pin 21) to RF Module Pin 7 ( MISO )
RPi GPIO10 (Pin 19) to RF Module Pin 6 ( MOSI )
RPi GPIO 11 (Pin 23) to RF Module Pin 5 ( SCK )
RPi GPIO8 (Pin 24) to RF Module Pin 3 ( CE )
RPi GPIO 25 (Pin 22) to RF Module Pin 4 ( CSN )
RPI 3.3V (Pin 17) to RF Module Pin 2 ( VCC/3.3V )
RPi Gnd (Pin 25) to RF Module Pin 1 (GND)