HM-10 BLE Module with an Arduino Uno
The HM-10 is a Bluetooth 4.0 Low Energy UART bridge on TI's CC2541 that works with iPhones, Android phones and Web Bluetooth.

The Arduino Uno has no radio of its own, and the HM-10 gives it a Bluetooth Low Energy link that phones reach through service 0xFFE0. On the Uno it runs from 5V on its carrier and uses SoftwareSerial on D10 and D11, with a 1 kΩ / 2 kΩ divider into RXD because the bare module runs at 2.5 V to 3.3 V.
Wiring the HM-10 BLE Module to the Arduino Uno
Pin by pin.
| HM-10 BLE Module | Arduino Uno | Note |
|---|---|---|
| VCC | 5V | |
| GND | GND | |
| TXD | D10 | |
| RXD | D11 | through a 1 kΩ resistor, with a 2 kΩ resistor from RXD to GND (a divider) |
| STATE | D7 | |
| Sensor output | A0 | optional: any analog sensor, such as a soil probe's AOUT; the sketch sends its reading as moisture= |
What to know on the Arduino Uno
- The bare HM-10 runs at 2.5 V to 3.3 V, so the Uno's 5 V TX on D11 reaches RXD through the divider; the carrier's regulator takes the Uno's 5V on VCC.DSD TECH HM-10 datasheet, p. 1
- The HM-10 can be set as fast as 230400 baud, but SoftwareSerial on the Uno is rated to 115200 at most and is most reliable far below that. Keep the factory 9600, or test any higher AT+BAUD setting before relying on it.DSD TECH HM-10 datasheet, p. 17; Arduino SoftwareSerial library reference
- Unlike the HC-05, AT commands take no line ending and only work while no phone is connected, which is why the sketch sends them in setup() with print() and a 150 ms pause.DSD TECH HM-10 datasheet, p. 10
- The example also sends analogRead(A0) to the phone as a moisture value. The table's optional row puts any analog sensor, such as a soil probe's AOUT, on A0; without one, the phone receives a floating reading.Microchip ATmega328P datasheet DS40002061B, p. 2
HM-10 BLE Module code for the Arduino Uno
Compiled for arduino:avr:uno on 2026-10-29.
// HM-10 BLE Module on Arduino Uno: wiring and a free simulation at https://www.tinkered.ai/components/hm-10/arduino-uno
#include <SoftwareSerial.h>
SoftwareSerial ble(10, 11); // RX, TX
const int STATE_PIN = 7;
void at(const char* cmd) {
ble.print(cmd); // no line ending: the HM-10 takes it when the line goes quiet
delay(150);
while (ble.available()) Serial.write(ble.read());
Serial.println();
}
void setup() {
Serial.begin(9600);
ble.begin(9600);
pinMode(STATE_PIN, INPUT);
pinMode(LED_BUILTIN, OUTPUT);
at("AT"); // OK
at("AT+NAMEPlantBot"); // OK+Set:PlantBot
at("AT+NOTI1"); // OK+Set:1, then OK+CONN / OK+LOST on links
}
uint32_t last = 0;
void loop() {
while (ble.available()) {
char c = ble.read();
if (c == '1') digitalWrite(LED_BUILTIN, HIGH);
if (c == '0') digitalWrite(LED_BUILTIN, LOW);
Serial.write(c);
}
if (digitalRead(STATE_PIN) && millis() - last > 1000) {
last = millis();
ble.print("moisture=");
ble.println(analogRead(A0));
}
}
HM-10 BLE Module on the Arduino Uno: questions
Can an iPhone connect to an Arduino Uno through the HM-10?
Yes: the HM-10 is Bluetooth 4.0 Low Energy (DSD TECH datasheet, p. 1), which phones reach with a BLE terminal app writing to characteristic 0xFFE1. A Classic module such as the HC-05 uses the serial port profile instead.
Why does the HM-10 ignore AT commands from my Uno?
Send them without a line ending (print, not println) and while no phone is connected (DSD TECH datasheet, p. 10). Check also that SoftwareSerial runs at the module's baud rate, 9600 by default.
Does the HM-10 need a level shifter on the Uno?
A divider is enough on RXD: 1 kΩ from D11 to RXD and 2 kΩ to GND. TXD goes straight to D10.
Keep going
This guide as plain Markdown. /components/hm-10/arduino-uno.md