HM-10 Bluetooth 4/BLE Modules

Updated 2017-01-05.
Updated 2017-03-01.
Since I first posted about the HM-10 the firmware has been update several times and some of the commands are no longer supported. Therefore, I decided to redo the guide. For this update I am using modules with firmware 5.40 and 5.47.

Introduction
Bluetooth / BLE
HM-10 Basic specs
Get Started With the HM-10
Getting an Arduino talking to the HM-10
HM-10 AT Commands: Using the Arduino’s serial monitor to talk to the HM-10
Scanning for other HM-10s
Arduino to Arduino using HM-10s
HM-10: Updating the firmware
HM-10 Downloads

Introduction

The HM-10 is has become a very popular Bluetooth 4 / Bluetooth LE / BLE module for use with the Arduino. In part this is due to the standard UART serial connection it offers that makes it fairly straight forward to connect to an Arduino (The UART layer is a good thing and a bad thing).

The HM-10 is made by Jinan Huamao who make a range of Bluetooth modules including the HM-11 which works in the same way as the HM-10 but in a smaller form factor with less pins broken out.

There are 2 versions of the HM-10; the S version and the C version. There are slight component differences and the HM-10C does not have the pads along the bottom (26 pads instead of 34) but operationally they are the same.

HM-10S

HM-10S

HM-10C

HM-10C


For this article I am using HM-10Cs on the Keyes branded breakout boards. I purchased these from a seller on taobao and they are also available from the usual sources like ebay and Aliexpress as well as many other places. I also have a couple of HM-10Ss are on non-branded breakout boards.

HM-10The actual HM-10 is the small daughter board but most people use the HM-10 name interchangeably between the the small original board and the board+breakout board together.

One important thing to be aware of; the small original board is a 3.3v device and is not 5v tolerant. The breakout board adds, among other things, a 3.3 voltage regular so that a 5V power supply can be used. Unfortunate the RX and TX pins are still 3.3v.

 

Bluetooth 4 / BLE

BLE is not an upgrade to Bluetooth Classic, it is a different system with different intended uses. BLE works in a very different way to the earlier Bluetooth. BLE is designed for low energy applications and achieves this by using infrequent small packets of data. It is not really designed for continuous connections and large amounts of data. For this, Bluetooth Classic is a better choice. In essence, BLE achieves its low power consumption by not being connected very often, unlike Bluetooth Classic which maintains a constant connection.

While you can create a classic style connection using 2 HM-10s, and I give an example below, they were not designed for this and if this is all you need then you would be better suited with Bluetooth Classic modules like the HC-05s or a HC-05 and a HC-06.

There are 2 ways BLE devices can talk to each other; Broadcaster + Observer, and, Central + Peripheral. The HM-10 can use both methods.

  • With Broadcaster + Observer there isn’t a standard connection, the Broadcaster, usually some kind of sensor, sends out periodic signals (advertising packets) which the Observer listens for. The Broadcaster does not normally know if anything is listening or not.
  • The Central + Peripheral scenario is more like (but not exactly the same) as the classic connection. When the Central (master) device finds a Peripheral (slave) device it wants to connect to it initiates a connection and takes on the master role managing the connection and timings.

 
 
 

The HM-10 Basic Specs

The HM-10 has become a popular Bluetooth 4/BLE module for use with the Arduino as the standard UART serial connection makes it fairly easy to use. Although the Bluetooth 4 spec includes backwards compatibility with Bluetooth 2.1, the HM-10s are Bluetooth 4.0 only and not compatible with Bluetooth 2.0 or 2.1. This means they cannot connect to modules like the HC-06 and HC-05 which are Bluetooth 2.1 / Bluetooth Classic.

The HM-10s can act as master(central) or slave(peripheral) by changing settings via AT commands.

Basic Specs

  • Bluetooth version 4.0
  • Default baud rate is 9600
  • Default PIN is 000000
  • Default name is HMSOFT
  • All the modules I have, have the CCCC2541 chip

The HM-10 has a UART serial layer added to the BLE. This means they connect to an Arduino using serial the same as many other modules. This makes then easy to use but hides the BLE layer from the user. This means you lose some of the control and benefits of BLE.

