Skip to content

MilindLate/Differential-Drive-RC-Robot-Controlled-via-ROS2-Humble-ROS2-ESP32-

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

5 Commits
ย 
ย 
ย 
ย 

Repository files navigation

๐Ÿค– Mini Bot

ROS2 Humble + ESP32 + Micro-ROS | Wireless Differential Drive Robot

ROS2 ESP32 Platform License Arduino


Control a differential-drive robot wirelessly using ROS2 Humble on a Linux PC and Micro-ROS on an ESP32 over WiFi UDP. Drive two DC motors via an L298N H-Bridge with full keyboard teleop support.


๐Ÿš€ Quick Start โ€ข ๐Ÿ“ Wiring โ€ข ๐Ÿ’ป Code Overview โ€ข ๐Ÿ”ง Troubleshooting โ€ข ๐Ÿ“– References


๐Ÿ“ Repository Structure

mini_bot_ros2_esp32/
โ”œโ”€โ”€ ๐Ÿ“‚ arduino/
โ”‚   โ”œโ”€โ”€ ๐Ÿ“‚ ESP32_L298N_MicroROS_CmdVel_WiFi/     โ† โœ… Main sketch (WiFi/UDP)
โ”‚   โ”‚   โ””โ”€โ”€ ESP32_L298N_MicroROS_CmdVel_WiFi.ino
โ”‚   โ””โ”€โ”€ ๐Ÿ“‚ microros_cmd_vel_serial/              โ† Serial/USB fallback
โ”‚       โ””โ”€โ”€ microros_cmd_vel_serial.ino
โ”œโ”€โ”€ ๐Ÿ“‚ docs/
โ”‚   โ”œโ”€โ”€ wiring_diagram.md
โ”‚   โ”œโ”€โ”€ troubleshooting.md
โ”‚   โ””โ”€โ”€ led_status.md
โ”œโ”€โ”€ ๐Ÿ“‚ scripts/
โ”‚   โ”œโ”€โ”€ setup_microros_agent.sh    โ† One-time setup script
โ”‚   โ”œโ”€โ”€ run_agent_wifi.sh
โ”‚   โ”œโ”€โ”€ run_agent_serial.sh
โ”‚   โ””โ”€โ”€ run_teleop.sh
โ””โ”€โ”€ README.md

๐Ÿ› ๏ธ Hardware Requirements

Component Specification Notes
ESP32 Dev Module Any 38-pin ESP32 Use Espressif board v2.0.2 in Arduino IDE
L298N Motor Driver Dual H-Bridge, 2A/ch 12V input; has onboard 5V regulator
DC Motors ร— 2 3Vโ€“12V with gearbox Match voltage to battery
12V Battery Li-Ion or NiMH Powers L298N & motors
USB Cable Micro-USB or USB-C Flash ESP32 via Arduino IDE
WiFi Router 2.4 GHz 802.11 b/g/n โš ๏ธ ESP32 does NOT support 5 GHz
Robot Chassis 2WD differential Any standard 2-wheel platform

๐Ÿ’ฟ Software Prerequisites

# ROS2 Humble (Ubuntu 22.04)
sudo apt install ros-humble-desktop

# Build tools
sudo apt install python3-colcon-common-extensions python3-rosdep2

# Teleop keyboard
sudo apt install ros-humble-teleop-twist-keyboard

Also required:

  • Arduino IDE 2.x
  • ESP32 board support v2.0.2 (via Arduino Boards Manager)
  • micro_ros_arduino library (via Arduino Library Manager)

๐Ÿš€ Quick Start

Step 1 โ€” Clone the Repository

git clone https://github.com/YOUR_USERNAME/mini_bot_ros2_esp32.git
cd mini_bot_ros2_esp32

Step 2 โ€” Setup Micro-ROS Agent (One-time)

chmod +x scripts/setup_microros_agent.sh
./scripts/setup_microros_agent.sh
๐Ÿ“‹ What this script does (click to expand)
# Creates ~/microros_ws workspace
mkdir -p ~/microros_ws/src
cd ~/microros_ws/src

# Clones micro-ROS-Agent (humble branch)
git clone -b humble https://github.com/micro-ROS/micro-ROS-Agent.git

# Installs dependencies & builds
cd ~/microros_ws
rosdep install --from-paths src --ignore-src -y
colcon build
source install/setup.bash

Step 3 โ€” Setup Arduino IDE

  1. Open Arduino IDE โ†’ File โ†’ Preferences
  2. Add to Additional Board Manager URLs:
    https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json
    
  3. Tools โ†’ Board โ†’ Boards Manager โ†’ search ESP32 โ†’ install ESP32 by Espressif Systems v2.0.2
  4. Sketch โ†’ Include Library โ†’ Manage Libraries โ†’ search micro_ros_arduino โ†’ install

