Hand Contrtolled Robotic Car
by polidefkislepidas116 in Circuits > Robots
55 Views, 0 Favorites, 0 Comments
Hand Contrtolled Robotic Car
This is is a hand controlled robotic car. With the command of your hand it can go in the direction you wish.
This Project is Split into three parts :
-The design and assembly of the controller(Master).
-The design and assembly of the robot (Slave).
-The esp now connection.
(i am using the terms slave and master because the connection between them was made using esp now)
Also note that this project was made on a budget so i will list the prices for you to create at home!
Supplies
The supplies are
Master:
-Two mini breadboards (you can use pcb planks i preffered breadboards) 1€
-MPU-6500 4€
-esp 32 5€
-9V battery 3€
Slave:
-Two mini breadboards 1€
-L298N H-bridge 4€ (i used one but i suggest you use two in your projects because i ran into a lot of issues)
-12V battery 6€
-esp32 5€
-4 dc motors 9€
-card board (i dont know waht value to list here it was free )
-wires (whole set) 3€
-two side glu sticks 1€
Also some other tools i would suggest are :
-soldering kit 11€
-regular glue 2€
The Master
This is the controller.
the controller has to have the following connections as shown by the photo above:
ESP // MPU
3V->VCC
GND -> GND
D21->SDA
D22->SCL
After you do the programming using the following code :
#include <WiFi.h>
#include <esp_now.h>
#include <esp_wifi.h> // Required for channel locking
#include <Wire.h>
// --- Settings ---
const int MPU_ADDR = 0x68;
uint8_t broadcastAddress[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; // Broadcast to everyone
// --- Data Structure ---
typedef struct struct_message {
int pitch;
int roll;
} struct_message;
struct_message myData;
void setup() {
Serial.begin(115200);
// 1. Initialize MPU6050 (Pins 21/22)
Wire.begin(21, 22);
Wire.beginTransmission(MPU_ADDR);
Wire.write(0x6B);
Wire.write(0);
Wire.endTransmission(true);
// 2. Set Wi-Fi Mode and LOCK CHANNEL 1
WiFi.mode(WIFI_STA);
esp_wifi_set_promiscuous(true);
esp_wifi_set_channel(1, WIFI_SECOND_CHAN_NONE); // This must be inside setup()!
esp_wifi_set_promiscuous(false);
// 3. Initialize ESP-NOW
if (esp_now_init() != ESP_OK) {
Serial.println("Error initializing ESP-NOW");
return;
}
// 4. Register Peer
esp_now_peer_info_t peerInfo = {};
memcpy(peerInfo.peer_addr, broadcastAddress, 6);
peerInfo.channel = 1;
peerInfo.encrypt = false;
esp_now_add_peer(&peerInfo);
Serial.println("Master Ready. Channel Locked to 1.");
}
void loop() {
// 5. Read MPU6500 Sensor
Wire.beginTransmission(MPU_ADDR);
Wire.write(0x3B);
Wire.endTransmission(false);
Wire.requestFrom(MPU_ADDR, 6, true);
int16_t acc_x = Wire.read()<<8 | Wire.read();
int16_t acc_y = Wire.read()<<8 | Wire.read();
int16_t acc_z = Wire.read()<<8 | Wire.read();
// 6. Calculate Tilt (Pitch)
float ay = acc_y / 16384.0;
float az = acc_z / 16384.0;
myData.pitch = (int)(atan2(ay, az) * 180.0 / PI);
myData.roll = 0;
// 7. Print to Serial Monitor
Serial.print("Master Pitch: ");
Serial.println(myData.pitch);
// 8. Send wirelessly to Slave
esp_now_send(broadcastAddress, (uint8_t *) &myData, sizeof(myData));
delay(100);
}
You connect the 9V battery to the esp with the following connections:
ESP // Battery
VN<-9v+
GND<-9v-
!!SOS!!
you have to connect the -9V to the same ground as the GND from the MPU
GND(battery)
|
|______ GND ESP32
|
|
GND(MPU)
The Slave (Robot)
This is a bit uncomfortable because of limited budget i used a cardboard instead of 3d printed parts for the base of my robot and made two holes for the wires of the motors to come out off. If you have a 3d printer i suggest you use that. Otherwise dont worry i will tell you exactly what i did.
- Cut a carboard in 27x20 cm so we can have plenty of space.
- Try to put your H bridge in the middle of the the cardboard so you can make two holes next to it for easy access to the motor wires. At this stage id suggest going with two h-bridges instead of one like i suggested in the introduction because it will draw less current from your esp 32 and you wont have any issues with the current flow during the upload phase.
- After that put your 12 V battery next to it and try sticking it with either glue or two sided glue sticks.
- Lastly use your breadboard remove the tape from the bottom and stick it on the the cardboard this is where we are going to make our connections.
Breadboard Connections:
ESP//L298N
VIN->5V
GND->GND(you make this connection only once your code has been uploaded and you have disconected the usb port from the esp 32 )
ENA->D13
IN1->D14
IN2->D27
ENB->D25
IN3->D33
IN4->D32
!!Reminder this is for 4 motors at the same time if you want to do this twice(use the L298N 2 times)
you need to make the same connections again using a new h-bridge and diffrent GPIO pins. Example IN1->D5 IN2->D19 ect. !!
After completing these connections you flip the cardboard. you now can place your motors on the four corners using two sided gluesticks. Now we make the Motor connections.
Motor connections:
Motor//H-bridge
front wheels red wires -> OUT3
front wheels black wires->OUT4
(it doesnt matter how we put the you could do the opposite if you wish)
rear wheels red wires -> OUT2
rear wheels black wires -> OUT1
BUT THE WIRES HAVE TO BE FACING EACH OTHER:
red red
black black
!! Again if you wish to do it with two modules you have to make the same connections again with a diffrent h-bridge. example rear 1 black->OUT1 of H-Bridge1 // rear2 Black -> OUT 1 of H-Bridge 2 ect. !!
Final connections are the 12 V battery with the H-Bridge
Battery//L298N
12V+ -> 12V
GND -> GND
Programming :
#include <WiFi.h>
#include <esp_now.h>
#include <esp_wifi.h> // Required for channel locking
// --- Motor Pins ---
#define M_LEFT_IN1 14
#define M_LEFT_IN2 27
#define M_RIGHT_IN1 26
#define M_RIGHT_IN2 25
// --- Enable Pins (Speed Control) ---
#define M_LEFT_ENA 13
#define M_RIGHT_ENB 32
#define LED_PIN 2
typedef struct struct_message {
int pitch;
int roll;
} struct_message;
struct_message incomingData;
void driveRobot(int p) {
// Set Enable pins HIGH to give power to motors
digitalWrite(M_LEFT_ENA, HIGH);
digitalWrite(M_RIGHT_ENB, HIGH);
if (p > 50) { // Forward
digitalWrite(M_LEFT_IN1, HIGH); digitalWrite(M_LEFT_IN2, LOW);
digitalWrite(M_RIGHT_IN1, HIGH); digitalWrite(M_RIGHT_IN2, LOW);
Serial.println("Moving: FORWARD");
} else if (p < -50) { // Backward
digitalWrite(M_LEFT_IN1, LOW); digitalWrite(M_LEFT_IN2, HIGH);
digitalWrite(M_RIGHT_IN1, LOW); digitalWrite(M_RIGHT_IN2, HIGH);
Serial.println("Moving: BACKWARD");
} else { // Stop
digitalWrite(M_LEFT_IN1, LOW); digitalWrite(M_LEFT_IN2, LOW);
digitalWrite(M_RIGHT_IN1, LOW); digitalWrite(M_RIGHT_IN2, LOW);
digitalWrite(M_LEFT_ENA, LOW); digitalWrite(M_RIGHT_ENB, LOW);
Serial.println("Status: STOPPED");
}
}
void OnDataRecv(const esp_now_recv_info_t *info, const uint8_t *data, int len) {
memcpy(&incomingData, data, sizeof(incomingData));
digitalWrite(LED_PIN, !digitalRead(LED_PIN)); // Flicker blue light
driveRobot(incomingData.pitch);
}
void setup() {
Serial.begin(115200);
pinMode(LED_PIN, OUTPUT);
pinMode(M_LEFT_IN1, OUTPUT); pinMode(M_LEFT_IN2, OUTPUT);
pinMode(M_RIGHT_IN1, OUTPUT); pinMode(M_RIGHT_IN2, OUTPUT);
pinMode(M_LEFT_ENA, OUTPUT); pinMode(M_RIGHT_ENB, OUTPUT);
WiFi.mode(WIFI_STA);
// --- LOCK CHANNEL 1 ---
esp_wifi_set_promiscuous(true);
esp_wifi_set_channel(1, WIFI_SECOND_CHAN_NONE);
esp_wifi_set_promiscuous(false);
if (esp_now_init() != ESP_OK) {
Serial.println("Error initializing ESP-NOW");
return;
}
esp_now_register_recv_cb(OnDataRecv);
Serial.println("Slave Ready. Channel Locked to 1.");
}
void loop() {}
ESP NOW
the final step is the esp now connection :
when we put both master and slave in esp now mode the slave has uploaded code that will inform you if its paired or not with the master it will do that with blinking the blue led in D2. That means that the machine is searching for a channel to connect. Once the blinking becomes stable the connection is made and you can turn your hand to make the robot move as shown by the following video.
Thats the end of the instructions.
Thank you for your time!