How to Build a Bluetooth Robotic Rover with Arduino

Description

This project is a Bluetooth-controlled Arduino car built with an Arduino board, a Bluetooth serial module, a motor driver, and two DC motors. The robot receives movement commands from a smartphone or computer through Bluetooth and uses them to move forward, backward, left, right, or stop. The code also uses PWM speed pins to set different speeds for the two motors, which is useful for balancing the car if one motor is stronger or faster than the other. This project is useful for learning wireless control, SoftwareSerial communication, motor driver logic, PWM speed control, and basic Arduino robotics.

Required components and Schematic:

We have gathered everything, including the complete list of required components and the wiring diagram, on our dedicated page for building the wheeled robot. There, you will find links to the components, the list of necessary materials (including the HC-SR04 sensor, which we will not be using in this project), and the 3D files for printing the robot's multipurpose chassis. How to Build a Wheeled Robot with Arduino

CODE:

bluetooth_robotic_rover.ino
// https://nemiatools.com
#include <SoftwareSerial.h> // Imports software serial library
SoftwareSerial bluetooth(9, 12); // Creates Bluetooth serial port

// Motor control pins
const int leftMotorForwardPin = 3; // Defines left forward pin
const int leftMotorBackwardPin = 2; // Defines left backward pin
const int rightMotorForwardPin = 5; // Defines right forward pin
const int rightMotorBackwardPin = 4; // Defines right backward pin
const int rightMotorSpeedPin = 6; // Defines right speed pin
const int leftMotorSpeedPin = 11; // Defines left speed pin

char command = 'S'; // Stores current Bluetooth command
unsigned long lastCommandTime = 0; // Stores last command time

void setup() {
  pinMode(rightMotorForwardPin, OUTPUT); // Sets right forward output
  pinMode(leftMotorForwardPin, OUTPUT); // Sets left forward output
  pinMode(leftMotorBackwardPin, OUTPUT); // Sets left backward output
  pinMode(rightMotorBackwardPin, OUTPUT); // Sets right backward output
  pinMode(leftMotorSpeedPin, OUTPUT); // Sets left speed output
  pinMode(rightMotorSpeedPin, OUTPUT); // Sets right speed output

  analogWrite(rightMotorSpeedPin, 110); // Sets right motor speed
  analogWrite(leftMotorSpeedPin, 97); // Sets left motor speed

  bluetooth.begin(9600); // Starts Bluetooth communication
  Serial.begin(9600); // Starts serial communication
  Serial.println("START"); // Prints startup message
}

void stopMotors() { // Stops both robot motors
  digitalWrite(rightMotorForwardPin, LOW); // Disables right forward
  digitalWrite(leftMotorForwardPin, LOW); // Disables left forward
  digitalWrite(rightMotorBackwardPin, LOW); // Disables right backward
  digitalWrite(leftMotorBackwardPin, LOW); // Disables left backward
}

void driveForward() { // Drives robot forward
  digitalWrite(leftMotorForwardPin, HIGH); // Enables left forward
  digitalWrite(rightMotorForwardPin, HIGH); // Enables right forward

  digitalWrite(leftMotorBackwardPin, LOW); // Disables left backward
  digitalWrite(rightMotorBackwardPin, LOW); // Disables right backward
}

void driveBackward() { // Drives robot backward
  digitalWrite(leftMotorBackwardPin, HIGH); // Enables left backward
  digitalWrite(rightMotorBackwardPin, HIGH); // Enables right backward

  digitalWrite(leftMotorForwardPin, LOW); // Disables left forward
  digitalWrite(rightMotorForwardPin, LOW); // Disables right forward
}

void turnRobotLeft() { // Turns robot left
  digitalWrite(leftMotorForwardPin, HIGH); // Enables left forward
  digitalWrite(rightMotorBackwardPin, HIGH); // Enables right backward

  digitalWrite(leftMotorBackwardPin, LOW); // Disables left backward
  digitalWrite(rightMotorForwardPin, LOW); // Disables right forward
}

void turnRobotRight() { // Turns robot right
  digitalWrite(leftMotorBackwardPin, HIGH); // Enables left backward
  digitalWrite(rightMotorForwardPin, HIGH); // Enables right forward

  digitalWrite(leftMotorForwardPin, LOW); // Disables left forward
  digitalWrite(rightMotorBackwardPin, LOW); // Disables right backward
}

void loop() {

  if (bluetooth.available()) { // Checks for Bluetooth data
    command = bluetooth.read(); // Reads Bluetooth command
    Serial.print(command); // Prints received command
    lastCommandTime = millis(); // Updates last command time
  }

  if(command == 'F') // Checks forward command
    driveForward(); // Drives robot forward
  else if(command == 'B') // Checks backward command
    driveBackward(); // Drives robot backward
  else if(command == 'L') // Checks left command
    turnRobotLeft(); // Turns robot left
  else if(command == 'R') // Checks right command
    turnRobotRight(); // Turns robot right
  else if(command == 'S') // Checks stop command
    stopMotors(); // Stops both motors

  if(millis() - lastCommandTime > 1000) { // Checks command timeout
    command = 'S'; // Sets stop command
  }
}

