HM-10 or CC41-A module? Automatic Arduino BLE module identification 13

Lately I am working a lot with Arduino, which is a new field for me, hence fewer posts. Arduino is a very popular entry level embedded electronics platform. My latest Arduino project features Bluetooth Low Energy (BLE) communication. Arduino boards have no built-in BLE capabilities so I was looking to add a BLE module to my circuit. After some research, the name HM-10 comes up as a popular and simple BLE option for Arduino. I ordered an HM-10 BLE module from the Far East via ebay. I soon discovered that there are many complexities involved, even before you get to send or receive the first packet over the air. The difficulties originate from the existence of “clones” of the original module, that though sold as HM-10 are actually different in some aspects from the original. Eventually I ordered and worked with both the original and clone. In this article I will cover the basic construction of the modules, the differences and will present an Arduino sketch that can automatically identify which module you have and then help you configure it without needing to remember the commands.

Parts of an Arduino BLE module

HM-10 Front

HM-10 Front

BLE system-on-chip (SoC) and micro-controller unit (MCU)

All the BLE modules I have seen use the Texas Instruments (TI) CC2541 chip. This is the large black square in the middle of the module as can be seen in the photo above. Online resources suggest that the CC2540 chip, that is similar, can also be used. This chip is programmed with matching firmware and it then implements the logical layers needed for the BLE protocol. The chip operates at voltages between 2V and 3.6V.

Daughter board

This is the light blue part in the photo above. The CC2541 chip needs some passive components to work, such as oscillators, capacitors, resistors and an antenna. Those are provided by this board. The daughter board is soldered to the main board around the perimeter, via arc-like soldering pins.

The daughter board that you can see in the photo above is the HM-10 module, made by Chinese “JNHuaMao Technology Company”, hence the HM initials. Their site is www.jnhuamao.cn (It might have been hacked at some point, so it is showing a “Reported attack page” warning for me in Firefox. Proceed at your own risk). JNHuaMao makes different kinds of Bluetooth modules. In this case they designed the board and wrote a firmware for the TI chip to implement the needed functionality. The firmware determines the interface that will be used to control the module over serial connection.

Another Chinese company, “Bolutek Technology Co., Ltd“, decided to make a similar board. Their model is called CC41-A (CC41 from now on). It uses the same TI chip and similar board design (both are based on TI’s reference design for the chip). One difference that is easy to spot is that CC41 only has one oscillator where HM-10 has two. This is ok as one of the oscillators is optional per CC2541 specifications. See a photo of the CC41 module below and identify the missing oscillator.

CC41 Front

CC41 Front

As can be seen, the daughter boards are very similar. The pins are also compatible. Regardless of whether Bolutek copied the board design or made one of their own, many sellers were selling the CC41 module by using the HM-10 module name. This led to confusion and caused JNHuaMao to launch a campaign against clones posting various accusations. The bottom line is that these two daughter boards have the same TI chip, very similar board layout but different firmware. When ordering from the Far East, relying on model name alone, you might not know which exact model you will be getting.

Voltage-wise, the daughter boards have no voltage regulators and expect to be powered by 3.3V per chip specifications. Similarly, the serial logic expects 3.3V TTL levels.

Module (breakout) board

These daughter board modules are not Arduino specific and expected to be soldered on to another PCB, for example one inside some remote controlled device. This is not convenient or popular in the Arduino space. Arduino modules are usually 5V and are connected with 2.54mm spaced pins which are good for solderless breadboards. This is where the breakout board comes in. The breakout board is the largest part in the photos above. It is the dark blue PCB with pins. The breakout board can add a voltage regulator to drop 5V to 3.3V, serial logic level conversion, leds, buttons and protection circuits.

A typical BLE module breakout board has between 4 and 6 pins. I would highly recommend getting the 6 pin versions. The basic pins are Vcc, Gnd, Rx and Tx. The additional pins depend on model and could be STATE, EN(able) or BRK. STATE allows you to know current module connection state, EN allows you to enable or disable the module and BRK allows you to initiate a disconnect of the current connection.

Keyes, HM-10 Back

Keyes, HM-10 Back

ZS-040, CC41 Back

ZS-040, CC41 Back

There is no particular reason to have a two PCB hierarchy. In fact, a company could have made a single breakout board to take us from a chip directly to 5V breadboard pin form-factor. In reality, the breakout boards are typically made by completely different companies than the ones making the daughter modules. Adding some logic to adapt a circuit for Arduino is a much simpler task than writing a firmware for Bluetooth and different companies that target different markets specialize in each task. In the photos above you can see that Keyes made the breakout board for the HM-10 while the CC41 breakout board is marked with “ZS”.

Further differences can be seen in pin order, serial logic voltage levels and price. The more expensive Keyes HM-10 module has an on-board 5V to 3.3V logic level conversion on pins Rx and Tx. This allows direct connection to Arduino digital pins. On the other hand, the simple ZS, CC41 module is clearly marked “LEVEL: 3.3V” meaning some logic conversion needs to be done. You can use a logic conversion chip/module or you can make your own voltage divider with two resistors to drop voltage on Arduino’s Tx pin by 2/3 for it to work properly with CC2541’s Rx pin.

It should be noted that there are other types of breakout boards (AC-BT-V4) and other types of daughter boards (i.e. HC-08) than those mentioned in this article. The principle should remain the same though. If you have one of the other modules in your possession I am interested to learn more to improve this resource. Please reach out.

Communicating with the module

In this article I will be assuming that you are connected in the following way:

  1. A PC connected to the Arduino over a Serial connection through a USB port. Using the hardware Serial port(s) of the Arduino.
  2. The Arduino is connected to the BLE module via Serial Rx and Tx pins (and power, obviously). With logic conversion, if required by the module. Using SoftwareSerial on any two available Arduino digital pins.
  3. The BLE module can then be connecting wirelessly via RF to another BLE device.

Both the HM-10 and CC41 use AT commands over the serial connection (#2) to configure the module. A single serial interface that is used for both data and commands. When the module is connected to another BLE device (#3), the serial connection is used for sending and receiving data. This is called “data mode”. When the module is disconnected from another BLE device, the serial connection is used for sending and receiving commands. This is called “command mode” and we need to be in this mode so we can sent AT commands to the device.

If we want to experiment with AT commands ourselves, we can use a simple sketch to echo any text from the module to the PC and vise-versa, using the Arduino as a middle man:

#include <SoftwareSerial.h>
SoftwareSerial BTSerial(2, 3); //RX|TX

void setup(){
  Serial.begin(9600);
  BTSerial.begin(9600); // default baud rate
  while(!Serial); //if it is an Arduino Micro
  Serial.println("AT commands: ");
}

void loop(){
  //read from the HM-10 and print in the Serial
  if(BTSerial.available())
    Serial.write(BTSerial.read());
   
  //read from the Serial and print to the HM-10
  if(Serial.available())
    BTSerial.write(Serial.read());
}

Firmware differences

Unfortunately the HM-10 AT commands are different from CC41 AT commands. Specifically the CC41 is less documented and the command set and available functionality are poorer.

Main differences include:

  • Case-sensitivity.
  • End-of-line termination, with HM-10 expecting no new-line or carriage-return while the CC41 expects both.
  • Different command names, such as VERS vs VERSION.
  • Different command syntax, such as using a ‘?’ for queries or not using any special character.
  • etc.

Automatic identification and simplified configuration

To cope with these complexities and simplify usage of these modules, I have written an Arduino sketch that will try to automatically detect your module type and then interface with it. Introducing “arduino-ble-ident’n’set”!

The sketch is released on GitHub under the GPL license: https://github.com/ayavilevich/arduino-ble-ident-n-set

The sketch:

  1. Detects the module type (currently supports HM-10 and CC41)
  2. Detects the module state, including blinking state
  3. Prints main module settings, such as name, pin, address, etc.
  4. Allows you to easily change module name or pin
  5. Allows you to change state pin behavior mode (useful for the Keyes, HM-10 module)

If you have a similar module that is not one of the supported modules, please try this sketch and share the result so I can support and improve this project.

Examples:

Initializing module and reporting main settings

Initializing module and reporting main settings

Changing module name using a menu interface

Changing module name using a menu interface

Additional resources

See these articles for more information about BLE and using BLE modules with Arduino

13 thoughts on “HM-10 or CC41-A module? Automatic Arduino BLE module identification

  1. Reply Rm Mar 4,2017 5:22 pm

    Great article, thanks for sharing!

    I just found myself with a CC41 module and immediately found the problems you describe, in particular how different the AT commands are (which don’t even meet Bolutek’s own spec)…
    A frustrating experience no doubt.

    • Reply Arik Yavilevich Mar 4,2017 6:46 pm

      Hey Rm, happy that you found the article useful. If you have any interesting findings about any special or different commands, please share them. Good luck with your project.

  2. Reply UK Mar 6,2017 10:17 am

    I am facing a problem here. When i tried to pass the AT commands through an Arduino Nano, the CC41 module is not replying back. Can you help me.
    Have you written the code for pairing two CC41 modules using arduino? Please help me.

    • Reply Arik Yavilevich Mar 6,2017 1:45 pm

      Hi UK, have you tried this sketch https://github.com/ayavilevich/arduino-ble-ident-n-set ? Try it first. If it doesn’t manage to communicate with the module please send links to a schematic of your circuit and a photo of your devices connected together. Can you connect to the module from a smartphone?
      With regard to pairing two modules, I have only used such modules as slaves and have no knowledge to share about connecting them together.

  3. Reply Arik Yavilevich Mar 9,2017 6:34 am

    Update: Recently I have ordered an HM-10 clone module on ebay that was showing the CC41 model in the pictures. When I got it, I was surprised to find out that it had a different breakout board. It still says ZS-040 on the back, but in thicker text and the (breakout) components on the front are different. A 5 pin regulator is used instead of the 3 pin. The module works ok except that the STATE pin is floating and not functional. The module has a slightly different AT-command names and identifies itself as MLT-BT05-V4.0 and MLT-BT05. Please we warned about the STATE pin and please post your experiences if differ. Identification support was added to the “arduino-ble-ident’n’set” sketch. Read more here: http://blog.yavilevich.com/2017/03/mlt-bt05-ble-module-a-clone-of-a-clone/

  4. Pingback: MLT-BT05 BLE module – a clone of a clone?? | Arik Yavilevich's blog

  5. Pingback: Fixing a bad STATE pin on an MLT-BT05 BLE module | Arik Yavilevich's blog

  6. Reply GM-1 Apr 20,2017 6:57 am

    I bought a Arduino-Android-IOS-HM-10-BLE-Bluetooth-4-0-CC2540-CC2541-Serial-Wireless-Module. i connect with my arduino uno. my android phone paired. i try to connect my blutooth app not work. AT command also not work. please help to me ebay link – http://www.ebay.com/itm/311567433651?_trksid=p2057872.m2749.l2649&ssPageName=STRK%3AMEBIDX%3AIT

  7. Reply Ag May 17,2017 3:19 pm

    Hello,

    I have read the publications you did on the HM-10 and have clarified several doubts I had. Thank you very much for the time you have spent on this and the willingness to make it public.

    According to your publication, everything seems to indicate I have a CC41-A in my hands.

    I managed to establish the communication between two CC41-A modules, each one connected to an MSP430 (TI), but if I have three modules working, I do not know how to get only the two I want communicated.

    Also, after the communication is established, how do I stop it by using commands o other software way?

    Regards
    Ag

    • Reply Arik Yavilevich May 18,2017 6:20 am

      Hi Ag,

      Glad you found the articles useful.

      Using these modules as masters is pretty challenging. There are many limits. For example you can only have one connection at any time. There are other modules, with a lower level of control, that allow for several connections. You didn’t specify what “topology” you have with three modules, but I assume one is master and the other two are slaves. It is then up to the master to disconnect from one and connect to another. To make things difficult, once you are in data mode you can’t send AT commands so you have disconnect.

      I have not used these modules as masters, so let me throw some ideas at you and hopefully you can make this work and post an update for others to learn from.

      1. Get a module with a BRK (break) pin, this should allow you to disconnect (break) the current connection.
      2. Power cycle the module, I guess you would use a transistor.
      3. Use 4 modules, where each slave will have its own master.
      4. Solder connection to the daughter board’s pin 23. It should be the disconnect pin. http://img.banggood.com/file/products/20150104013145BLE-CC41-A%20Spefication.pdf
      5. Get manual control over master/slave state through pins 27, 28. Perhaps changing master to a slave state will allow you to reconfigure it. http://wiki.yfrobot.com/ble4.0/BLE-CC41-A%E8%93%9D%E7%89%99%E6%A8%A1%E5%9D%97%E6%8A%80%E6%9C%AF%E6%89%8B%E5%86%8Cv2.1.pdf

      Good luck.

Leave a Reply