๐Ÿ“Œ Reference: Installing ESP32 in Arduino IDE

Step 4 โ€” Flash the ESP32

Open arduino/ESP32_L298N_MicroROS_CmdVel_WiFi/ESP32_L298N_MicroROS_CmdVel_WiFi.ino and edit these 4 lines:

const char* ssid       = "YOUR_WIFI_SSID";      // Your WiFi name
const char* password   = "YOUR_WIFI_PASSWORD";  // Your WiFi password
const char* agent_ip   = "192.168.1.100";        // Your PC's IP (run: hostname -I)
const int   agent_port = 8888;                   // Keep as 8888

In Arduino IDE:

  • Tools โ†’ Board โ†’ ESP32 Dev Module
  • Tools โ†’ Port โ†’ /dev/ttyUSB0 (or /dev/ttyACM0)
  • Click Upload โ–ถ

If port is not visible: sudo usermod -aG dialout $USER (then log out and back in)

Step 5 โ€” Run Every Session

# Terminal 1 โ€” Micro-ROS Agent
./scripts/run_agent_wifi.sh

# Terminal 2 โ€” Keyboard Control
./scripts/run_teleop.sh

# Power on ESP32 โ†’ auto-connects WiFi โ†’ LED blinks 1 Hz โ†’ ready! โœ…

๐Ÿ“ Wiring & Pin Connections

ESP32 โ†’ L298N

ESP32 GPIO L298N Pin Wire Function
GPIO 5 ENA ๐Ÿ”ต Blue Right Motor Speed (PWM)
GPIO 18 IN1 ๐ŸŸข Green Right Motor Direction 1
GPIO 19 IN2 ๐ŸŸก Yellow Right Motor Direction 2
GPIO 4 ENB ๐Ÿ”ต Blue Left Motor Speed (PWM)
GPIO 16 IN3 ๐ŸŸข Green Left Motor Direction 1
GPIO 17 IN4 ๐ŸŸก Yellow Left Motor Direction 2
GND GND โšซ Black Common Ground (required!)

L298N โ†’ Motors & Power

L298N Terminal Connection
OUT1 & OUT2 Right Motor
OUT3 & OUT4 Left Motor
12V input Battery positive
GND Battery negative + ESP32 GND
5V output ESP32 5V pin (optional)

โš ๏ธ Always connect common GND between ESP32 and L298N โ€” without it, motor direction signals will not work correctly.

๐Ÿ“Œ Reference: ESP32 Pinout Reference | L298N Tutorial


๐Ÿ’ป ESP32 Code Overview

System Data Flow

[ Keyboard ]
     โ”‚
     โ–ผ
[ teleop_twist_keyboard ]
     โ”‚  /cmd_vel  (geometry_msgs/Twist)
     โ–ผ
[ micro_ros_agent ]  โ† runs on PC  (UDP port 8888)
     โ”‚
   WiFi (UDP)
     โ”‚
     โ–ผ
[ ESP32 + Micro-ROS ]
     โ”‚
     โ”œโ”€โ”€โ†’ Left Motor  (ENB / IN3 / IN4)
     โ””โ”€โ”€โ†’ Right Motor (ENA / IN1 / IN2)

Differential Drive Mixing

// /cmd_vel provides:
//   linear.x  โ†’ forward/backward  (+positive = forward)
//   angular.z โ†’ rotation          (+positive = turn left / CCW)

float left_speed  = linear_x - angular_z;
float right_speed = linear_x + angular_z;

// Both constrained to [-1.0, +1.0]
// Multiplied by SPEED_SCALE (default 0.8)
// Converted to PWM 0โ€“255 via ledcWrite()
linear.x angular.z Robot Motion
+ 0 Forward
- 0 Backward
0 + Spin Left (CCW)
0 - Spin Right (CW)
+ + Forward + Left arc
+ - Forward + Right arc
0 0 Stop

Connection State Machine (WiFi Sketch)

  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
  โ”‚  WAITING_AGENT  โ”‚ โ† LED slow blink, ping agent every 1s
  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
    ping OK โ”‚
            โ–ผ
  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
  โ”‚ AGENT_AVAILABLE โ”‚ โ† Create node, subscriber, timer, executor
  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
   success โ”‚
            โ–ผ
  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
  โ”‚ AGENT_CONNECTED โ”‚ โ† LED 1Hz blink, spin executor, drive motors
  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
  ping failโ”‚
            โ–ผ
  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
  โ”‚ AGENT_DISCONNECTED  โ”‚ โ† Stop motors, destroy entities
  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”˜
                     โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ†’ WAITING_AGENT

