Aim. To control two DC motors wirelessly from a phone using a Bluetooth module (HC-05) and an L298N driver.
Components. All items from Practical 6, plus HC-05 (or HC-06) module, 1 kΩ and 2 kΩ resistors (or three 1 kΩ resistors), an Android phone with a Bluetooth serial terminal or Bluetooth RC car app.
Concepts used. SoftwareSerial, character commands, switch statements, wireless control.
Wiring (in addition to Practical 6).
| HC-05 | Arduino |
|---|---|
| VCC | 5V |
| GND | GND |
| TXD | Pin 2 (SoftwareSerial RX) |
| RXD | Pin 3 (SoftwareSerial TX) through a 1 kΩ / 2 kΩ divider |
Pins 2 and 3 do not conflict with the motor pins 5 to 10 used in Practical 6.
Command table (to be set in the phone app).
| Character sent | Action |
|---|---|
F | Forward |
B | Reverse |
L | Turn left |
R | Turn right |
S | Stop |
0 to 9 | Set speed (0 = slow, 9 = fast) |
Program.
#include <SoftwareSerial.h>
SoftwareSerial bt(2, 3); // RX, TX
const int ENA = 5, IN1 = 7, IN2 = 8;
const int ENB = 6, IN3 = 9, IN4 = 10;
int speedValue = 200; // 0..255
void setup() {
pinMode(ENA, OUTPUT); pinMode(IN1, OUTPUT); pinMode(IN2, OUTPUT);
pinMode(ENB, OUTPUT); pinMode(IN3, OUTPUT); pinMode(IN4, OUTPUT);
Serial.begin(9600);
bt.begin(9600);
stopMotors();
}
void drive(bool leftFwd, bool rightFwd) {
digitalWrite(IN1, leftFwd ? HIGH : LOW);
digitalWrite(IN2, leftFwd ? LOW : HIGH);
digitalWrite(IN3, rightFwd ? HIGH : LOW);
digitalWrite(IN4, rightFwd ? LOW : HIGH);
analogWrite(ENA, speedValue);
analogWrite(ENB, speedValue);
}
void stopMotors() {
digitalWrite(IN1, LOW); digitalWrite(IN2, LOW);
digitalWrite(IN3, LOW); digitalWrite(IN4, LOW);
analogWrite(ENA, 0); analogWrite(ENB, 0);
}
void loop() {
if (bt.available()) {
char cmd = bt.read();
Serial.print("Received: ");
Serial.println(cmd);
switch (cmd) {
case 'F': drive(true, true); break; // forward
case 'B': drive(false, false); break; // reverse
case 'L': drive(false, true); break; // left: left wheel back, right wheel forward
case 'R': drive(true, false); break; // right
case 'S': stopMotors(); break; // stop
default:
if (cmd >= '0' && cmd <= '9') { // speed digits
speedValue = map(cmd - '0', 0, 9, 100, 255);
}
}
}
}Procedure.
- Build and test Practical 6 first.
- Add the HC-05 and divider. Upload the program (the module is on pins 2 and 3, so USB upload is not blocked).
- Pair the phone with the HC-05 (PIN 1234).
- Open the Bluetooth terminal app, connect, and send
F,S,B,S. Watch the motors and the Serial Monitor. - Send
0and9to compare speeds.
Expected result. Each letter sent from the phone produces the matching movement, and the Serial Monitor prints the received character.
Troubleshooting.
- Nothing received: swap the TXD and RXD connections (module TXD goes to the Arduino RX pin); check the baud rate (9600).
- Cannot pair: make sure the module has power; PIN is usually 1234 or 0000.
- Garbage characters: baud rate mismatch (some modules are set to 38400 or 115200).
- Motors move randomly: loose ground; line ending characters (
\r,\n) are ignored by theswitchbecause they fall in thedefaultbranch and are not digits.
Safety extension (fail-safe). Stop the motors if no command arrives for 1 second (so a lost connection does not leave a robot running):
unsigned long lastCommand = 0;
// ... inside loop(), after reading a command: lastCommand = millis();
if (millis() - lastCommand > 1000) stopMotors();Viva questions
- Why do we use SoftwareSerial?
- What does
cmd - '0'do? - Why is the voltage divider needed?
- What changes to make the left motor spin the opposite way?
Show viva answers
- To create an extra serial port so USB and Bluetooth can work at the same time.
- It converts the character
'7'to the number 7 (characters are numbers in ASCII). - To reduce the Arduino's 5 V signal to about 3.3 V for the module's RXD pin.
- Swap the two wires of that motor, or invert the logic in the program.