The HM-10 is controlled via AT commands which allow you to do things like change the name, change the baud rate used for the serial communications, set what role to use, etc.
 

Onboard LED

The on board LED blinks when waiting for connection. It blinks once a second (half a second on, half a second off).
The LED becomes solid on when a connection is made and returns to blinking when the connection is broken.
The LED changes to solid on when pairing. After pairing it returns to flashing. It basically makes a connection to pair and so turns on the LED to show the connection status. After pairing is completed the connection is closed and the LED is turned off.

The status of the STATE pin mimics the LED and the STATE pin goes HIGH whenever the LED is on.
 

BRK Pin

The BRK pin allows you to cancel a connection. When there is an active connection, bringing the BRK pin momentarily LOW breaks the connection. When there is no connection making the BRK HIGH or LOW has no effect. Although not strictly required, pulling the BRK pin HIGH for normal use will stop the pin floating.

 
 
 

Get Started With the HM-10

First lets use an Android device to read the services and characteristics from the HM-10

Checking the HM-10 with an Android Device

Depending on your Android device and the version of Android you are running the HM-10 may or may not show up when searching for Bluetooth devices under the Android Settings.

Samsung S7 with Android 6.0.1 – Finds the HM-10 and allows pairing.
Sony Z3 Compact running Android 4.4.4 – Finds the HM-10 and allows pairing.
Huawei honor pro 4 running Android 4.4.4 – Does not find the HM-10

If you device does not find the HM-10 try using a BLE scanner such as B-BLE or BLE Scanner

HM-10_S7_SCRN_001HM-10_Sony Z3_SCRN_001HM-10_honorPro4_SCRN_001

The Samsung S7 and the Sony Z3 Compact find the HM-10 through Settings but the honor Pro 4 does not. When using a BLE app all phones can find the HM-10 though.

 

Reading the characteristics of the HM-10 using an Android device

Using a Samsung S7 running Android 6, the modules appear when scanning for Bluetooth devices in Settings => Bluetooth and I am able to pair. This is the same for my Sony Z3 Compact (Android 4.4) but not my my Huawei honor pro 4 (Android 4.4). If your Android devices fails to find the HM-10s use a BLE scanning app like B-BLE or BLE Scanner. If that fails check that the device has BLE.
HM-10_002_Samsung_S7_Pairing_800
The modules can be paired using the default pin 000000 (unless you have changed it of course).

Using BLE Scanner

Open the BLE Scanner app and find the HM-10. Tap the CONNECT button to get the app to connect to the HM-10 and start reading its properties.
HM-10_BLE-Scanner_001HM-10_BLE-Scanner_002

.

Clicking the small down arrows will expand the three data types.
HM-10_BLE-Scanner_007

Tapping the HM-10_BLE-Scanner_009_R_20 labels gives you additional information. For example, under Device Name, tapping the HM-10_BLE-Scanner_009_R_20 shows the name value.
HM-10_BLE-Scanner_008_Name

R = Read value
W = Write Value
I = Toggle indications on and off
N = Toggle notifications on and off

 

Getting an Arduino talking to the HM-10

Next we will connect the HM-10 to an Arduino and try basic serial communication and AT commands. The AT commands used in this section have been implemented for quite a while and therefore should work on all modules. A little later we will look at some of the newer AT commands that may require a firmware update.

Circuit

Connect the modules as per the following:
– HM-10 TX pin to Arduino D8
– HM-10 RX pin to a voltage divider and then to Arduino D9*
– HM-10 GND to GND
– HM-10 VCC to +5V

*The pins on the actual HM-10 (the small daughter board) are 3.3v only. They are not officially 5v tolerant so use a voltage divider or something else to bring the voltage down to 3.3v.

I am using AltSoftSerial to talk to the modules. AltSoftSerial uses pin D9 for transmission and pin D8 to receive.
HM-10_Circuit_001_800

HM-10_Breadboard_001_1200

