Learning Goals 5 min
Yesterday you talked through the HC-05 (your phone's data passed through to the Arduino). Today you talk to the HC-05 itself — to give it a custom name, a custom PIN, and change its data-mode baud rate. The conversation language is called AT commands, a 1960s text protocol that's still standard for every modem-class radio, including modern 4G/5G modules. By the end of this lesson you will:
- Boot the HC-05 into AT mode using the EN/KEY pin and the on-board button.
- Send the four most useful AT commands —
AT,AT+NAME,AT+PSWD,AT+UART— and read back "OK" / "ERROR" responses. - Rename your module to something distinctive (e.g.
HC-05-AISYAH) and set a non-default PIN so your classmates can't accidentally pair to it.
Warm-Up 10 min
Use yesterday's wiring. The HC-05 is connected to D2/D3 via SoftwareSerial, plus 5 V and GND. Today we add one wire: the EN (or KEY) pin, which we'll briefly tie HIGH at boot to enter AT mode.
Why HC-05 has two modes
| Mode | How to enter | What it does | Baud rate |
|---|---|---|---|
| Data mode (normal) | Boot with EN floating or LOW | Passes bytes between phone and Arduino over the air | 9600 by default; changeable via AT |
| AT mode (config) | Boot with EN HIGH, or press the on-board button while powering up | Listens for AT commands and replies on the UART | Always 38400 (cannot be changed) |
Critical detail: AT mode always uses 38400 baud, regardless of what you've set the data-mode baud to. So in your sketch you'll need bt.begin(38400) in AT mode, and bt.begin(9600) (or your custom baud) for normal use. Easy to forget; classic gotcha.
The boot button trick (modules without an EN pin)
Some cheap clones don't have an EN pin broken out. They do have a small tactile push-button on the PCB. Hold the button while applying power, then release — the module starts in AT mode. The on-board LED blinks slowly (~once every 2 seconds) in AT mode, vs rapidly in data mode.
New Concept · The AT command language 25 min
Format
Every command starts with the literal text AT. Most commands need a + and a keyword. Replies are OK on success or ERROR on failure. Both lines end with \r\n (carriage return + newline). The Arduino Serial Monitor needs "Both NL & CR" in its line-ending dropdown.
| Command | What it does | Example reply |
|---|---|---|
AT | Check if the module is in AT mode and listening | OK |
AT+VERSION? | Show firmware version | +VERSION:3.0-20170601 OK |
AT+NAME? | Show current name | +NAME:HC-05 OK |
AT+NAME=Aisyah-Bot | Set the name | OK |
AT+PSWD? | Show current PIN | +PSWD:1234 OK (or similar) |
AT+PSWD=4567 | Set the PIN (you'll re-pair after) | OK |
AT+UART? | Show baud + stop + parity | +UART:9600,0,0 OK |
AT+UART=57600,0,0 | Change data-mode baud to 57600 | OK |
AT+ADDR? | Show MAC address | +ADDR:11:22:33:44:55:66 OK |
AT+ROLE? | Master (1) or slave (0) | +ROLE:0 OK |
AT+ORGL | Factory reset (warning!) | OK |
The most common gotchas
- Wrong baud. AT mode is ALWAYS 38400. If you typed
ATand saw nothing, your Serial Monitor is on the wrong baud. - Wrong line endings. The Serial Monitor needs to send
\r\n. Pick "Both NL & CR" in the dropdown. Default is usually "No line ending" — and then the HC-05 ignores you. - Spaces in the name don't work on some firmwares. Use hyphens or underscores.
- PIN length matters. Older firmware wants exactly 4 digits; newer ones accept longer strings as a passkey.
The bridge sketch
The easiest way to send AT commands is via a small "pass-through" sketch: characters from the laptop's USB Serial Monitor go straight to the HC-05, and vice versa. The Arduino acts as a dumb pipe.
#include <SoftwareSerial.h>
const int BT_RX = 2;
const int BT_TX = 3;
SoftwareSerial bt(BT_RX, BT_TX);
void setup() {
Serial.begin(9600); // USB monitor baud
bt.begin(38400); // AT-mode baud
Serial.println("# AT bridge ready. Monitor: 9600 baud; module: 38400.");
Serial.println("# Set line ending to 'Both NL & CR'. Try: AT");
}
void loop() {
// Anything I type goes to the HC-05
while (Serial.available()) {
char c = Serial.read();
bt.write(c);
}
// Anything the HC-05 replies goes to my screen
while (bt.available()) {
char c = bt.read();
Serial.write(c);
}
}Upload, open the Serial Monitor at 9600 (the USB side), set line ending to "Both NL & CR", type AT + Enter. If the HC-05 is in AT mode you see OK.
Worked Example · Rename, repin, rebaud 25 min
Step 1 — wire EN to a GPIO pin (optional)
If your HC-05 has an EN/KEY pin broken out, wire it to a free Arduino pin (e.g. D9). We'll drive it HIGH from the sketch right before powering up the module's AT mode. If your module only has the button, skip this and use the button method.
Step 2 — enter AT mode
Two paths:
- EN pin path: wire EN to VCC, then power on the HC-05 (e.g. plug in the UNO). The module boots in AT mode (LED blinks slowly).
- Button path: hold the on-board button while powering on the module, release after ~1 second. LED blinks slowly = AT mode.
Step 3 — upload the bridge sketch from §3
Open Serial Monitor: 9600 baud, "Both NL & CR".
Step 4 — first command
Type AT + Enter. You should see OK. If not, re-check baud and line ending.
Step 5 — rename your module
Type:
AT+NAME=Aisyah-Bot
Response: OK. Verify with AT+NAME? — you should see +NAME:Aisyah-Bot.
On your phone's Bluetooth settings, unpair the old "HC-05" entry. Re-scan; you'll now see "Aisyah-Bot" instead. Much easier to tell whose robot is which in a classroom of 20 students.
Step 6 — set a custom PIN
AT+PSWD=4567
Response: OK. Some newer firmwares use AT+PIN=4567 instead — try the other if the first fails. Verify with AT+PSWD?.
Re-pair from your phone, entering 4567 instead of 1234. Now classmates' phones can't hijack your module.
Step 7 — change the data-mode baud (optional)
If you want faster than 9600 in normal operation:
AT+UART=57600,0,0
Response: OK. The three numbers are baud, stop bits (0 = 1 stop), parity (0 = none).
Switch back to data mode: turn off EN (or release the button on next power cycle), re-power. The module is now at 57600 baud for phone communication. Update your sketch's bt.begin(57600).
Step 8 — verify a clean handoff
- Exit AT mode (disconnect EN or power-cycle without holding the button).
- Re-upload yesterday's LED sketch, but with
bt.begin(57600)(or whatever you set). - Re-pair the phone (using the new name + new PIN).
- Connect from the phone's Bluetooth terminal app at 57600 baud.
- Type
1→ LED on;0→ LED off, just like yesterday — but at 6× the throughput.
Try It Yourself 15 min
Goal: Query and write down: your HC-05's firmware version, its MAC address, and its role. Use AT+VERSION?, AT+ADDR?, AT+ROLE?.
Hint
Just type each command into the bridge sketch's monitor. Save the answers — the MAC address uniquely identifies this physical module, useful if you forget which one is yours.
Goal: Write a small Arduino-side sketch that, on boot, sends a sequence of AT commands automatically and prints the responses to USB. So you can re-init a module without typing each command by hand.
Hint
void setup() {
Serial.begin(9600);
bt.begin(38400);
delay(500);
sendAT("AT");
sendAT("AT+NAME=Aisyah-Bot");
sendAT("AT+PSWD=4567");
sendAT("AT+UART=57600,0,0");
}
void sendAT(const char* cmd) {
Serial.print(">> "); Serial.println(cmd);
bt.print(cmd); bt.print("\r\n");
delay(500);
while (bt.available()) Serial.write(bt.read());
Serial.println();
}This is a one-time "factory programming" script — power the module in AT mode, run this sketch, then move on. Same pattern that real factories use to configure modules at production scale.
Goal: Two HC-05s, one configured as master (AT+ROLE=1), one as slave (default 0). The master can pair with the slave automatically without a phone in the loop. This is "Arduino-to-Arduino over Bluetooth".
Hint
On the master: AT+ROLE=1, then AT+CMODE=0 (only connect to specific MAC), then AT+BIND=<slave-MAC-from-step-1>, then AT+INIT, then power-cycle. On boot in data mode, the master auto-connects to the bound slave. From there, both sides see a UART link.
This setup is rarely worth doing in a classroom (you only have one phone, and pairing manually is fine for school projects), but it's the way to build wireless robot-to-robot communication. Skip if your time is tight.
Mini-Challenge · Personalise your module 10 min
- Pick a unique name that includes your initials or first name (e.g.
HC05-AL,Aliya-Bot). - Pick a 4-digit PIN that isn't 1234 / 0000 / your birth year (anyone in class can guess those).
- Run the configuration. Verify by re-scanning from your phone.
- Write the name + PIN + MAC + current baud in your notebook's "hardware register". Future-you will thank you next month when you can't remember which module is yours.
If you finish early, also write the "recovery" steps in case future-you forgets the PIN:
- Boot in AT mode (EN HIGH or button held).
- Bridge sketch at 38400.
- Send
AT+ORGLto factory-reset. - Re-configure from scratch.
Recap 5 min
AT commands are how you configure the HC-05 itself, not just send data through it. AT mode is entered by booting with EN HIGH or holding the on-board button. AT mode always uses 38400 baud regardless of the data-mode baud. Commands are AT... + CR+LF; responses are OK or ERROR. The four most useful: AT (alive check), AT+NAME= (rename), AT+PSWD= (change PIN), AT+UART= (set baud). Personalise your module so it's identifiable; non-default PIN stops accidents in shared classrooms. Cluster E continues — next we'll use this configured module to build real phone-controlled commands, then a robot.
- AT command
- A text-based command sent to a modem-class radio. Originates with the 1960s Hayes modem standard; still the language of GSM modems, BLE modules and many WiFi modules.
- AT mode
- The HC-05's configuration mode. UART baud is locked to 38400. Module listens for AT commands instead of passing data through.
- Data mode
- The normal operating mode. Bytes from the radio side appear at the UART; bytes written to the UART go out over the radio.
- EN / KEY pin
- The HC-05's mode-select input. HIGH at boot = AT mode; LOW or floating = data mode. Some modules expose this; others use a momentary button instead.
- Bridge sketch
- A pass-through Arduino sketch that copies bytes between USB Serial and SoftwareSerial. Lets you type AT commands from a laptop terminal as if you were directly wired to the module.
- Line ending (CR+LF)
- The terminator AT commands require. Carriage return (\r, 0x0D) + line feed (\n, 0x0A). Set in the Arduino Serial Monitor's dropdown.
- Factory reset (
AT+ORGL) - Reset all settings (name, PIN, baud, role) to factory defaults. The "rescue command" if you've forgotten your PIN.
- Master / slave (role)
- HC-05 can be either. Master initiates connections (e.g. to another HC-05); slave waits for incoming connections (e.g. from your phone). Default is slave.
Homework 5 min
- Save the bridge sketch as
at-bridge.ino. Re-use whenever you need to talk to an HC-05 module. - Save a one-page "Bluetooth module config" in your notebook: name, PIN, MAC, current baud, recovery steps. One per module you own.
- Read ahead to ARD-L03-25 (Bluetooth Commands). Tomorrow we extend yesterday's LED rig to a richer command set with arguments — the protocol layer above raw bytes.
Bring back next class:
- Personalised, repinned HC-05.
- Module config page.
- Bridge sketch saved.