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

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

34 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.

  8. Reply Nabil May 24,2017 4:38 pm

    hi,

    i tried to change pin via AT+PIN4529 but it respond back ERR

    could you help me ? Thanks

  9. Reply Orbitatronics Jun 19,2017 3:15 pm

    Thanks for the brilliant article.

    I’m making a board that’s essentially a teensy 3.2 reference board with a host of other components; i have a very small area for a feature i want to add that is on-board BLE.

    I know there are some decent nordic ICs about but i only have about 2cm^2 of free space.

    My question is, do you think it’ll be semi-trivial to take the reference CC2541 design with parts of the breakout board, and add it to my custom board, or will i need to upload difficult-to-find firmware to the CC2541?

    I’m open to any suggestions,

    Thanks again!

    • Reply Arik Yavilevich Jun 19,2017 4:49 pm

      Hi Ben,

      A Teensy 3.2 board should be 3.3V, so you don’t really need the logic that is usually found on the breakout board.
      Designing good RF circuits is difficult. There are grounding issues, etc. You should avoid designing your own unless you are into RF.
      I suggest you take an HM-10 or HM-11 (even smaller, less gpio) module without the breakout board and solder it to a place on your board. See the documentation about the recommended placement so the antenna is in an optimal location. Sometimes it has to be “in the air” and sometime on a certain edge.
      These “open stamp” form factor modules are designed for this purpose exactly. Search Google images for HM-11 and you will see examples.
      With regards to firmware, I have not tried it but, there are articles showing how to flash new firmware to the CC2541 chip, including flashing original HM-10 firmware to the CC41. For example, see https://forum.arduino.cc/index.php?topic=393655.0 . Doesn’t look too difficult.

      Good luck with your project.

      • Reply Orbitatronics Jun 19,2017 4:58 pm

        Thank you for getting back to me. I have indeed been eyeing up the HM-11 but it’s just a tad too big. I may go for it though by making the board bigger, will be be trivial to pull out break/state/enable pins to the teensy from the HM-11?

        Also, do you have any opinions on the Simblee RFD77101 and/or the laird BL652 series modules? The latter especially isn’t THAT much more than the HM boards, but i bet they’re in a different league, maybe overkill for my project.

        Thanks.

        • Reply Arik Yavilevich Jun 19,2017 7:03 pm

          Hi Ben,

          As far as I can see, the HM-11 is 18*13.5*2.2mm which is under 2cm^2.
          The function of the pins will depend on the firmware. The pin layout can be seen in the spec: http://fab.cba.mit.edu/classes/863.15/doc/tutorials/programming/bluetooth/bluetooth40_en.pdf

          I have no experience with the other modules you have mentioned. They do seem to be more serious. They have FCC and CE certifications which might be desirable for your project.

          • Reply Orbitatronics Jun 19,2017 7:16 pm

            Hi Arik,

            After some thought i decided to put the BL652 on hold, opting for the HM-11; i don’t know how i’ll fit this (and a micro vibrating motor) on the remainder of this board, but when there’s a will there’s a way.

            I’ll aim to get the antenna handing off the top side.

            I have been looking through documentation and pinouts, but i was hoping you could point me in the right direction with going about setting up inputs to the hm-11 for break/state/enable. I can see the pinout in the document you linked, but it’s not clear which pins correlate to what, is this all determined by firmware?

          • Reply Arik Yavilevich Jun 19,2017 7:32 pm

            Hi Ben,

            Challenges are fun, right? 😉

            Most of the pins are GPIO, so they depend on the firmware. Could vary between the different clones. Usually PIO0 is “key” which can function as “break”, PIO1 is “LED” which can represent “state” and be visual indicator and PIO2 is pure logical “state”. I believe “enable” is a feature of the breakout board, and just cuts the power to the module. I have never used it.

          • Reply Orbitatronics Jun 19,2017 7:46 pm

            Thanks, i’m just matching up the pinouts from a schematic in your article about the clone of a clone here to the schematic in the document you provided on page 10. Sadly the pin numbers do differ a tad but i think it should all be ok, i might just go crazy and pull all the GPIOs of the HM-11 to GPIOs of the uC as a safety, maybe with solder jumpers in front of each.

            I thought about using enable to totally kill the BT module to save power, as this is a battery powered project (teensy’s not the best choice but i had written the complex firmware last year, don’t want to look at it again let alone port it to some other architecture :p )

            One question i had about the schematic i linked above from your other article; at P0_6 there is a switch to toggle the HM-11 between master and slave. I’ll attach this to a GPIO to be safe but if i just had say two HM-11 modules (or two HM-10’s), and i wanted to send and receive data between the two, would i need to change between master or slave? Or should i just set slave for both?

            Thank you for all of your advice and help so far!

          • Reply Orbitatronics Jun 19,2017 8:15 pm

            I’ve got something like this, hopefully it works :p

          • Reply Arik Yavilevich Jun 20,2017 4:59 am

            Hi Ben,

            Actually, connecting all the pins to the uC can be a good idea. I suggest you also make sure you have access to the pins needed to program the CC2541. This way you can later write a different firmware but still use all the pins.
            If you want to kill all the power you will probably need to add a FET of some sort. Or you can keep the BLE module in sleep state and wake it with AT commands or GPIO signal.
            With regard to slave/master mode. Even though some modules allow this to be set through a pin, this state can be set by an AT command, so the usefulness of the pin is limited.
            If you want to have communication between two BLE devices one would have to be a master. Perhaps you should get two modules in their breakout form and play with them a bit before you commit to this design. BLE is good for communicating to a phone or some base station device, but is not the best option, for example, for mesh network. So the right choice will depend on your intended use.

          • Reply Orbitatronics Jun 20,2017 2:22 pm

            Hi Arik,

            Thank you so much for your help and advice. I’ve taken all of it on board as i now have all the pins pulled out. I don’t think the HM-11 can be set master/slave by a pin anyway so i will rely on the AT command (i’m assuming they’ll be similar, i’ll definitely use your ID code and let you know).

            Also you make a good point, my space now is ridiculously limited so i’ll rely on the sleep commands instead of a FET to turn the module off.

            I’ve somehow managed to fit everything onto the board!

            My intended use for BT in this project is simple: I have teensy that processes sensor data. i have 1 FSLP sensor breaken out wirelessly sending filtered data. i want bluetooth to be the protocol. So I assume i need to set the teensy side BT as master and the breakout side as slave, (breakout will probably just use a cloned HM-10). I don’t think this is particularly complex, would you say i’ve chosen the wrong architecture/setup for this intended purpose?

            The board will look something like this, i think the very bottom of the ant is covered by the mother board but the majority of the ant is ‘in the air’.

            board

          • Reply Arik Yavilevich Jun 21,2017 6:07 am

            Hi Ben,

            Nice PCB design work.

            If I follow you correctly, you are going to have 2 FSLP sensors on the board directly and an additional one which is wireless. The wireless one will be connected to another uC and an HM-11/10 in slave role. The main board, which is BLE master, will then pull data from the wireless unit. Sounds doable. I have not tried something like this myself yet, but I don’t see a reason why it shouldn’t work.

            Thanks for sharing, let us know how it works.

          • Reply Orbitatronics Jun 21,2017 8:15 pm

            Thanks.

            Yes you got the design down perfect. I’ll let you know how it goes.

            Do you know how one can go about setting up a bluetooth HID, so i could ‘create’ a hid device (say keyboard or bluetooth) and have it show up as a hid device on a phone (via bluetooth)? I’m not sure what this requires.

          • Reply Arik Yavilevich Jun 22,2017 12:59 pm

            Hi Ben,

            Yes, BT HID is based on the “older” BT, not BLE. So you can do with something simpler.
            A cheap way to do this is to hack an HC-05. See https://www.youtube.com/watch?v=BBqsVKMYz1I
            But there are dedicated modules for this, such as:
            BlueSMiRF HID – https://www.sparkfun.com/products/retired/10938
            Bluefruit EZ-Key HID – https://www.adafruit.com/product/1535
            It seems it is also possible to reprogram the CC2541 : https://github.com/rampadc/cc254x-hidKbdM but not sure if there is a good firmware available. Didn’t try it.

          • Reply Orbitatronics Jun 22,2017 4:57 pm

            Hi Arik,

            That was very interesting. I researched the two dedicated HID devices and found they’re a bit clunky on android, likely due to their age and stack architecture. There must be newer alternatives, but that HC05 mod looks very nice. I have one of those modules, i’ll see if i can use an ftdi to write the RL52 firmware onto it.

            Thanks a lot for the links!

          • Reply Orbitatronics Jun 22,2017 11:03 pm

            I have spoken to a guy at sparkfun, he suggested i can use a bluetooth module as a simple uart passthrough if i already have usb HID output, and have bluetooth HID that way. (I do already have usb hid setup as i have a teensy setup as a mouse). If that’s possible then that’d be brilliant, does this make sense to you ?

          • Reply Arik Yavilevich Jun 23,2017 1:11 pm

            Hi Ben,

            Yeah, that makes sense and should work but it won’t show on your phone as Bluetooth HID. It will be a USB HID and you will have to plug it in the USB OTG port of the phone. Right?
            So it’s more like a DIY USB wireless keyboard/mouse. With BT for the wireless part (internally).

          • Reply Orbitatronics Jun 23,2017 1:31 pm

            so the idea was to remove all that double hm11 stuff, and just have 1 board with 1 bt module (atm not decided but i have a board being fabbed with a hm11 footprint), and have an existing setup where usb hid data is talking to a phone via otg, have that wire removed, by ‘passing through’ the usb hid data to the bt module.

            Makes sense?

          • Reply Arik Yavilevich Jun 23,2017 1:47 pm

            Hey Ben,

            No. 🙁 I don’t follow you on this one.
            Got an account at hackaday? My account page is at https://hackaday.io/ayavilevich . Happy to take this topic to the chat, it is no longer on topic for this post.

  10. Pingback: Fochica™ – Forgotten Child in Car Alert | Arik Yavilevich's blog

Leave a Reply