The HM-10 is a 3.3v device. The breakout board converts the +5v vcc to 3.3v to power the HM-10 but the RX pin is still 3.3v. Therefore, we need to bring down the Arduinos 5V TX pin to 3.3V. A simple way to do this is by using a voltage divider made from 2 resistors. I use a 1k ohm resistor and a 2k ohm resistor. 1K+2K = 3K. 2K is 2 thirds of 3K and 2 thirds of 5V is 3.3v.

The Arduino will see the 3.3v signal from the HM-10 TX pin as HIGH so we can connect the HM-10 TX pin directly to the Arduino RX pin (D8).

HM-10_SerialMonitor_011_VoltageDivider_800I am using a premade voltage divider. Because I make a lot of this kind of breadboard circuit I make small breadboard modules. One of these is a voltage divider.

If you want to be special you can place a LED on the STATE pin. Remember to add a resistor. The STATE pin is 3.3v when HIGH so using Ohm’s law we find that a 100ohm resistor would be OK. I didn’t have one on hand so I used a 220ohm one that I did have. Using larger resistors is OK but you shouldn’t use smaller ones. The LED will blink in sync with the on board LED.

HM-10_Circuit_003_LED_800HM-10_Breadboard_004_LED_800

Serial Sketch

After building the circuit upload the following sketch. This is a simple serial in, serial out program. Whatever the Arduino receives from the serial monitor it relays to the HM-10. What ever it receives from the HM-10 it copies to the serial monitor. Since the HM-10 does not like newline and carriage return (/n/r) characters the # character is used to create a newline in the serial monitor. This is not required for your own projects but I use it to make the examples clearer to see.

The sketch uses AltSoftSerial which will need to be added to the Arduino IDE or copied to the library folder before you can compile.

// basicSerial_AltSoftSerial_003
//
//  Uses hardware serial to talk to the host computer and AltSoftSerial for communication with the bluetooth module
//
//  When a command is entered in the serial monitor on the computer 
//  the Arduino will relay it to the Bluetooth module and display the result in the serial monitor.
//
//  Pins
//  BT VCC to Arduino 5V out. 
//  BT GND to GND
//  Arduino D8 (ASS RX) - BT TX no need voltage divider 
//  Arduino D9 (ASS TX) - BT RX through a voltage divider
//
 
#include <AltSoftSerial.h>
AltSoftSerial BTSerial; 
 
 
char c=' ';
 
void setup() 
{
    Serial.begin(9600);
    Serial.print("Sketch:   ");   Serial.println(__FILE__);
    Serial.print("Uploaded: ");   Serial.println(__DATE__);
    Serial.println(" ");
 
    BTSerial.begin(9600);  
    Serial.println("BTserial started at 9600");
    Serial.println("Enter a # character to create a newline");
    Serial.println(" ");
 
}
 
void loop()
{
 
    // Read from the Bluetooth module and send to the Arduino Serial Monitor
    if (BTSerial.available())
    {
        c = BTSerial.read();
        Serial.write(c);
    }
 
 
    // Read from the Serial Monitor and send to the Bluetooth module
    if ( Serial.available() )
    {
        c = Serial.read();
 
        // ENTER THE # character to create a newline.
        if (c=='#')  { Serial.write(10);  Serial.write(13);   }
        else         { Serial.write(c);   BTSerial.write(c);  }
    }
 
 
}

 
 

HM-10 AT Commands: Using the Arduino’s serial monitor to talk to the HM-10

Open the serial monitor and you should see something similar to:
HM-10_SerialMonitor_001

Remember that the HM-10 requires commands to be in upper case and no line endings. So if you have not already done so, set line ending to “No line ending” at the bottom of the serial monitor. The sketch uses 9600 baud rate so also ensure you have 9600 selected.
HM-10_SerialMonitor_002

To see if the connections are correct we use the AT command. The AT command is used to confirm communication is working and all it does is return an “OK”.

Enter “AT” (no quotes) in the text box and click Send. If everything is working you should see “OK”.
HM-10_SerialMonitor_003
The HM-10 does not use line endings so everything would normally appear on one line.

To check what firmware the HM-10s have, use AT+VERR?
HM-10_SerialMonitor_004

To check the modules name use AT+NAME?, or use an Android device and search for Bluetooth devices. The default name is HMsoft.
HM-10_SerialMonitor_005b_NAME
HM-10_SerialMonitor_005c_NAME_Android
This only works when the HM-10 is in Salve/Peripheral mode. When in Master/Central mode it does not broadcast its name.

To get the modules address, use AT+ADDR?
HM-10_SerialMonitor_006b_ADDR

Change the name using AT+NAME. Later I will be using 2 HM-10s and changing the names will help identify which is which. As you can see from the below I have changed the name to HMsoft-38A3. The “38A3″ are the last 4 digits of the mac address.
HM-10_SerialMonitor_010_NAME

To get the modules Bluetooth characteristic, either use AT+CHAR? or use a BLE scanner.
HM-10_SerialMonitor_016_CHAR_02

To find the UUID use AT+UUID? This returns OK+Get:0xFFE0.
HM-10_SerialMonitor_015_UUID_02

 
To get the commands on separate lines I am using a # character. After getting the result from a command I simply enter # and hit send. The sketch then printsd a new line to the serial monitor.
HM-10_SerialMonitor_007_HASH

 

Common AT commands

Here is a list of the main AT commands. Remember that commands should be in uppercase and not include line ending characters (\r\n).

AT Test Command or Disconnect Command If the module is not connected to a remote device it will reply: “OK”
If the module has a connection then the connection will be closed. If the notification setting is active, the module will reply with “OK+LOST”
AT+NAME? Query the name Returns the name the module broadcasts such as HMsoft.
AT+NAMEnewname Change the name of the module Changes the name broadcast by the module. For example
AT+NAMEmyBTmodule changes the name to myBTmodule.
The maximum length for a new name is 12 characters.
AT+ADDR? Queries the HM-10s mac address Returns the address as a 12 digit hexidecimal number. For example, OK+ADDR:606405D138A3
AT+VERS?
AT+VERR?
Queries the firmware version number For example: HMSoft V540
AT+RESET Restarts the module. Returns OK+RESET
Will close an active connection while restarting.
AT+RENEW Restores the default factory settings. Good if you have changed the PIN and have forgotten what you changed it to.
AT+BAUD? Query the baud rate used for UART serial communication. This is the speed a host device like an Arduino uses to talk to the BT module. It is not the the speed used to send wireless signals between different modules. Returns the value 0-8, for example, OK+Get:0
0 – 9600
1 – 19200
2 – 38400
3 – 57600
4 – 115200
5 – 4800
6 – 2400
7 – 1200
8 – 230400
The default setting is 0 – 9600.
Remember that both devices, the Arduino and the HM-10 need to use the same baud rate. Garbage characters are usually a sign of mismatched baud rates.
AT+BAUDx Set the baud rate used for UART serial communication. x is a value from 0 to 8. See the above for wwhat value represents which baud rate.
Take care when using with an Arduino. The maximum baud rate the Arduino serial monitor allows is 115200. If you set the baud rate to 230400 with AT+BAUD8 you wont be able to talk to the module.
AT+NOTI Set the notification status If notifications are turned on, the HM-10 will reply to commands with a confirmation message or send out a message when certain events take place, like “OK” for the AT command and “OK+LOST” when a connection is broken.

AT+NOTI0 – turn off notifications
AT+NOTI1 – turn on notifications

AT+NOTI? Query the notification status Returns either 0 or 1:
0 – notifications are off
1 – notifications are on
AT+PIN? Query the PIN number used for pairing. Replies with a 6 digit number like “OK+Get:123456″ or whatever the current PIN number is.
AT+PIN Set a new PIN/PASS. The PIN must be 6 characters long..
AT+PIN123456 sets the new PIN number to 123456
AT+ROLE? Query the current Role; Master or Slave AT+ROLE? returns either 0 or 1.
0 = Slave or Peripheral
1 = Master or Central.
The default setting is 0 (Slave).
AT+ROLEx Set the device role. x is 0 or 1. To change to Slave/Peripheral mode use AT+ROLE0. This will return OK+Set:0
To change to Master/Central mode use AT+ROLE1. This will return OK+Set:1

For a full list of AT commands see the official data sheet. The download is version 5.45 published Jan 2017.

 
 

Scanning for other HM-10s

The HM-10 has to be in Master/Central mode to scan. HM-10s are set to Peripheral mode by default so we need to change to Central mode. We do this using the AT+ROLE command.
AT+ROLE? queries what mode the device is in.
AT+ROLE0 sets the module to Peripheral mode.
AT+ROLE1 sets the module to Central mode.

Use AT+ROLE? to find out what mode the HM-10 is currently in.
HM-10_SerialMonitor_020_ROLE_01

Use AT+ROLE1 to put the HM-10 in to Central mode.
HM-10_SerialMonitor_020_ROLE_02

Next we need to set the modules start work type mode. There are two options AT+IMME0 and AT+IMME1.
AT+IMME0 sets the module to start working straight away when powered on. This mode is used if you want to module to auto connect on start up.
AT+IMME1 sets the module so that it it will not make any connection until it receives the appropriate AT command (AT+START, AT+CON, and AT+CONNL).
HM-10_SerialMonitor_020_IMME_01

To scan for other HM-10 modules use the Discover command AT+DISC?

Since firmware version 5.3x. Jinan Huamao changed how the module finds non HM-10 modules. Now, by default, a scan will only show other HM-10s.

HM-10_SerialMonitor_020_DISC_01

Returned is the address and name of the modules found.

AT+DISC?OK+DISCSOK+DIS0:A81B6AAE55E4OK+NAME:HMSoft
OK+DISCE

The results are stored inside the HM-10 in an index. The index is based on the position the address is listed and starts at position 0. So, if the HM-10 only finds one module the result will be stored at index 0. When more than one module is found the addresses will be stored in the order they are discovered. The index can be used when making a connection instead of using the full address.

This is one of the rare occasions the HM-10 adds line endings. After the list of discovered modules and before the “OK+DISCE” the module will add NL and CR characters. The “OK+DISCE” statement shows that the scan has Ended.

 

Arduino to Arduino using HM-10s

Connecting 2 Arduinos using 2 HM-10s is fairly easy. The HM-10s has a single connection command and the serial UART layer does all the hard work. The UART layer does mean you have no control over the actual BLE details though. To make a connection, all we need to do is set the main module to Central mode and then use the connection command AT+CON. The HM-10 transfers data by setting the value of a characteristic to the data you are sending. The receiving device then reads the value.

For this example I have 2 Arduinos with each Arduino connected to a HM-10. Both are wired up exactly the same.

HM-10_Connection_Circuit_001_1200

HM-10_040_Breadboard_Connection_003_800
and if you are wondering where the second HM-10 is getting power from; the connections are round the back.
HM-10_040_Breadboard_Connection_002_800

I am using 2 different Arduino IDEs. Version 1.82 as the main IDE and version 1.63 as the secondary IDE. This gives me 2 serial monitors. The Arduino on COM14 is #1 and the Arduino on COM9 is #2.

HM-10_Connection_001_2IDEs

 

HM-10 to HM-10 manual connection

To make a connection we:
Set the main module to Central mode with “AT+ROLE1″.
Then set it for manual start mode using “AT+IMME1″.
Then use “AT+CONA81B6AAE55E4″ to connect. Of course I need to know the address of the second module for this which I found by using “AT+DISC?”.

If the connection is successful we get “OK+CONNA” and the LEDs on the HM-10s stop flashing and become steady on.

HM-10_SerialMonitor_030_Connecting
Remember that the sketch copies everything entered in the input box to the main window so when I enter the AT+CON command I get “AT+CONA81B6AAE55E4OK+CONNA” in the serial monitor. “AT+CONA81B6AAE55E4″ is the command I entered and “OK+CONNA” is the reply.

Now, everything entered in one serial monitor is transmitted to the other.

Note that I have change the line endings to Both NL & CR. This adds a new line to everything I enter.

HM-10_Connection_002b

HM-10_Connection_004b

 

HM-10 to HM-10: Turning an LED on and off

We now try LED remote control. This is a very simply example, when a button switch is pressed a remote LED comes on. When the button switch is released the LED goes out.

On Arduino #1 we add a button switch to D2 and on Arduino #2 we add a LED to D4.

The switch on Arduino #1 is pulled down with a 10K resistor. This means pressing the button switch goes LOw to HIGH.
The LED on Arduino #2 is connected inline with a 220 ohm resistor (330 ohm is also OK).

HM-10_connection_005_circuit

HM-10_connection_006_BreadBoards_1200

 
HM-10_Remote_LED_400

 
The sketch on the master Arduino uses 3 AT commands to set up the Central HM-10 and start the connection. These are the same commands we used in the manual connection example above.

BTserial.print("AT+ROLE1" );
delay(1000);
BTserial.print("AT+IMME1" );
delay(1000);
BTserial.print("AT+CONA81B6AAE55E4" );
delay(1000);

This is not really the best solution but it works and it keeps the example easy to understand.
Of course, if the HM-10 is already in Central mode and in manual start mode the first 2 commands are not required.
The delays allow time for the replies. You could, if you wished, check for the correct reply before moving to the next command.

After this, the sketch checks the status of the pin connected to the button switch and if it has changed sends out 1 of 2 commands.

  • LOW to HIGH. The button switch has been pressed so we want to turn on the LED. This is done by sending a “1” to the remote module.
  • HIGH to LOW. The button switch has been released so we want to turn of the LED. This is done by sending a “0” to the remote module.

Note that we are send ascii “1” and ascii “0” not the value 1 and the value 0.

// Very simple debouce.
boolean state1 = digitalRead(switchPin); delay(1);
boolean state2 = digitalRead(switchPin); delay(1);
boolean state3 = digitalRead(switchPin); delay(1);
 
if ((state1 == state2) && (state1==state3))  
{ 
    switch_State = state1;  
 
    if (switch_State != oldswitch_State)
    {
          if ( switch_State == HIGH) { BTserial.print("1" );  Serial.println("1"); }
          else                       { BTserial.print("0" );  Serial.println("0"); }
 
          oldswitch_State = switch_State;
    }
}

 
The secondary Arduino simply checks for a “1” or a “0” and if it finds one of them it either turns the LED on or turns the LED off.

void loop()
{
    // Read from the Bluetooth module and check if it is a command
    if (BTSerial.available())
    {
        c = BTSerial.read();
 
        // 49 is the ascii code for "1"
        // 48 is the ascii code for "0"
        if (c==49)   { digitalWrite(LEDpin,HIGH);   }
        if (c==48)   { digitalWrite(LEDpin,LOW);    }
        Serial.println(c);
    }
 
}

 
 
Here are the full sketches.

On the first Arduino we have HM-10_Example_01_simpleLED_Central.

// HM-10_Example_01_simpleLED_Central
//
//  Simple remote control using HM-10s: LED on. LED off
//
//
//  Pins
//  BT VCC to Arduino 5V out. 
//  BT GND to GND
//  Arduino D8 (ASS RX) - BT TX no need voltage divider 
//  Arduino D9 (ASS TX) - BT RX through a voltage divider
//
 
#include <AltSoftSerial.h>
AltSoftSerial BTserial; 
 
byte switchPin = 2;
boolean switch_State = LOW;
boolean oldswitch_State = LOW;
 
void setup() 
{
    Serial.begin(9600);
    Serial.print("Sketch:   ");   Serial.println("basicSerial_AltSoftSerial_003.ino");
    Serial.print("Uploaded: ");   Serial.println("Jan 10 2017");
    Serial.println(" ");
 
    BTserial.begin(9600);  
    Serial.println("BTserial started at 9600");
    Serial.println(" ");
 
    pinMode(switchPin, INPUT); 
 
    // connect to the remote Bluetooth module
    BTserial.print("AT+ROLE1" );
    delay(1000);
    BTserial.print("AT+IMME1" );
    delay(1000);
    BTserial.print("AT+CONA81B6AAE55E4" );
    delay(1000);
 
}
 
void loop()
{
    // Very simple debouce.
    boolean state1 = digitalRead(switchPin); delay(1);
    boolean state2 = digitalRead(switchPin); delay(1);
    boolean state3 = digitalRead(switchPin); delay(1);
    if ((state1 == state2) && (state1==state3))  
    { 
        switch_State = state1;  
 
        if (switch_State != oldswitch_State)
        {
              if ( switch_State == HIGH) { BTserial.print("1" );  Serial.println("1"); }
              else                       { BTserial.print("0" );  Serial.println("0"); }
 
              oldswitch_State = switch_State;
        }
    }
}

 
 
On the second Arduino we have HM-10_Example_01_simpleLED_Peripheral.

// HM-10_Example_01_simpleLED_Peripheral
//
//  Pins
//  BT VCC to Arduino 5V out. 
//  BT GND to GND
//  Arduino D8 (ASS RX) - BT TX no need voltage divider 
//  Arduino D9 (ASS TX) - BT RX through a voltage divider
//
 
#include <AltSoftSerial.h>
AltSoftSerial BTSerial; 
 
char c=' ';
byte LEDpin = 4;
 
void setup() 
{
    Serial.begin(9600);
    Serial.print("Sketch:   ");   Serial.println("basicSerial_AltSoftSerial_003.ino");
    Serial.print("Uploaded: ");   Serial.println("Jan 10 2017");
    Serial.println(" ");
 
    BTSerial.begin(9600);  
    Serial.println("BTserial started at 9600");
    Serial.println(" ");
 
    pinMode(LEDpin, OUTPUT); 
    digitalWrite(LEDpin,LOW); 
}
 
void loop()
{
    // Read from the Bluetooth module and check if it is a command
    if (BTSerial.available())
    {
        c = BTSerial.read();
 
        // 49 is the ascii code for "1"
        // 48 is the ascii code for "0"
        if (c==49)   { digitalWrite(LEDpin,HIGH);   }
        if (c==48)   { digitalWrite(LEDpin,LOW);    }
        Serial.println(c);
    }
 
}

The above works well but what happens when you reset Arduino #1 when there is an Active connection? The AT commands get sent as data and any “1”s or “0”s in the data get recognised as LED Commands. There are a couple of ways to stop this happening.

  1. Before sending the AT commands, send a welcome message to see if there is an active connection. The remote device would reply to the message.
  2. Check the HM-10 STATE pin before sending the AT commands. The STATE pin is HIGH when there is a connection. This is the easiest option.

I leave this to you to implement.

 
 
 

HM-10 an an iBeacon

Not yet available. Being rewritten.

 
 
 

HM-10: Updating the firmware

One of the nice things about the HM-10 is that Jinan Huamao update the firmware on a fairly regular basis and make all the tools and the latest firmware available from the download centre on their website. They also have a guide on uploading new firmware.

Like the Arduino, the HM-10 has a boot loader that makes uploading new firmwares fairly straight forward. You will need a Windows PC and a USB to serial UART adaptor though.

Tools required

– Windows PC.
– USB to serial UART adaptor.
– If you want to be extra safe a couple of resistors to form a voltage divider.
– Firmware zip archive.

 

Get the files

From the download Centre down load the latest HM-10 firmware zip file, place it somewhere convenient such as your desktop, and unpack it.
HM-10_FW_002_downloadCentreWebsite

Note: The firmware for the CC2540 and the CC2541 chips are not the same. You cannot load the CC2540 firmware on the CC251 chip.
All the HM-10s I have use the CC2541 chip and the only firmware available on the Jinan Haumao website is for the CC2541 chip but it is still worth double checking.

This is a zip archive for firmware 5.47 which contains the following 4 files. Other firmwares may be different.
HM-10_FW_003_DownloadFileList
The two files we need are HMSoft.exe, and HMSoft.bin. HMSoft.exe is a Windows app that does the uploading and HMSoft.bin is the actual firmware. HMSoft.exe does not need installing, just double click to run it.

Connecting the HM-10 to a PC

I am using a 5v UART adapter so I am using a voltage divider on the TX pin. Many guides online show connections from a 5V UART adaptors (and 5V Arduinos) TX pin straight to the HM-10 RX pin. I do not advise it. The HM-10 is a 3.3v device and the RX pin is not designed for 5V. To reduce the 5V signal from the UART adapter to 3.3v I am using a voltage divider made from a 1K ohm resistor and a 2k ohm resistor.
The HM-10s TX pin is also 3.3v but 5V UART adaptors will read 3.3v as HIGH so we do not need to convert to 5V. Since I am using the HM-10 on a breakout board that has a 3.3v regulator I can connect 5V VCC directly to the VCC pin on the board.

If you are using a 3.3v UART adapter then you will not need the voltage divider but you will more than 3.3v to power the HM-10. The voltage regulator on the breakout board requires a minimum of 3.6v to operate.

HM-10_FW_003_BreadboardFront_800
HM-10_FW_004_BreadboardBack_800
VCC and GND from the UART adaptor are fed to the + and – rail on the bread board.

HM-10_FW_030_Circuit

 

Checking we can talk to the HM-10

After setting up the connections we need to check that we can talk to the HM-10. Any terminal app can be used but to keep it simple I generally use the Arduino IDE.

A couple of things to remember. The HM-10 likes commands in uppercase and it does not like line endings.

Open the Arduino IDE and make sure the correct COM port is selected. On my computer this UART adapter is Port 6. You need to remember the port number for later.
HM-10_FW_005_COMport

Open the Serial Monitor, select “9600 baud” and “No line ending” at the bottom, then enter “AT”. If the connections are correct you will get an “OK”.
HM-10_FW_006_AT+OK

If you do not get the “OK”:
– Check you have the correct baud rate. The default is 9600.
– Check that you have “No line ending” selected at the bottom of the Serial Monitor.
– Check that you have the TX and RX connections the right way round.
– Check that you have the correct value resistors and that they are in the right order.

After confirming that we have communication working we can check the existing firmware version with “AT+VERR?”.
HM-10_FW_007_VERR
As you can see the HM-10 I am updating is version 5.40.

To put the HM-10 in to update mode use the “AT+SBLUP” command. You should get a “OK+SBLUP” reply and the LED on the HM-10 will stop flashing.
HM-10_FW_008_SBLUP

We can now close the Serial Monitor.

 

Actually updating the firmware

Open the folder containing the firmware files and run the HMSoft.exe file. If you are using Win7 or later you may need to run the app in admin mode.
HM-10_FW_010_HMSoft

Load the bin file, enter the correct COM port number and then hit the Load Image button.
HM-10_FW_011_updateFirmware

The firmware file is first written and then verified.
HM-10_FW_020_updateFirmware

When finished the Download completed successfully dialogue box will pop up and the LED on the HM-10 will start to flash again.
HM-10_FW_021_updateFirmware

We can now close the updater app and reopen the Serial Monitor to check the new firmware version.
HM-10_FW_022_updateFirmware_VERR

Firmware 5.46 adds 128 bit UUID compatibility
Firmware 5.47 adds the AT+DISA? command that “search devices and return full information”.

Using fw V5.47 I am able to connect to the non HM-10 BLE modules like the AT09 and BT05 and data sent from the remote device is received by the HM-10. Unfortunately data sent by the HM-10 is not received by the other device. It is early days though and I have not spent much time on this.

 

Trouble shooting the firmware update

If you start the update and nothing happens you have probably left the Arduino IDE open. You need to close it to free up the COM port. The update app does not give an error message if the COM port is not available. It just sits there.

If you get a timeout error when updating try again. If you keep getting the error your UART adapter is likely to blame. I have a couple that are not good at high speed (I suspect they have fake FDTI chips) and they give errors when uploading and/or verifying.

If you crash out and the LED on the HM-10 remains solid on. It means it is still in upload mode. It will remain in upload mode even after cycling the power. Just start the update again using the update app.

 
 
 

HM-10 Downloads

HM-10 data sheet V5.45
Official update firmware guide
V5.47 firmware files
HM-10 Self-learning guide. Requires fw v5.42 or later.

 
 
 
 

 

3 thoughts on “HM-10 Bluetooth 4/BLE Modules

  1. Pingback: Bluetooth Modules | Martyn Currey

Leave a Reply

Your email address will not be published. Required fields are marked *


6 − = two

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>