Learning Goals 5 min
Cluster D taught you protocols on a wire. Cluster E takes the wire away. The HC-05 is the classroom Bluetooth module — a small blue PCB that, once paired with your phone, behaves exactly like a UART link over the air. Your sketch sees characters via Serial; your phone sees characters in a terminal app. By the end of this lesson you will:
- Wire an HC-05 to a UNO using SoftwareSerial (so the hardware UART stays free for upload) plus power and a 5 V → 3.3 V level shifter for the module's RX pin.
- Pair your phone to the HC-05 (default PIN 1234) and use a Bluetooth-serial app to send characters that your sketch reads — same code patterns as L01-26.
- Build a Bluetooth-controlled LED:
1from the phone turns it on,0turns it off.
Warm-Up 10 min
Pull out the HC-05. Identify the pins (usually 6, sometimes 4):
| HC-05 pin | What it does |
|---|---|
| EN (or KEY) | Enable/AT mode toggle. Leave floating for normal use; tie HIGH at boot for AT mode (L03-24). |
| VCC | 3.6–6 V power. 5 V from the UNO works fine. |
| GND | Ground. |
| TXD | Module's TX → goes to UNO's SoftwareSerial RX (no level shifter needed; module sends 3.3 V, UNO reads it as HIGH fine). |
| RXD | Module's RX → comes from UNO's SoftwareSerial TX. 5 V is too high for HC-05's 3.3 V input — use a divider or shifter. |
| STATE (optional) | HIGH when paired, LOW when not. Useful for "connection" LEDs. |
Pre-class question
Why does the HC-05's TX → Arduino RX direction not need a level shifter, but the Arduino TX → HC-05 RX direction does?
Reveal
The HC-05 outputs 3.3 V for "HIGH". The UNO's digital pins recognise anything > ~3 V as HIGH, so 3.3 V is detected correctly. No shifter needed.
The UNO outputs 5 V for "HIGH". The HC-05's RX pin is rated for max 3.6 V — feeding 5 V into it can damage the chip. So you need to drop the 5 V signal to ~3.3 V before it hits the HC-05. The cheap fix: a resistor divider (1 kΩ + 2 kΩ). The proper fix: a logic-level shifter breakout.
New Concept · Bluetooth Classic as a wireless UART 25 min
What an HC-05 actually is
Internally: a Bluetooth Classic SoC running Bluetooth's Serial Port Profile (SPP). To your sketch it presents a UART; to your phone it presents a Bluetooth serial endpoint. The radio negotiates the pairing and the encryption; the data layer is plain bytes-in, bytes-out, both directions.
Latency: ~10 ms per byte once paired. Throughput: up to ~10 KB/s with good RSSI. Range: ~10 m indoors. Power: ~30 mA when paired, ~5 mA idle. Plenty for remote-control toys, dashboards, sensor uploads.
HC-05 vs HC-06 vs BLE — quick decoder
| Module | Mode | iOS support? | Use for |
|---|---|---|---|
| HC-05 | Bluetooth Classic (SPP), can be master or peripheral | Limited (iOS Classic apps blocked) | Phone↔Arduino (Android); Arduino↔Arduino |
| HC-06 | Bluetooth Classic (SPP), peripheral only | Limited | Cheap and simple, but can't connect outward |
| HM-10 / BLE | Bluetooth Low Energy (GATT) | Yes | Modern phones, including iOS. Lower throughput. |
| Nano 33 BLE / nRF52 | BLE (Arduino-native) | Yes | Custom BLE characteristics, the "modern" route |
The HC-05 is the cheapest and easiest for Android-based projects. For iOS, jump to L03-26 (ArduinoBLE).
Pairing flow
- Power up the HC-05 (5 V to VCC, GND to GND). The on-board red LED blinks rapidly (~5 Hz) = "not paired, advertising".
- On your Android phone: Settings → Bluetooth → Scan → see "HC-05" in the list → tap → enter PIN
1234(default) or0000(some clones). - Pairing complete. The LED's blink slows to ~once every 2 seconds = "paired".
- Open a Bluetooth-serial app (e.g. "Serial Bluetooth Terminal" for Android). Connect to HC-05. The LED stays solid = "connected".
- Type characters in the app → they appear on the HC-05's TX pin → on the Arduino's SoftwareSerial RX → in
mySerial.read().
Wiring with a resistor divider for RX protection
| HC-05 | UNO / breadboard |
|---|---|
| VCC | 5V |
| GND | GND |
| TXD | UNO D2 (SoftwareSerial RX) directly |
| RXD | UNO D3 → 1 kΩ → HC-05 RXD; HC-05 RXD → 2 kΩ → GND |
The 1 kΩ / 2 kΩ divider takes 5 V from the UNO down to 5 V × (2 / (1+2)) ≈ 3.3 V at the HC-05's RXD. Safe.
Worked Example · Bluetooth-controlled LED 25 min
Step 1 — wire it (with the resistor divider)
HC-05 VCC/GND to UNO 5V/GND. HC-05 TXD → UNO D2 (direct). UNO D3 → 1 kΩ → HC-05 RXD → 2 kΩ → GND. LED + 220 Ω resistor between UNO D6 and GND.
Step 2 — pair your phone
Power the UNO. The HC-05's red LED blinks rapidly. On your phone: Settings → Bluetooth → pair with HC-05 (PIN 1234 or 0000). Open "Serial Bluetooth Terminal" (or equivalent). Tap menu → Devices → tap HC-05. The terminal should connect and the HC-05's LED should slow / go solid.
Step 3 — the sketch
// L03-23 · Bluetooth-controlled LED via HC-05 + SoftwareSerial
#include <SoftwareSerial.h>
const int BT_RX = 2; // UNO RX <- HC-05 TXD
const int BT_TX = 3; // UNO TX -> HC-05 RXD (through 1k/2k divider)
const int LED = 6;
SoftwareSerial bt(BT_RX, BT_TX); // RX, TX
void setup() {
Serial.begin(9600);
bt.begin(9600); // HC-05 default baud
pinMode(LED, OUTPUT);
Serial.println("# Bluetooth LED ready. From phone: '1' = on, '0' = off");
}
void loop() {
if (bt.available()) {
char c = bt.read();
switch (c) {
case '1':
digitalWrite(LED, HIGH);
bt.println("LED ON");
Serial.println("# LED ON");
break;
case '0':
digitalWrite(LED, LOW);
bt.println("LED OFF");
Serial.println("# LED OFF");
break;
default:
bt.print("Unknown: ");
bt.println(c);
}
}
}Two Serials are open simultaneously: Serial (hardware, USB → laptop monitor) and bt (software, D2/D3 → HC-05 → phone). Lessons L03-15 / L03-16 enabled this.
Step 4 — upload and test
Upload the sketch. The terminal app on your phone should be connected to the HC-05. Type 1 → the LED on D6 lights up; the phone shows "LED ON". Type 0 → LED off. Type anything else → "Unknown: x" on the phone.
Step 5 — try the laptop Serial Monitor too
With the sketch running and the phone connected, open the laptop's Serial Monitor at 9600 baud. Press 1 on the phone → you see "# LED ON" on the laptop monitor AND "LED ON" on the phone. Two windows into the same sketch.
Step 6 — extend with a real action
Replace the LED with a servo from L03-01. F = forward 90°, B = backward 90°, S = stop. Now you have a Bluetooth-controlled servo — the foundation for the BLE robot car of L03-28.
#include <Servo.h>
Servo s;
void setup() {
bt.begin(9600);
s.attach(9);
s.write(90);
}
void loop() {
if (bt.available()) {
char c = bt.read();
if (c == 'F') s.write(180);
else if (c == 'B') s.write(0);
else if (c == 'S') s.write(90);
}
}Walk away from your laptop with the phone in hand. The Arduino runs on USB power (or 9 V battery); you control it from up to ~10 m away. First wireless project of the course.
Basic 5 min
Goal: Send a heartbeat from the Arduino to the phone every 2 seconds: "tick 1", "tick 2", "tick 3", ... Confirm the data flows in both directions, not just phone → Arduino.
Challenge 1 5 min
Goal: Bluetooth-controlled RGB LED. Phone sends R, G, or B to set the colour; X turns off. Use the L01-30 RGB LED wiring on PWM pins.
Challenge 2 5 min
Goal: Bidirectional sensor link. Arduino reads a TMP36 temperature every 5 seconds and sends "temp 23.4 C" to the phone. Phone can also send ? at any time to get an immediate reading. Plus set 25 to set a phone-stored alarm threshold (printed back when crossed).
Challenge 3 · Fix the silent Bluetooth LED 10 min
A classmate rebuilt the Bluetooth LED. Nothing works. Here is their wiring and their sketch.
- HC-05 VCC → 5V, HC-05 GND → GND.
- HC-05 TXD → D3.
- D2 → 2 kΩ → HC-05 RXD; HC-05 RXD → 1 kΩ → GND.
- D6 → 220 Ω → LED → GND.
#include <SoftwareSerial.h>
const int BT_RX = 2;
const int BT_TX = 3;
const int LED_PIN = 6;
SoftwareSerial bt(BT_RX, BT_TX);
void setup() {
Serial.begin(9600);
bt.begin(38400);
pinMode(LED_PIN, OUTPUT);
}
void loop() {
if (bt.available()) {
char c = bt.read();
switch (c) {
case 1:
digitalWrite(LED_PIN, HIGH);
bt.println("LED ON");
break;
case 0:
digitalWrite(LED_PIN, LOW);
bt.println("LED OFF");
break;
default:
bt.print("Unknown: ");
bt.println(c);
}
}
}There are four faults: two in the wiring and two in the code. For each one, say what it causes and give the fix. For the divider, work out the voltage the HC-05's RXD actually gets.
It works if the phone app (line ending set to none) can send 1 and 0. The LED must follow, and the phone must show LED ON or LED OFF each time.
Recap 5 min
The HC-05 is "UART, but wireless". Wire 4 pins (VCC, GND, TX, RX — with a level divider on RX), pair the phone, open a terminal app, and your sketch's SoftwareSerial reads characters that came from your phone. Default PIN 1234 (sometimes 0000); default baud 9600. iOS users need BLE instead — covered in L03-26. The full pattern shape is what you already know — read a character, switch on it, do something — just over the air instead of a USB cable. Tomorrow we learn to talk to the HC-05 itself (not just through it) using AT commands — rename it, change its PIN, change its baud.
- HC-05
- Cheap Bluetooth Classic module with SPP firmware. The classroom Bluetooth standard for Android-based projects.
- SPP (Serial Port Profile)
- A Bluetooth Classic profile that emulates a serial port over the radio link. Your sketch reads/writes bytes; the radio handles delivery.
- Pairing
- The one-time security handshake between phone and module. Establishes a shared key (using the PIN), saved for future quick connections.
- PIN
- The 4-digit number you enter during pairing. Default for HC-05: 1234. Change it for any real project; cover in L03-24.
- SoftwareSerial
- The library that gives you a second UART on any pin pair. Used to talk to the HC-05 without taking pins 0/1 (which would block USB upload).
- Level shifter / resistor divider
- A small circuit that drops a 5 V signal to 3.3 V to protect a 3.3 V chip. Resistor divider (1k + 2k) is the cheapest; dedicated breakouts (TXS0102) are cleaner.
- RSSI (Received Signal Strength Indicator)
- A measure of how strong the Bluetooth radio link is. Larger values (closer to 0) = better signal. Lower values (negative, far from 0) = weak signal.
- Bluetooth Classic vs BLE
- Classic: higher throughput, SPP, NO iOS support. BLE: lower throughput, GATT services / characteristics, full iOS support. Different radios, different APIs.
Extra Mission 5 min
Part 1 — Design a phone-controlled gadget and its command list
Your sketch is now a tiny remote-controlled device. Design one you would really use: a night light, a "do not disturb" sign, or a desk fan.
Your design must include:
- The gadget's name and its one job.
- Its command list as a table: each command, what the gadget does, and the exact reply.
- What it does on power-up, and its reply to an unknown command.
- The pairing details: the baud rate and the PIN.
- A wiring drawing, including the 1 kΩ / 2 kΩ divider.
Part 2 — Make it
Build your gadget with the HC-05 and outputs you already know: LEDs, an RGB LED or a servo. Make the sketch follow your command list exactly. Every command must send its reply.
It works if every command in your table gives the action and the exact reply you wrote down.
Bring back next class: your command list, your sketch and a phone screenshot showing commands and replies. Keep the HC-05 wired for L03-24.