The gesture control robot is one of the most common type of projects made by hobbyists and students to understand and implement micro-controller knowledge in a physical and practical project. The concept behind it is simple: the orientation of the palm controls the motion of the robot car. How does it do that, you ask? Let's break it down.
To get a good understanding, we'll move by understanding the role and function of each component and then combining them to achieve the desired performance.
1. ADXL335 (Accelerometer)The function of the accelerometer is simple: to sense the orientation of the wrist. The accelerometer measures acceleration including the acceleration due to gravity 'g' as well. Thus we can use the accelerometer to sense the orientation of the wrist by measuring the component of 'g' in any particular axis of ADXL335 as shown in figure below:
Due to tilt of hand, the X and/or Y axis' angle with vertical changes and hence a component of 'g' acceleration acts upon them as well which can be measured and thus indicates the orientation of the hand.
The ADXL335 can measure up to 3g of acceleration and is interfaced with Arduino by connecting it's axis pins to Analog pins of Arduino. The accelerometer outputs voltage values proportional to acceleration.
In this project, Accelerometer is connected to Arduino Nano and is attached to the palm. The ADXL335 outputs voltage in range from 0 to Vcc (Applied voltage usually 3.3V) and is read by Arduino's Analog pins. Thus for the user, we get a value in range from 0 to 1024 (10-bit ADC). The different orientation yields a different analog value for each axis which is then mapped to different robot movements.
The circuit diagram for the Accelerometer is:
A test code to understand working of ADXL335 is as follows:
void setup()
{
pinMode(A0,INPUT); //x-axis is connected to A0
pinMode(A1,INPUT); //y-axis is connected to A1
pinMode(A2,INPUT); //z-axis is connected to A2
Serial.begin(9600); //To print data to Serial Monitor
}
void loop()
{
Serial.print(" X= ");
Serial.println(analogRead(A0));
Serial.print(" Y= ");
Serial.println(analogRead(A1));
Serial.print(" Z= ");
Serial.println(analogRead(A2));
delay(1000);
}
You can run this program to see what values you get for forward, backward, left and right tilt of your palm and wrist which will be used finally for controlling the robot.
2. RF-433 Transmitter and ReceiverThe function of RF module is simple: to transmit command data from wrist Arduino Nano to the motor controlling Arduino Uno. The RF module uses Radio waves at 433hz frequency and thus the name RF-433. They use Amplitude Modulation to send data, but not getting into much technicalities and keeping things simple, they will be used to transmit command to the robot, that is: move forward, backward, right or left. And in case of no data, stand still. They work well up to 10 meter range.
Now to understand how to implement RF module in our project, let's work on the transmitter and receiver circuits sequentially.
Transmitter CircuitThe transmitter circuit consist of two parts: the Transmitter RF and the Encoder HT12E. The Transmitter consist of one data pin, one antenna, one ground and power. It is the work of HT12E encoder to provide data to the transmitter. The encoder consists of 4 data pins whose data can be sent. We will use these 4 data pins to represent the four motions, a HIGH on these pins individually will represent one of the four motions and a LOW on all represents stand still.
The circuit diagram is as shown:
The left hand pins (A0-A7) are the address pins and define the pair which will exchange data (Transmitter and Receiver having same addresses will only share data). We will set A0-A7 as LOW (Grounded).
The Data In pins are connected to Arduino digital pins (in this project 6 to 9) and they will output the command data as:
Digital Pin Command (When HIGH)
9 Forward
10 Reverse
11 Left
12 Right
We will digitalWrite the digital pins as HIGH based upon the input from ADXL335 to perform the required motion.
Receiver CircuitThe receiver circuit is completely similar to the transmitter circuit as shown, but instead of data pins going as output from Arduino, in this case they will be read as inputs to take in the command for Arduino Uno and run the motors as required:
To simplify, you can connect the LED in series at pin 17 with a 1K resistor instead of the complex circuit as shown to indicate proper connection with transmitter.
3. MOTOR SHIELDThe motor shield is the easiest part to handle due to the availability of the Adafruit library AFMotor, link :- https://github.com/adafruit/Adafruit-Motor-Shield-library
Download and copy the library in the Arduino libraries folder to be able to include it in the program sketch.
An example of AFMotor library is as given:
#include <AFMotor.h>
AF_DCMotor motor(4);
//Attach motor wires to point Motor 4 on shield
void setup()
{
Serial.begin(9600);
// set up Serial library at 9600 bps
Serial.println("Motor test!");
// turn on motor
motor.setSpeed(200);
motor.run(RELEASE);
}
void loop()
{
uint8_t i;
Serial.print("tick");
motor.run(FORWARD);
for (i=0; i<255; i++)
{
motor.setSpeed(i);
delay(10);
}
for (i=255; i!=0; i--)
{
motor.setSpeed(i);
delay(10);
}
Serial.print("tock");
motor.run(BACKWARD);
for (i=0; i<255; i++) {
motor.setSpeed(i);
delay(10);
}
for (i=255; i!=0; i--) {
motor.setSpeed(i);
delay(10);
}
Serial.print("tech");
motor.run(RELEASE);
delay(1000);
4. Combining EverythingThe last and the final part includes combining all the above parts together to form the complete robot that follows the commands of the hand!
Since the motor shield uses almost all the digital pins, we'll use the analog pins of Arduino Uno to read the Receiver Data. The final Circuit Diagram is as given:
The motor shield handles the connections to the motors. Connect a 9V battery to the power input to the shield.
NOTE: I personally prefer connecting 2 or even 3,9V batteries in parallel to the shield power input to provide enough power to run all four motors. I have connected the four motors in a group of 2 (same sided motors are connected in parallel together and hence thus require only motor point 3 and 4 to run).
For Arduino Nano:
int x_axis = 0;
int y_axis = 0;
int forward = 9;
int backward = 10;
int right = 11;
int left = 12;
void setup()
{
pinMode(A0, INPUT); //X-Axis
pinMode(A3, OUTPUT); //Y-Axis
pinMode(forward, OUTPUT); //HIGH to move Forward
pinMode(backward, OUTPUT); //HIGH to move Backward
pinMode(right, OUTPUT); //HIGH to move Right
pinMode(left, OUTPUT); //HIGH to move Left
Serial.begin(9600);
}
void loop()
{
x_axis = analogRead(A0);
y_axis = analogRead(A3);
Serial.print(" X = ");
Serial.println(x_axis);
Serial.print(" Y = ");
Serial.println(y_axis);
if (y_axis >= 390)
{
Serial.println("Forward");
digitalWrite(forward, HIGH);
}
else
{
if (y_axis <= 310)
{
Serial.println("BACK");
digitalWrite(backward, HIGH);
}
else
{
if (x_axis >= 380)
{
Serial.println("RIGHT");
digitalWrite(right, HIGH);
}
else
{
if (x_axis <= 320)
{
Serial.println("LEFT");
digitalWrite(left, HIGH);
}
Serial.println(" ");
}
}
}
delay(200);
if (x_axis > 320 && x_axis < 380 && y_axis > 310 && y_axis < 390)
{
digitalWrite(forward, LOW);
digitalWrite(backward, LOW);
digitalWrite(right, LOW);
digitalWrite(left, LOW);
}
}
For Arduino Uno:
#include<AFMotor.h>
AF_DCMotor motor_right(3);
AF_DCMotor motor_left(4);
int forward=0;
int backward=0;
int right=0;
int left=0;
void setup()
{
pinMode(A2,INPUT);
pinMode(A3,INPUT);
pinMode(A4,INPUT);
pinMode(A5,INPUT);
Serial.begin(9600);
motor_right.setSpeed(255);
motor_left.setSpeed(255);
motor_right.run(RELEASE);
motor_left.run(RELEASE);
}
void loop()
{
forward=digitalRead(A0);
backward=digitalRead(A1);
right=digitalRead(A2);
left=digitalRead(A3);
if(forward==HIGH)
{
motor_right.run(FORWARD);
motor_left.run(FORWARD);
Serial.println("Forward");
}
if(backward==HIGH)
{
motor_right.run(BACKWARD);
motor_left.run(BACKWARD);
Serial.println("Reverse");
}
if(right==HIGH)
{
motor_right.run(FORWARD);
motor_left.run(RELEASE);
Serial.println("RIGHT");
}
if(left==HIGH)
{
motor_right.run(RELEASE);
motor_left.run(FORWARD);
Serial.println("LEFT");
}
if(left==LOW&&right==LOW&&forward==LOW&&backward==LOW)
{
motor_right.run(RELEASE);
motor_left.run(RELEASE);
}
delay(100);
}
The photos and videos are here:
Comments