Key Configuration

// โ”€โ”€ WiFi โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
const char* ssid       = "YOUR_WIFI_SSID";
const char* password   = "YOUR_WIFI_PASSWORD";
const char* agent_ip   = "192.168.1.100";   // PC IP
const int   agent_port = 8888;

// โ”€โ”€ Motor Pins โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
#define ENA  5    // Right Motor PWM speed
#define IN1  18   // Right Motor Direction 1
#define IN2  19   // Right Motor Direction 2
#define ENB  4    // Left Motor PWM speed
#define IN3  16   // Left Motor Direction 1
#define IN4  17   // Left Motor Direction 2

// โ”€โ”€ Tuning โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
#define SPEED_SCALE  0.8   // Reduce if robot moves too fast (0.0โ€“1.0)
#define PWM_FREQ     5000  // 5 kHz PWM
#define PWM_RES      8     // 8-bit โ†’ 0โ€“255

๐ŸŽฎ Keyboard Controls (Teleop)

   u    i    o
   j    k    l
   m    ,    .
Key Action
i โฌ†๏ธ Forward
, โฌ‡๏ธ Backward
j โฌ…๏ธ Turn Left
l โžก๏ธ Turn Right
k โน๏ธ STOP
u / o โ†–๏ธ / โ†—๏ธ Forward diagonal
m / . โ†™๏ธ / โ†˜๏ธ Backward diagonal
q / z Increase / decrease max speed
w / x Increase / decrease linear speed only
e / c Increase / decrease angular speed only

๐Ÿ’ก LED Status Reference

LED Pattern Meaning
โšก Fast blink ร— 5 Startup โ€” GPIO initializing
๐Ÿ”ต Slow blink Connecting to WiFi...
๐ŸŸข Steady ON WiFi connected, waiting for agent
๐ŸŸข Regular blink (1 Hz) โœ… Ready โ€” connected to ROS2 agent
๐Ÿ”ด Fast continuous blink โŒ ERROR โ€” check agent & serial monitor

๐ŸŒ Network Configuration

WiFi Router:  192.168.1.1
  โ”œโ”€โ”€ PC (Ubuntu):  192.168.1.100   โ† runs micro-ros-agent on UDP :8888
  โ””โ”€โ”€ ESP32:        192.168.1.150   โ† auto-assigned via DHCP

Find Your PC's IP

hostname -I
# or: ip addr show wlan0 | grep "inet "

Firewall Rules

sudo ufw allow 8888/udp
sudo ufw status

Optional: Static IP for ESP32

Add before WiFi.begin() in the sketch:

IPAddress local_IP(192, 168, 1, 150);
IPAddress gateway(192, 168, 1, 1);
IPAddress subnet(255, 255, 255, 0);
WiFi.config(local_IP, gateway, subnet);

โœ… WiFi vs Serial

Feature WiFi (UDP) โœ… Recommended Serial (USB)
Cable required โŒ No โœ… Yes
Range 50+ meters USB length
Auto-reconnect โœ… Yes (state machine) โŒ Manual reset
Multiple robots โœ… Yes One per port
Latency ~1โ€“5 ms ~1โ€“2 ms
Best for Final use, demos Initial setup, debug

๐Ÿ”ง Troubleshooting

โŒ Garbled Serial output ( โ–ฏโ–ฏโ–ฏโ–ฏโ–ฏโ–ฏ )

Cause: Baud rate mismatch โ€” code uses 115200 but Serial Monitor is set to 9600

Fix:

  1. In Arduino IDE โ†’ Serial Monitor โ†’ change 9600 โ†’ 115200
  2. Press RESET on ESP32

This is a Serial Monitor display issue only โ€” nothing to do with WiFi or Micro-ROS.

โŒ ESP32 won't connect to WiFi
  • Double-check SSID and password (case-sensitive)
  • Make sure your router broadcasts 2.4 GHz โ€” ESP32 does not support 5 GHz
  • Add debug output:
// After Serial.begin(115200):
Serial.print("WiFi status: ");
Serial.println(WiFi.status());
// 3 = connected, 6 = wrong password, 1 = no SSID found
โŒ micro-ROS agent not receiving data
# 1. Confirm your PC's IP matches the sketch
hostname -I

# 2. Allow UDP port through firewall
sudo ufw allow 8888/udp

# 3. Run agent with maximum verbosity
ros2 run micro_ros_agent micro_ros_agent udp4 --port 8888 -v6

# 4. Verify port is open and listening
sudo netstat -tulpn | grep 8888

