Hey guys, this is a tutorial on how
to make a transmitter that we can use to control RC plane, drone and other RC
models using Arduino. Below you will find a diagram for the RC transmitter and
the receiver circuit and also the coding for each of them.
Before uploading the code, make sure
you have the NRF24 library important in your project. If you don’t have the
NRF24 library, go to Arduino IDE and go sketch > include library > manage
libraries.
On the search bar, type RF24 and
scroll down to the one it says “RF24 by TMRh20” and click on install. This
should install the necessary library to use the NRF module. Wait for the
installation to complete before uploading the code.
The schematic diagram for the Transmitter
Now let's talk a bit of
what we have in this circuit. I am using an Arduino nano (328p) to control the transmitter
as it is relatively small in size to fit the transmitter. For this project, I am
using the NRF24l01 with a power amplifier that has an external antenna for wireless communication. Note that this might not be the best way for wireless
communication as the range is often affected by interferences. However, with the
amplified version of the NRF24, you can get a decent range of around 800 m to
even 1.2 Km. It is, however, easier to use this module. You do have alternatives
such as LoRa, RF module of 433Mhz, Bluetooth
module or even wifi.
I am also using spring return joystick which is also available in Arduino pack. If you are planning to make a drone or RC plane with it, you might want to choose one which is not spring return for the throttle. If you do not have one, you can map only the upper half of the joystick for the throttle else the motor will always remain on. I have also added two digital switches which can be used to turn on or off a led or to switch from angle mode to horizontal mode for the drone. I have also added a potentiometer for analog signals. Now, this is a beginner project, it lacks more features that a commercial transmitter would have. So it can be powered from a 9 V battery and you can use the regulated voltage, 5 V or 3.3 V where needed. Note that in other posts, I have made some changes in this schematic. This one uses the 3.3 V from the Arduino to power the NRF24l01 which is the required voltage for the NRF module. However, as the 3.3 V can supply a maximum of 150mA, it would not be good to use it with the power amplified version of the Arduino. This will often create lost a connection between the transmitter and the receiver. To solve this problem, I have added a buck converter to regulate the 9 V, to 3.3 V which was able to deliver the required current to the NRF. We could also use a linear voltage regulator but it would be very inefficient for our purpose.
Receiver Schematics
For the receiver, you
connect the Arduino same as we did earlier for the transmitter, I have added 3
different types of output for you to understand how it works. The first one is
the led, which is controlled to be either on or off through the transmitter. This
is a digital output. The second thing is the servo, and the third one is a speed
control dc motor. To control the speed of a DC motor, you must switch on and of the
input of the motor at a very fast rate. The amount of time the switch is on and off
determines the average voltage. The higher the average voltage, the higher is
the speed of the motor. This is normally achieved by sending a PWM signal to the drain of MOSFETs or IGBTs, which will turn on and off the circuit at a very high
frequency.
If you want to make a drone with this transmitter and receiver, check it HERE.
If you want to make a drone with this transmitter and receiver, check it HERE.
Transmitter code
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
const uint64_t pipeOut = 0xE7E7F0F0E1LL; //Remember to keep this exactly the same for the receiver code also
RF24 radio(9, 10);
struct MyData {
byte throttle;
byte yaw;
byte pitch;
byte roll;
byte AUX1;
byte AUX2;
};
MyData data;
void resetData()
{
data.throttle = 0;
data.yaw = 127;
data.pitch = 127;
data.roll = 127;
data.AUX1 = 0;
data.AUX2 = 0;
}
void setup()
{
radio.begin();
radio.setAutoAck(false);
radio.setDataRate(RF24_250KBPS);
radio.openWritingPipe(pipeOut);
resetData();
}
int mapJoystickValues(int val, int lower, int middle, int upper, bool reverse)
{
val = constrain(val, lower, upper);
if ( val < middle )
val = map(val, lower, middle, 0, 128);
else
val = map(val, middle, upper, 128, 255);
return ( reverse ? 255 - val : val );
}
void loop()
{
data.throttle = mapJoystickValues( analogRead(A0), 13, 524, 1015, true );
data.yaw = mapJoystickValues( analogRead(A1), 1, 505, 1020, true );
data.pitch = mapJoystickValues( analogRead(A2), 12, 544, 1021, true );
data.roll = mapJoystickValues( analogRead(A3), 34, 522, 1020, true );
data.AUX1 = digitalRead(4); //The 2 toggle switches
data.AUX2 = digitalRead(5);
radio.write(&data, sizeof(MyData));
}
****************************************************************************
I’ll make some
important points in the code that you should take into consideration.
First of all is
this line: “const uint64_t pipeOut =
0xE7E7F0F0E1LL; “
This part of the
code is the address of the transmitter. It is very important to make it the
same as the receiver for it to be detected. I recommend copy and paste the exact
thing to the receiver code which you will find below.
The second thing is
this: “RF24 radio (9, 10);”
This line of code defines
the pin that we have selected from the Arduino that we are going to connect to
the NRF24L01 CE and CSN input. In the above circuit diagram, you can see I connected
the CE and CSN of the NRF to pin 9 and 10 of the Arduino respectively. So, I
define it as above.
Now this part:
int
mapJoystickValues(int val, int lower, int middle, int upper, bool reverse)
{
val =
constrain(val, lower, upper);
if ( val
< middle )
val =
map(val, lower, middle, 0, 128);
else
val =
map(val, middle, upper, 128, 255);
return (reverse
? 255 - val : val );
}
This part is a function that is telling to map the values of the joystick to the PWM signal.
You should check the values of the lower, middle and upper position of your
joystick and enter the values according to it. Use analogRead( The analog pin
your joystick is connected to), and then use Serial.println to print the values
in the serial monitor.
Here you should add
the values you got from the above test.
void loop()
{
data.throttle = mapJoystickValues( analogRead(A0), 13, 524, 1015, true );
data.yaw = mapJoystickValues( analogRead(A1), 1, 505,
1020, true );
data.pitch = mapJoystickValues( analogRead(A2), 12, 544, 1021,
true );
data.roll = mapJoystickValues( analogRead(A3), 34, 522,
1020, true );
data.AUX1 = digitalRead(4); //The 2 toggle switches
data.AUX2 = digitalRead(5);
radio.write(&data,
sizeof(MyData));
}
This will calibrate
the joystick for you.
Receiver code
#include <Servo.h>
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
const uint64_t pipeIn = 0xE7E7F0F0E1LL;
RF24 radio(9, 10); CE and CSN pin
Servo myServo;
struct MyData {
byte throttle;
byte yaw;
byte pitch;
byte roll;
byte Trim;
byte AUX1;
byte AUX2;
};
MyData data;
void resetData()
{
data.throttle = 0;
data.yaw = 127;
data.pitch = 127;
data.roll = 127;
data.Trim = 0;
data.AUX1 = 0;
data.AUX2 = 0;
}
void setup()
{
Serial.begin(9600); //Set the speed to 9600 bauds if you want.
resetData();
radio.begin();
radio.setAutoAck(false);
radio.setDataRate(RF24_250KBPS);
radio.openReadingPipe(1,pipeIn);
radio.startListening();
pinMode(2,OUTPUT);
pinMode(3,OUTPUT);
myServo.attach(4);
pinMode(5,OUTPUT);
}
/**************************************************/
unsigned long lastRecvTime = 0;
void recvData()
{
while ( radio.available() ) {
radio.read(&data, sizeof(MyData));
lastRecvTime = millis(); //here we receive the data
}
}
/**************************************************/
void loop()
{
recvData();
unsigned long now = millis();
if ( now - lastRecvTime > 1000 ) {
resetData();
}
digitalWrite(2,data.AUX1);
digitalWrite(3,data.AUX2);
int val = map(data.throttle,128,255,0,255);
int val1 = map(data.roll,0,255,0,180);
myServo.write(val1);
if(val > 0){
analogWrite(5,val);
}else{
analogWrite(5,0);
}
Serial.print("Throttle: "); Serial.print(data.throttle); Serial.print(" ");
Serial.print("Yaw: "); Serial.print(data.yaw); Serial.print(" ");
Serial.print("Pitch: "); Serial.print(data.pitch); Serial.print(" ");
Serial.print("Roll: "); Serial.print(data.roll); Serial.print(" ");
Serial.print("Trim: "); Serial.print(data.Trim); Serial.print(" ");
Serial.print("Aux1: "); Serial.print(data.AUX1); Serial.print(" ");
Serial.print("Aux2: "); Serial.print(data.AUX2); Serial.print("\n");
}
So that’s the receiver code that you can use to test if the
receiver is working. If you do not own an oscilloscope, you can open the serial
monitor and see if the receiver is getting the data sent by the transmitter.
Watch also the video for this tutorial on YouTube here:
NEXT >>
24 Comments
hello bro ,thanks for making this nice projects ,i need your help , i am trying to make a rc mud truck .. your tutorial is the best ever i found, but every thing is ,but 1st joystick only work up i need to make down ... 2nd joystick left right is OK ... can you please help me what should i do?
ReplyDeletehello there, sorry for late reply, for this you need to map half the value of the joystick to go up (532 -1023) and the other half to go down (0 - 531). Send me a mail on faheem1356@gmail.com if you need any more help
Deleteand can you make a nother video for RCcar.... servo motor for left/right , and DC motor for Forword/back??
ReplyDeletei'll try to make that in the following week :)
Deletehello pls... is the code line spacing critical
ReplyDeleteNo ...its not :D
DeleteWow 😍😍😍😍
ReplyDeleteThis comment has been removed by a blog administrator.
ReplyDeletewhat type of transistor and diode it is
ReplyDeleteits a MOSFET A2SHB and the diode is 1N5819 Schottky diode
DeleteWhat things required to be make transmitter and receiver please give me list please because i want to make
ReplyDeleteHow can I use it for my quadcopter
ReplyDeleteDear friend, i am currently working on how to use it for a quadcopter... i'll upload the video soon... stay tune 😊
DeleteHow can I use it for my quadcopter
ReplyDeleteCan we attach the camera in audino nano in gsm
ReplyDeleteHi, thanks for you project.
ReplyDeleteyou write potentiometer for analog signals !
how i can use it in transmitter code please.
thanks
Arduino: 1.8.12 (Windows 7), Board: "Arduino Uno"
ReplyDeletesketch_reciver:8:20: error: 'CE' does not name a type; did you mean 'CD'?
RF24 radio(9, 10); CE and CSN pin
^~
CD
C:\Users\user\Documents\Arduino\sketch_reciver\sketch_reciver.ino: In function 'void setup()':
sketch_reciver:50:1: error: 'myServo' was not declared in this scope
myServo.attach(4);
^~~~~~~
C:\Users\user\Documents\Arduino\sketch_reciver\sketch_reciver.ino:50:1: note: suggested alternative: 'Servo'
myServo.attach(4);
^~~~~~~
Servo
C:\Users\user\Documents\Arduino\sketch_reciver\sketch_reciver.ino: In function 'void loop()':
sketch_reciver:86:1: error: 'myServo' was not declared in this scope
myServo.write(val1);
^~~~~~~
C:\Users\user\Documents\Arduino\sketch_reciver\sketch_reciver.ino:86:1: note: suggested alternative: 'Servo'
myServo.write(val1);
^~~~~~~
Servo
Multiple libraries were found for "Servo.h"
Used: C:\Users\user\Documents\Arduino\libraries\Servo
Not used: C:\Program Files\Arduino\libraries\Servo
exit status 1
'CE' does not name a type; did you mean 'CD'?
This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.
can you mail the codes? I could not compile in Arduino. Can you help ?
ReplyDeletetopraksevil@hotmail.com
on the Receiver code RF24 radio(9, 10); CE and CSN pin
ReplyDeleteshould be RF24 radio(9, 10);
delete CE and CSN pin
he just telling you what pins you need.
ReplyDeleteDear Sir. Here is (maybe) a stupid question. I would like to know data.Trim (as described code). What's Trim? Can you explain via my email Nguyenthuy261082@gmail.com?
ReplyDeleteArduino: 1.8.14 Hourly Build 2021/01/29 11:33 (Windows 7), Board: "Arduino Uno"
ReplyDeleteTransmitter:2:10: fatal error: nRF24L01.h: No such file or directory
#include
^~~~~~~~~~~~
compilation terminated.
exit status 1
nRF24L01.h: No such file or directory
This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.
You need to include the library of NRF to your sketch, bro.
DeletePerhaps, I have the same question to other comments @FScreations - What is trim? I google that trim is a midpoint as in multiwii and betaflight. The question is: How to write it. I didn't see it in your explanation, Thanks.
Hi,
ReplyDeleteThis is a great source and I am interested in building this but the schematic is totally unreadable. Can yo help by replacing it with a clear readable schematic. Would be grateful if you could kindly do this?
Thanks
Raj Sherikar
Post a Comment