Chapter 9 · Arduino Practicals and Programming Projects

Practical 7Reading Bluetooth Signals and Controlling DC Motors (Forward and Reverse)

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-05Arduino
VCC5V
GNDGND
TXDPin 2 (SoftwareSerial RX)
RXDPin 3 (SoftwareSerial TX) through a 1 kΩ / 2 kΩ divider
Arduino UNO5VGNDPin 2 (RX)Pin 3 (TX)HC-05BluetoothVCCGNDTXDRXDTXD → Arduino RX1 kΩ2 kΩRXD ≈ 3.3 V5 × 2 ÷ (1 + 2)
Practical 7: HC-05 on pins 2 and 3 (motor wiring as Practical 6)

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 sentAction
FForward
BReverse
LTurn left
RTurn right
SStop
0 to 9Set speed (0 = slow, 9 = fast)

Program.

Arduino C/C++
#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.

  1. Build and test Practical 6 first.
  2. Add the HC-05 and divider. Upload the program (the module is on pins 2 and 3, so USB upload is not blocked).
  3. Pair the phone with the HC-05 (PIN 1234).
  4. Open the Bluetooth terminal app, connect, and send F, S, B, S. Watch the motors and the Serial Monitor.
  5. Send 0 and 9 to compare speeds.

Expected result. Each letter sent from the phone produces the matching movement, and the Serial Monitor prints the received character.

Troubleshooting.

Safety extension (fail-safe). Stop the motors if no command arrives for 1 second (so a lost connection does not leave a robot running):

Arduino C/C++
unsigned long lastCommand = 0;
// ... inside loop(), after reading a command: lastCommand = millis();
if (millis() - lastCommand > 1000) stopMotors();

Viva questions

  1. Why do we use SoftwareSerial?
  2. What does cmd - '0' do?
  3. Why is the voltage divider needed?
  4. What changes to make the left motor spin the opposite way?
Show viva answers
  1. To create an extra serial port so USB and Bluetooth can work at the same time.
  2. It converts the character '7' to the number 7 (characters are numbers in ASCII).
  3. To reduce the Arduino's 5 V signal to about 3.3 V for the module's RXD pin.
  4. Swap the two wires of that motor, or invert the logic in the program.