In this post I will show how to construct a wireless servo motor circuit which can control 6 servo motors wirelessly on 2.4 GHz communication link.
Introduction
The project is divided into two parts: a transmitter with 6 potentiometers and a receiver circuit with 6 servo motors.
The remote has 6 potentiometers to control 6 individual servo motors independently at receiver. By rotating the potentiometer, the angle of the servo motor can be controlled.
The proposed circuit can be used where you need controlled motion, for example arm of a robot or front wheel direction control of RC car.
The heart of the circuit is NRF24L01 module which is a transceiver; it works on ISM band (Industrial, Scientific and Medical band) it is the same frequency band which your WI-FI works.
Illustration of NRF24L01 Modules:
It has 125 channels, it has maximum data rate of 2MBps and it has theoretical maximum range of 100 meters. You will need two such modules to establish a communication link.
Pin configuration:
It works on SPI communication protocol. You need to connect 7 of the 8 pins to Arduino to make this module work.
It works on 3.3 V and 5V kills the module so care must be taken while powering. Fortunately we have on board 3.3V voltage regulator on Arduino and it must be powered only from 3.3V socket of Arduino.
Now let’s move on to Transmitter circuit.
Transmitter Circuit:
The circuit consists of 6 potentiometer of 10K ohm value. The middle terminal of 6 potentiometers is connected to A0 to A5 analog input pins.
Tabulation is given beside the schematic for NRF24L01 to Arduino connection; you may refer, if you have any confusion in circuit diagram.
This circuit may be powered from USB or 9V battery via DC jack.
Please download the library file here: github.com/nRF24/
Program for Transmitter:
//----------------------Program Developed by R.Girish------------------------//
#include <nRF24L01.h>
#include <RF24.h>
#include<SPI.h>
RF24 radio(9,10);
const byte address[6] = "00001";
#define pot1 A0
#define pot2 A1
#define pot3 A2
#define pot4 A3
#define pot5 A4
#define pot6 A5
const int threshold = 20;
int potValue1 = 0;
int potValue2 = 0;
int potValue3 = 0;
int potValue4 = 0;
int potValue5 = 0;
int potValue6 = 0;
int angleValue1 = 0;
int angleValue2 = 0;
int angleValue3 = 0;
int angleValue4 = 0;
int angleValue5 = 0;
int angleValue6 = 0;
int check1 = 0;
int check2 = 0;
int check3 = 0;
int check4 = 0;
int check5 = 0;
int check6 = 0;
const char var1[32] = "Servo1";
const char var2[32] = "Servo2";
const char var3[32] = "Servo3";
const char var4[32] = "Servo4";
const char var5[32] = "Servo5";
const char var6[32] = "Servo6";
void setup()
{
Serial.begin(9600);
radio.begin();
radio.openWritingPipe(address);
radio.setChannel(100);
radio.setDataRate(RF24_250KBPS);
radio.setPALevel(RF24_PA_MAX);
radio.stopListening();
}
void loop()
{
potValue1 = analogRead(pot1);
if(potValue1 > check1 + threshold || potValue1 < check1 - threshold)
{
radio.write(&var1, sizeof(var1));
angleValue1 = map(potValue1, 0, 1023, 0, 180);
radio.write(&angleValue1, sizeof(angleValue1));
check1 = potValue1;
Serial.println("INPUT:1");
Serial.print("Angle:");
Serial.println(angleValue1);
Serial.print("Voltage Level:");
Serial.println(potValue1);
Serial.println("----------------------------------");
}
potValue2 = analogRead(pot2);
if(potValue2 > check2 + threshold || potValue2 < check2 - threshold)
{
radio.write(&var2, sizeof(var2));
angleValue2 = map(potValue2, 0, 1023, 0, 180);
radio.write(&angleValue2, sizeof(angleValue2));
check2 = potValue2;
Serial.println("INPUT:2");
Serial.print("Angle:");
Serial.println(angleValue2);
Serial.print("Voltage Level:");
Serial.println(potValue2);
Serial.println("----------------------------------");
}
potValue3 = analogRead(pot3);
if(potValue3 > check3 + threshold || potValue3 < check3 - threshold)
{
radio.write(&var3, sizeof(var3));
angleValue3 = map(potValue3, 0, 1023, 0, 180);
radio.write(&angleValue3, sizeof(angleValue3));
check3 = potValue3;
Serial.println("INPUT:3");
Serial.print("Angle:");
Serial.println(angleValue3);
Serial.print("Voltage Level:");
Serial.println(potValue3);
Serial.println("----------------------------------");
}
potValue4 = analogRead(pot4);
if(potValue4 > check4 + threshold || potValue4 < check4 - threshold)
{
radio.write(&var4, sizeof(var4));
angleValue4 = map(potValue4, 0, 1023, 0, 180);
radio.write(&angleValue4, sizeof(angleValue4));
check4 = potValue4;
Serial.println("INPUT:4");
Serial.print("Angle:");
Serial.println(angleValue4);
Serial.print("Voltage Level:");
Serial.println(potValue4);
Serial.println("----------------------------------");
}
potValue5 = analogRead(pot5);
if(potValue5 > check5 + threshold || potValue5 < check5 - threshold)
{
radio.write(&var5, sizeof(var5));
angleValue5 = map(potValue5, 0, 1023, 0, 180);
radio.write(&angleValue5, sizeof(angleValue5));
check5 = potValue5;
Serial.println("INPUT:5");
Serial.print("Angle:");
Serial.println(angleValue5);
Serial.print("Voltage Level:");
Serial.println(potValue5);
Serial.println("----------------------------------");
}
potValue6 = analogRead(pot6);
if(potValue6 > check6 + threshold || potValue6 < check6 - threshold)
{
radio.write(&var6, sizeof(var6));
angleValue6 = map(potValue6, 0, 1023, 0, 180);
radio.write(&angleValue6, sizeof(angleValue6));
check6 = potValue6;
Serial.println("INPUT:6");
Serial.print("Angle:");
Serial.println(angleValue6);
Serial.print("Voltage Level:");
Serial.println(potValue6);
Serial.println("----------------------------------");
}
}
//----------------------Program Developed by R.Girish------------------------//
That concludes the transmitter.
The Receiver:
The receiver circuit consists of 6 servo motors, one Arduino and two separate power supply.
The servo motors need higher current to operate so it must not be powered from arduino. That’s why we need two separate power source.
Please apply voltage to servo appropriately; for micro servo motors 4.8V is enough, if you want to power bulkier servo motors, apply voltage matching to the rating of servo.
Please remember that servo motor consumes some power even when there is no moment, that’s because the arm of the servo motor always fight against any change from its commented position.
Program for Receiver:
//----------------------Program Developed by R.Girish------------------------//
#include <nRF24L01.h>
#include <RF24.h>
#include<SPI.h>
#include<Servo.h>
RF24 radio(9,10);
const byte address[6] = "00001";
Servo servo1;
Servo servo2;
Servo servo3;
Servo servo4;
Servo servo5;
Servo servo6;
int angle1 = 0;
int angle2 = 0;
int angle3 = 0;
int angle4 = 0;
int angle5 = 0;
int angle6 = 0;
char input[32] = "";
const char var1[32] = "Servo1";
const char var2[32] = "Servo2";
const char var3[32] = "Servo3";
const char var4[32] = "Servo4";
const char var5[32] = "Servo5";
const char var6[32] = "Servo6";
void setup()
{
Serial.begin(9600);
servo1.attach(2);
servo2.attach(3);
servo3.attach(4);
servo4.attach(5);
servo5.attach(6);
servo6.attach(7);
radio.begin();
radio.openReadingPipe(0, address);
radio.setChannel(100);
radio.setDataRate(RF24_250KBPS);
radio.setPALevel(RF24_PA_MAX);
radio.startListening();
}
void loop()
{
delay(5);
while(!radio.available());
radio.read(&input, sizeof(input));
if((strcmp(input,var1) == 0))
{
while(!radio.available());
radio.read(&angle1, sizeof(angle1));
servo1.write(angle1);
Serial.println(input);
Serial.print("Angle:");
Serial.println(angle1);
Serial.println("--------------------------------");
}
else if((strcmp(input,var2) == 0))
{
while(!radio.available());
radio.read(&angle2, sizeof(angle2));
servo2.write(angle2);
Serial.println(input);
Serial.print("Angle:");
Serial.println(angle2);
Serial.println("--------------------------------");
}
else if((strcmp(input,var3) == 0))
{
while(!radio.available());
radio.read(&angle3, sizeof(angle3));
servo3.write(angle3);
Serial.println(input);
Serial.print("Angle:");
Serial.println(angle3);
Serial.println("--------------------------------");
}
else if((strcmp(input,var4) == 0))
{
while(!radio.available());
radio.read(&angle4, sizeof(angle4));
servo4.write(angle4);
Serial.println(input);
Serial.print("Angle:");
Serial.println(angle4);
Serial.println("--------------------------------");
}
else if((strcmp(input,var5) == 0))
{
while(!radio.available());
radio.read(&angle5, sizeof(angle5));
servo5.write(angle5);
Serial.println(input);
Serial.print("Angle:");
Serial.println(angle5);
Serial.println("--------------------------------");
}
else if((strcmp(input,var6) == 0))
{
while(!radio.available());
radio.read(&angle6, sizeof(angle6));
servo6.write(angle6);
Serial.println(input);
Serial.print("Angle:");
Serial.println(angle6);
Serial.println("--------------------------------");
}
}
//----------------------Program Developed by R.Girish------------------------//
That concludes the receiver.
How to operate this project:
• Power the both the circuit.
• Now rotate any one of the potentiometer’s knob.
• For example 3rd potentiometer, the corresponding servo at the receiver rotates.
• This applies for all servo motors and potentiometers.
Note: You can connect the transmitter to computer and open serial monitor to see the data such as the angle of the servo motor, voltage level at analog pin and which potentiometer is being currently operated.
If you have any specific question regarding this Arduino based wireless servo motor project, please express in the comment section you may receive a quick response.
Arso says
Thanks for your project ….but why the servo motor moves slowly … does not move with the potentiometer
Swagatam says
sorry I cannot troubleshoot an Arduino, because I am not an expert with Arduino
Arso says
please.. can you check my code because this section( radio.openReadingPipe(0, address))do not work with my old version arduino program …i changed to this(radio.openReadingPipe(0,0xF0F0F0F0);)but when work the servo motor moves slowly,,, does not move with the potentiometer..it have any solve?
Swagatam says
I am sorry I cannot check, however you can refer this link to Arduino.cc forums and ask them about the question, they will surely help you out with the solution
Lau says
Hi,
I have a question regarding Arduino project.
Can I replace the potentialmeter with flex sensor and add on a accelerometer?
Swagatam says
Hi, you can perhaps try it with the help of the instructions provided in the following article:
https://www.homemade-circuits.com/how-flex-resistors-work/
Wero says
Thank You
wero says
Hi
good afternoon and good day
i would like to ask about where can I download the suitable nRF24L01 transceiver library?
Swagatam says
Hi, please try the below link, and let me know if it is OK
https://www.homemade-circuits.com/rf24/
Yew Kong says
Hi, just want to check with you.
is it possible to add on 3 more servo motor?
Because my project require 8 servo motor.
Swagatam says
I’ll forward your question to Mr. GR, he will reply you soon
GR says
Hi Yew,
Yes 8 servo is possible but not with Arduino Uno. You need Arduino Mega and also nessary changes in the code.
Regards
Yew Kong says
Hi
I’m apologize for asking again since my project condition does not mention properly before.
I’m using Arduino Mega to control 8 servo motors with 8 analogue sensors independently through nRF24L01 transceiver.
Is it possible to achieve this condition with using one address?
GR says
Hi yew,
Yes it is possible.
We will try to update the code.
Regards
Naseef says
What about its range?
Naseef says
Can I use arduino nano?
Swagatam says
sorry, I am not sure about it…most probably you can use it…
Naseef says
I want to use motor in one of the channel. Can I ?
Swagatam says
yes that’s possible…
Naseef says
I am very interested in it. Will it work. Do you tested it.
vishnu says
is that this circuit will work as an quad copter
Swagatam says
servo motor cannot be used in quadcopter due to weight ratio issue, it has to be BLDC
vishnu says
please suggest me an circuit forvquad copter in low cost
Swagatam says
you can explore this page
https://www.homemade-circuits.com/?s=quadcopter
james says
This article was very helpful, but your code will never work. Servos require PWM pins and only pins 3,5,6,9,10 and 11 can be used for servos.
GR says
Hi James,
Servo motors will work on any pin, if you use “servo.h” library.
The proposed project is well tested.
Regards
GR says
Hi,
I have no experience with ATTiny85, so I can't suggest you a solution.
Regards