This project aims to build a hand gesture controlled robot that can be used in hospitals, shops, hotels, homes, etc., where contact-less delivery is necessary so that social distancing is strictly followed amid the Covid-19 situation.
Overview of the ProjectThis project basically contains two circuits, a transmitter circuit and a receiver circuit. The hand gestures are converted into electrical signals by the MPU6050 accelerometer sensor, and the Arduino Nano processes the incoming signals and sends it to the RF transmitter. In the receiving end, these signals are received by the RF receiver and sent to the Arduino Uno for decoding. The Arduino Uno, on receiving the signals, actuates the motors via the motor driver.
Step 1: Transmission CircuitThe transmission circuit consists of an MPU6050 accelerometer sensor, an Arduino Nano, a 433 MHz RF transmitter and a 9V battery. The battery is used to power the Arduino while the sensor and the transmitter can be powered from the Arduino. This is because, the Arduino can accept voltages from 5V to 12V while the sensors must be powered by a 5V supply. The code for the Arduino has been provided in the later part of this project. The components are placed on a breadboard and the connections are given with respect to the diagram below.
After doing the necessary connections, it looks should look something like this. Here, I have used a power bank instead of a 9V battery.
The reception circuit consists of an Arduino Uno, a 433MHz RF receiver, an L298N H-bridge motor driver, two DC motors and four 18650 Li-ion batteries. The batteries power the motor driver, the motor driver powers the Arduino and the RF receiver is powered by the Arduino. The code for the Arduino has been provided in the later part of the project. The components are placed on a robot chassis and connections are given with respect to the below figure.
The motors along with their wheels, and the caster wheel should be attached to the bottom of the chassis. The components should be attached on the top with a tape. If it is a metal chassis as in my case, then insulate the top with a layer of insulating material like a paper. After doing the necessary connections the robot should look similar to the figure below. Here, I have used separate power supplies for the motors and the Arduino.
The MPU6050 sensor has an accelerometer and a gyroscope. For this project the accelerometer values are obtained from the sensor.
- If the value of acceleration along x axis is between 20 and 60, then the robot should move Forward.
- If the value of acceleration along x axis is between -20 and -60, then the robot should move Backward.
- If the value of acceleration along y axis is between 20 and 60, then the robot should turn Left.
- If the value of acceleration along y axis is between -20 and -60, then the robot should turn Right.
- If none of the above conditions are satisfied, then the robot should stop.
First, include the necessary libraries. Create instances namely acc and driver for the GY6050 and RH_ASK classes respectively. The 0x68 represents the I2C address of the sensor.
#include <RH_ASK.h>
#include <Wire.h>
#include <GY6050.h>
GY6050 acc(0x68);
RH_ASK driver;
char* msg="100";
Inside the setup function, first initialise the accelerometer sensor. Then begin the serial communication for displaying the values in the serial monitor with a baud rate of 9600. Then, check if the RH_ASK driver has been initialised properly.
void setup()
{
acc.initialisation();
Serial.begin(9600);
if (!driver.init())
Serial.println("init failed");
}
Inside the loop function, declare a variable called msg for sending the message to the receiver. Pass the necessary parameters to the refresh function for getting the accelerometer values for both the axes, and store them in two variables.
void loop()
{
const char *msg = "hello";
int AcX=acc.refresh('A', 'X');
int AcY=acc.refresh('A', 'Y');
delay(25);
- If the value of AcX is between 20 and 60, then print Front in the serial monitor and store the value Front in msg.
- If the value of AcX is between -20 and -60, then print Back in the serial monitor and store the value Back in msg.
- If the value of AcY is between 20 and 60, then print Left in the serial monitor and store the value Left in msg.
- If the value of AcY is between -20 and -60, then print Right in the serial monitor and store the value Right in msg.
- If none of the above conditions are satisfied then store the value Stop in msg and print Stop in the serial monitor.
if(AcX>=20 && AcX<=60)
{
Serial.println("Front");
msg="Front";
}
else if(AcX<=-20 && AcX>=-60)
{
Serial.println("Back");
msg="Back";
}
else if(AcY>=20&&AcY<60)
{
Serial.println("Left");
msg="Left";
}
else if(AcY>=-60&&AcY<-20)
{
Serial.println("Right");
msg="Right";
}
else
{
Serial.println("Stop");
msg="Stop";
}
delay(100);
Then send the message via the send function and wait for any previous message transmission to be finished.
driver.send((uint8_t *)msg, strlen(msg));
driver.waitPacketSent();
delay(200);
}
Step 5: Programming the receiverFirst, include the necassary library and create instances for the RH_ASK and String classes respectively.
#include <RH_ASK.h>
RH_ASK driver;
String str;
Inside the setup function, start the serial communication with a baud rate of 9600 and check if the RH_ASK driver has been initialised properly.
void setup()
{
Serial.begin(9600);
if (!driver.init())
Serial.println("init failed");
}
Inside the loop function, create a buffer for storing the value received from the transmitter. Then copy the value from the buffer to a string and print it in the serial monitor.
void loop()
{
uint8_t buf[RH_ASK_MAX_MESSAGE_LEN];//max size of the buffer
uint8_t buflen = sizeof(buf);
if (driver.recv(buf, &buflen)) //Receive the value and store it in a buffer
{
str=(char*)buf; //Copy the message from the buffer to a string
Serial.println(str);
}
delay(200);
The digital pins 5 and 6 are used to control the Left motor, and pins 7 and 8 are used to control the Right motor.
If the received string is Front, the robot should run forward. This is achieved by setting the first pin of both the motors HIGH and the next pin LOW.
If the received string is Back, the robot should run backward. This is achieved by setting the first pin of both the motors LOW and the next pin HIGH.
If the received string is Right, the robot should turn right. So the left motor should turn forward and the right motor should turn backwards.
If the received string is Left, the robot should turn left. So the left motor should turn backwards and the right motor should turn forward.
To stop the robot, set all the motor pins LOW.
if(str=="Front")
{
digitalWrite(5,HIGH); //5,6 Left motor
digitalWrite(6,LOW);
digitalWrite(7,HIGH); //7,8 Right motor
digitalWrite(8,LOW);
}
else if(str=="Back")
{
digitalWrite(5,LOW);
digitalWrite(6,HIGH);
digitalWrite(7,LOW);
digitalWrite(8,HIGH);
}
else if(str=="Left")
{
digitalWrite(5,LOW);
digitalWrite(6,HIGH);
digitalWrite(7,HIGH);
digitalWrite(8,LOW);
}
else if(str=="Right")
{
digitalWrite(5,HIGH);
digitalWrite(6,LOW);
digitalWrite(7,LOW);
digitalWrite(8,HIGH);
}
else
{
digitalWrite(5,LOW);
digitalWrite(6,LOW);
digitalWrite(7,LOW);
digitalWrite(8,LOW);
}
}
Step 6: TroubleshootingSometimes the motors will not run in the desired direction. First find out which motor behaves this way. Then the wires of that motor have to be interchanged and connected again. This will hopefully solve this problem.
If the received buffer contains some undesired values along with the message, then use substring fucntion to extraxt the messsage from it.
Working of the robotAfter building the robot and uploading the code to both the Arduinos, the robot works just fine. The working video of the robot has been attached here.
Due to the lockdown, I have been forced to do this project with the available components. Also, because of the same reason, I have shot this video with my mobile camera due to which the quality is poor. Sorry for the inconvenience. If you face any issues in building this project, please post it in the comments.
Comments