How it works:

This project controls a small robot car through Bluetooth. A Bluetooth module receives commands from an external device, such as a smartphone app, and sends them to the Arduino. The Arduino then controls the motor driver to move the car in the requested direction.

The line #include <SoftwareSerial.h> adds the SoftwareSerial library. This library allows the Arduino to create a second serial communication port using normal digital pins, instead of using only the hardware serial pins 0 and 1.

The line SoftwareSerial bluetooth(9, 12); creates a Bluetooth serial port. In this case, pin 9 is used as RX and pin 12 is used as TX. The Bluetooth module TX pin should be connected to Arduino pin 9, while the HC-05 RX pin should be connected to Arduino pin 12 through a voltage divider or a suitable 5 V-to-3.3 V level shifter, with a common ground.

The motor pins define how the Arduino controls the motor driver. The lines leftMotorForwardPin and leftMotorBackwardPin control the direction of the left motor, while rightMotorForwardPin and rightMotorBackwardPin control the direction of the right motor.

The pins rightMotorSpeedPin = 6 and leftMotorSpeedPin = 11 are used for motor speed control. These pins should be connected to the enable or PWM inputs of the motor driver. By using analogWrite(), the Arduino can control how much power is sent to each motor.

Inside setup(), all motor direction pins and speed pins are configured as outputs. This allows the Arduino to send HIGH, LOW, and PWM signals to the motor driver.

The lines analogWrite(rightMotorSpeedPin, 110); and analogWrite(leftMotorSpeedPin, 97); set the speed of the two motors. The values can go from 0 to 255, where 0 means stopped and 255 means maximum PWM output.

These speed values are very important in a real robot car because the two DC motors are often not perfectly identical. One motor may rotate faster than the other even with the same command. In this code, the right motor is set to 110 and the left motor to 97 to help balance the movement and make the car go straighter.

The user can change both the pin numbers and the speed values to adapt the project to their own wiring, motor driver, chassis, and motor behavior. If the car does not move straight, the user can slightly increase the speed of the slower motor or reduce the speed of the faster motor until the movement is balanced.

The line bluetooth.begin(9600); starts Bluetooth communication at 9600 baud. This value must match the baud rate of the Bluetooth module, such as an HC-05 or HC-06.

The function stopMotors() sets all direction pins LOW. This removes every forward and backward command from both motors, so the car stops.

The function driveForward() turns on the forward direction pins of both motors and turns off the backward direction pins. This makes the left and right motors rotate forward at the speed previously set by the PWM pins.

The function driveBackward() does the opposite. It turns on the backward direction pins and turns off the forward direction pins, so both motors rotate backward.

The functions turnRobotLeft() and turnRobotRight() rotate the motors in opposite directions. This makes the robot turn on the spot instead of simply moving in a wide curve.

Depending on how the motors are mounted and wired, the physical left and right movement may be reversed. If this happens, the user can swap the motor wires, change the pin definitions, or exchange the logic inside the turning functions.

Inside loop(), the condition if (bluetooth.available()) checks if a new Bluetooth command has arrived. If a command is available, command = bluetooth.read(); reads one character and stores it in the variable command.

The command characters define the movement. The character 'F' makes the robot move forward, 'B' makes it move backward, 'L' makes it turn left, 'R' makes it turn right, and 'S' stops the motors.

Every time a new Bluetooth command is received, the line lastCommandTime = millis(); saves the current time. The function millis() returns the number of milliseconds passed since the Arduino was powered on or reset.

The condition if(millis() - lastCommandTime > 1000) works as a safety timeout. If the Arduino does not receive any new Bluetooth command for more than one second, the code automatically sets command = 'S';, so the robot stops.

This timeout is useful because if the Bluetooth connection is lost or the controller app stops sending data, the robot will not continue moving forever with the last command.

Overall, the Bluetooth module receives movement characters, the Arduino interprets them, the motor driver powers the motors, and the PWM speed values help balance the two sides of the robot. By adjusting the pins and the speed values, the user can adapt the code to many different robot car layouts and make the movement more precise.

For real hardware, the motors should be powered through a suitable motor driver and an external power supply. The Arduino, Bluetooth module, motor driver, and motor power supply must share a common ground. If the Bluetooth module RX pin is not 5V tolerant, use a voltage divider or level shifter between Arduino TX and the module RX pin.

Demonstration Video:

This video is currently unavailable, sorry for the inconvenience.