# 5. Both devices must be on the same network
ping <ESP32_IP_ADDRESS>
โŒ Motors not responding
  • Verify GPIO numbers in sketch match your actual wiring
  • Ensure GND is connected between ESP32 and L298N (common ground)
  • Check L298N has 12V power from battery
  • Remove ENA/ENB jumpers from L298N โ€” the code controls speed via PWM
  • Try increasing SPEED_SCALE closer to 1.0
  • Test motors independently with a simple blink-style Arduino sketch first
โŒ Connection drops frequently

Add these lines after WiFi.begin():

WiFi.setSleep(false);                    // Disable WiFi power save mode
WiFi.setTxPower(WIFI_POWER_19_5dBm);   // Maximum transmit power
โŒ colcon build fails โ€” FastDDS target conflict

Error message:

Some (but not all) targets in this export set were already defined.
Targets Defined:     eProsima_atomic
Targets not yet defined: fastrtps

Root cause: Ubuntu ships FastRTPS 2.5.x; ROS Humble needs FastDDS 2.6.x โ€” both are installed simultaneously and CMake gets confused.

Fix โ€” run in order:

# 1. Remove Ubuntu's conflicting FastRTPS packages
sudo apt remove --purge -y \
  libfastrtps-dev libfastrtps2.5 \
  libfastcdr-dev libfastcdr1

# 2. Clean leftover CMake config files
sudo rm -rf /usr/lib/x86_64-linux-gnu/cmake/fastrtps
sudo rm -rf /usr/lib/x86_64-linux-gnu/cmake/fastdds
sudo ldconfig

# 3. Reinstall correct ROS Humble DDS packages
sudo apt install --reinstall -y \
  ros-humble-fastrtps \
  ros-humble-fastcdr \
  ros-humble-rmw-fastrtps-cpp

# 4. Wipe workspace and rebuild from scratch
cd ~/microros_ws
rm -rf build install log

# 5. Source ONLY ROS Humble (NOT /usr/local/setup.bash)
source /opt/ros/humble/setup.bash

# 6. Rebuild
colcon build --symlink-install

โš ๏ธ Rule of Thumb: Never install libfastrtps-dev from Ubuntu repos when using ROS 2 Humble. Always use ros-humble-fastrtps.

โŒ /dev/ttyUSB0 not visible or permission denied
# List all serial devices
ls /dev/tty*

# Add yourself to the dialout group (one-time โ€” requires logout/login)
sudo usermod -aG dialout $USER

# Quick temporary fix (resets on reboot)
sudo chmod 666 /dev/ttyUSB0

๐Ÿ“‹ Quick Reference Card

Once everything is set up, use these commands every session:

# โ”€โ”€ Terminal 1: Start Agent โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
cd ~/microros_ws && source install/setup.bash
ros2 run micro_ros_agent micro_ros_agent udp4 --port 8888

# โ”€โ”€ Terminal 2: Keyboard Control โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
source /opt/ros/humble/setup.bash
ros2 run teleop_twist_keyboard teleop_twist_keyboard

# โ”€โ”€ Terminal 3: Verify Everything โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
ros2 node list          # โ†’ /esp32_robot_wifi
ros2 topic list         # โ†’ /cmd_vel
ros2 topic info /cmd_vel  # โ†’ Subscription count: 1

# โ”€โ”€ Manual Test Commands โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
# Move forward
ros2 topic pub --once /cmd_vel geometry_msgs/msg/Twist "{linear: {x: 0.2}}"
# Turn left
ros2 topic pub --once /cmd_vel geometry_msgs/msg/Twist "{angular: {z: 0.5}}"
# Stop
ros2 topic pub --once /cmd_vel geometry_msgs/msg/Twist "{}"

๐Ÿ“– References

Resource Link
Micro-ROS Arduino Library https://github.com/micro-ROS/micro_ros_arduino
Micro-ROS Agent https://github.com/micro-ROS/micro-ROS-Agent
ROS2 Humble Documentation https://docs.ros.org/en/humble/
ESP32 Pinout Reference https://lastminuteengineers.com/esp32-pinout-reference/
L298N + ESP32 Video Tutorial https://youtu.be/2JTMqURJTwg
Installing ESP32 in Arduino IDE https://randomnerdtutorials.com/installing-the-esp32-board-in-arduino-ide-windows-instructions/
teleop_twist_keyboard https://github.com/ros2/teleop_twist_keyboard
Micro-ROS Docs https://micro.ros.org/docs/overview/

Made with โค๏ธ for the ROS2 + ESP32 robotics community

Mini Bot v1.0 ย |ย  ROS2 Humble ย |ย  ESP32 ย |ย  Micro-ROS

About

Design and develop a differential-drive robot that can be controlled wirelessly using ROS2 Humble through the teleop_twist_keyboard package.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages