Wireless Servo Motor Control Using 2.4 GHz communication link

In this post we are going to construct a wireless servo motor circuit which can control 6 servo motors wirelessly on 2.4 GHz communication link.

By Girish Radhakrishnan

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.

Need Help? Please send your queries through Comments for quick replies! And please Bookmark my site :)




Comments

Hi,

I have no experience with ATTiny85, so I can't suggest you a solution.

Regards
james said…
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.
Girish Radhakrishnan said…
Hi James,

Servo motors will work on any pin, if you use "servo.h" library.
The proposed project is well tested.

Regards
vishnu said…
is that this circuit will work as an quad copter
Swag said…
servo motor cannot be used in quadcopter due to weight ratio issue, it has to be BLDC
vishnu said…
please suggest me an circuit forvquad copter in low cost
Swag said…
you can explore this page

https://homemade-circuits.com/?s=quadcopter
Naseef said…
I am very interested in it. Will it work. Do you tested it.
Naseef said…
I want to use motor in one of the channel. Can I ?
Swag said…
yes that's possible...
Naseef said…
Can I use arduino nano?
Swag said…
sorry, I am not sure about it...most probably you can use it...
Naseef said…
What about its range?
Yew Kong said…
Hi, just want to check with you.
is it possible to add on 3 more servo motor?
Because my project require 8 servo motor.
Swag said…
I'll forward your question to Mr. Girish, he will reply you soon
Girish Radhakrishnan said…
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 said…
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?
Girish Radhakrishnan said…
Hi yew,

Yes it is possible.

We will try to update the code.

Regards
wero said…
Hi
good afternoon and good day
i would like to ask about where can I download the suitable nRF24L01 transceiver library?
Swag said…
Hi, please try the below link, and let me know if it is OK

https://www.homemade-circuits.com/rf24/
Lau said…
Hi,
I have a question regarding Arduino project.
Can I replace the potentialmeter with flex sensor and add on a accelerometer?
Swag said…
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 said…
Thank You
Arso said…
Thanks for your project ....but why the servo motor moves slowly ... does not move with the potentiometer
Swag said…
sorry I cannot troubleshoot an Arduino, because I am not an expert with Arduino
Arso said…
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?
Swag said…
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

Contact me for Customized Circuits

Name

Email *

Message *


 Follow on G+  Follow on Facebook   Follow on Tweeter  Follow on G+  Follow on G+

Follow Homemade Circuits