On a Mega the HC-05 gets a real hardware serial port. Wire it to Serial1 (RX1 = 19, TX1 = 18) and the Mega can talk to the phone, to the PC and to other modules at the same time.
The same sketch has two modes. In data mode, send 1 or 0 from a Bluetooth terminal app to switch the on-board LED. In AT mode it becomes a terminal for renaming the module or changing its PIN — handy when a classroom has ten robots all called “HC-05”.
Wiring
| Arduino Mega 2560 | HC-05 Bluetooth serial module | Wire | Notes |
|---|---|---|---|
| 5V | VCC | red | |
| GND | GND | black | |
| D19 | TXD | green | HC-05 TX → RX1. |
| D18 | RXD | yellow | Via 1 kΩ / 2 kΩ divider — TX1 → HC-05 RX, 5 V brought down to ~3.3 V. |
3.6–6 V on VCC (on-board 3.3 V regulator) — power from 5 V part, 5 V board. The module runs at 3.3 V logic. Its TXD connects straight to any board’s RX. Its RXD must not see 5 V: from an Uno or Nano TX, use a 1 kΩ / 2 kΩ divider. From ESP32 or Pico, connect directly.
Board quirks
- Use Serial1 instead of SoftwareSerial: the HC-05’s AT mode runs at 38400 baud, which SoftwareSerial handles badly but the Mega’s hardware UART does easily.
- Enter AT mode by holding the module’s button while you power it — the LED then blinks slowly (about every 2 s). Set
AT_MODE = trueand the Serial Monitor to Both NL & CR. - Useful AT commands:
AT+NAME=Pump1,AT+PSWD="4321"(some firmware:AT+PSWD=4321),AT+UART=9600,0,0. - Never connect the HC-05 to pins 0/1 on the Mega — that is the USB port.
Code
// HC-05 Bluetooth on an Arduino Mega 2560's hardware Serial1, with an AT-command mode.
// HC-05 TXD → D19 (RX1), RXD ← D18 (TX1) through a 1 kΩ / 2 kΩ divider, VCC → 5V, GND → GND.
// Data mode: 9600 baud. AT mode: hold the module's button while powering it (LED blinks slowly),
// set AT_MODE = true, and type AT commands in the Serial Monitor ("Both NL & CR").
const bool AT_MODE = false;
void setup() {
Serial.begin(115200);
Serial1.begin(AT_MODE ? 38400 : 9600); // AT mode is always 38400 on the HC-05
pinMode(LED_BUILTIN, OUTPUT);
Serial.println(AT_MODE ? F("AT mode - try AT, AT+NAME?, AT+PSWD?") : F("Data mode - pair the phone, send 1 or 0"));
}
void loop() {
while (Serial1.available()) {
char c = Serial1.read();
if (!AT_MODE && c == '1') digitalWrite(LED_BUILTIN, HIGH);
if (!AT_MODE && c == '0') digitalWrite(LED_BUILTIN, LOW);
Serial.write(c);
}
while (Serial.available()) Serial1.write(Serial.read());
}// HC-05 Bluetooth on an Arduino Mega 2560's hardware Serial1, with an AT-command mode.
// HC-05 TXD → D19 (RX1), RXD ← D18 (TX1) through a 1 kΩ / 2 kΩ divider, VCC → 5V, GND → GND.
// Data mode: 9600 baud. AT mode: hold the module's button while powering it (LED blinks slowly),
// set AT_MODE = true, and type AT commands in the Serial Monitor ("Both NL & CR").
const bool AT_MODE = false;
void setup() {
Serial.begin(115200);
Serial1.begin(AT_MODE ? 38400 : 9600); // AT mode is always 38400 on the HC-05
pinMode(LED_BUILTIN, OUTPUT);
Serial.println(AT_MODE ? F("AT mode - try AT, AT+NAME?, AT+PSWD?") : F("Data mode - pair the phone, send 1 or 0"));
}
void loop() {
while (Serial1.available()) {
char c = Serial1.read();
if (!AT_MODE && c == '1') digitalWrite(LED_BUILTIN, HIGH);
if (!AT_MODE && c == '0') digitalWrite(LED_BUILTIN, LOW);
Serial.write(c);
}
while (Serial.available()) Serial1.write(Serial.read());
}Expected serial output
Data mode - pair the phone, send 1 or 0
1
0Data mode - pair the phone, send 1 or 0 1 0
Common errors
No reply to AT
Not in AT mode (LED blinking fast), wrong baud (AT mode = 38400) or line ending not set to Both NL & CR.
Phone connects but the Mega receives nothing
TXD to pin 18 instead of 19. Module TX goes to Mega RX1 (19).