Understanding and Implementing the HC-12 Wireless Transceiver Module

Thread Starter

Witold Markowski

Joined Aug 8, 2018
Since some time I'm experimenting with HC-12 wireless transceiver.

My test environment has two Arduinos with HC-12 connected by a software serial. On HC-12 I'm using a default configuration which has:
  • 9600 bps as data speed of serial port
  • 15000 bps as data speed over the air

My simple test scenario is as below:
  • Arduino number A sends a 7B ping packet to Arduino number B
  • Arduino B receives that ping packet and sends ACK packet (acknowledgment) - which is also 7B - back to Arduino A
  • Arduino A receives the ACK packet
  • The whole round-trip of packets takes around 97ms. I was a bit surprised why it takes so long. Then I have found this article by @ Mark Hughes Thanks Mark! After reading it I understood that HC-12 uses Si4463 under the hood. When I took a look at its datasheet, I think now I know why the round trip takes so long :)

Si4463 sends data over the air as packets. It looks like HC-12 need to collects (on the serial port) some amount of bytes, then send them to Si4463, which sends them over the air as a packet.
Here is how it may looks like in my test scenario:
  • Arduino A sends 7B to serial port with data rate 9600 bps. It takes around 8ms (including start and stop bits for every byte).
  • HC-12 collects the data on its serial port. Ir receives 7B and after some time (like a timeout) it finds out that no more data will be sent over serial port. HC-12 sends the data to Si4463.
  • Si4463 sends the 7B as a packet. This packet's length is probably more than 7B (there is a preamble, CRC, and some other things). Lets assume that it has 15B of length. With 15000 bps, the transmission is roughly about 8ms.
  • HC-12 (attached to Arduino number B) receives the packet and shifts it to itd serial port with 9600 bps. It takes again around 8ms.
So the transmission takes roughly around 25ms but I didn't take any additional processing (like settling up the transmitter and so on). Every piece (including both Arduinos) puts some additional time to the transmission. In my case the trip from Arduino A to Arduino B takes around 50ms.

@ Mark Hughes , if you do not mind I created this thread with the same title as your article (mentioned above). If you do not agree, please let me know and I will change it.
@Mark Hughes, in your article you put an image:

where you send allaboutcircuits.com over HC-12. You have noticed that there is a gap (or a delay) before .com has been sent. I think this is because of the way how Si4463 sends data: it sends them in packets. Probably HC-12 is designed in the way, that every 16 characters (that are sent over serial port) are sent to Si4463 as a packet. Just count the number of characters in allaboutcircuits - it is 16. Then HC-12 receives the last part of text .com but default packet size for HC-12 is 16. HC-12 waits a bit for more data to read from serial port. But after some time (like a timeout) it notices, that no more data is sent through serial port. HC-12 decides that current transmission over serial port is over and send the last part to Si4463. This could be the explanation of the delay, that you have noticed. I think this delay can be read from your picture, but I need to take a closer look at this.

Mark - what do you think of this?

Mark Hughes

Joined Jun 14, 2016
@Witold Markowski ,
Thanks for creating the thread! So if I understand you correctly, you're trying to get to the heart of the round-trip delay? It seems that you've discovered that the module does som "under-the-hood" stuff that is affecting your project?
You're right that the module is made of the Si4463 transceiver -- there is also an STM8S003FS Microcontroller on board. It's been a while, but I seem to remember that one of those datasheets showed the buffer min/max levels (likely the Si4463). The module will sit and wait until a certain number of characters have been sent, or a certain amount of time has passed before sending out an underfilled buffer.
If speed is what you want -- fill the buffer to force transmission. Instead of sending your 7B packet, send 7B followed by however many nonsense characters are required to force transmission. On the receive side, throw the nonsense transmission out.

@ericgibbs @Raymond Genovese

Thread Starter

Witold Markowski

Joined Aug 8, 2018
I thought that the round trip will take much less time. I thought that first byte sent to serial port (with speed 9600 bps) will be sent automatically over the air with speed 15000 bps and will be available at the serial port on the receiver side. It doesn't work like that. Now I know that it is more like a pipeline of various transmissions (because HC12 has SI4463 and STM8S003FS on board). So the pipeline in my case is as below:
  • transmitter Arduino sends data to serial port with speed 9600 bps
  • STM8S003FS receives the data from serial port. If the number of bytes sent is enough to create a data packet for SI4463, then the data packet is sent at once. When the number of bytes sent by transmitter Arduino is less that a specific amount, then STM8S003FS waits for some milliseconds timeout and after that creates a data packet to SI4463
  • STM8S003FS send data packet to SI4463
  • SI4463 sends the data packet over the air with speed 15000 bps to a receiver SI4463
  • STM8S003FS on the receiver side gets the data packet from its SI4463 and sends it to receiver Arduino over serial port with speed 9600 bps
Actually the one way trip takes:
  • sending N bytes over serial port with speed 9600 bps (transmitter side)
  • sending a data packet (which is probably more than N bytes) over the air with speed 15000 bps
  • sending N bytes over serial port with speed 9600 bps (receiver side)
  • additional delays because both STM8S003FS and SI4463 need some time to process data
@Mark Hughes, I have retested your proposed solution to send some additional bogus data to force the transmission but it doesn't really help. The trip takes longer. Probably the time needed to send that bogus data twice over the serial port (once on the transmitter and once on the receiver) is longer than this timeout that STM8S003FS is waiting to find out that there will be no more data to sent.

I think - for now - I can live with this long data sending time.

Mark Hughes

Joined Jun 14, 2016
Sorry @Witold Markowski, it's been quite a while since I read those datasheets. What sort of project are you working on? Also -- in cases like these, I always try to bring @ericgibbs into the conversation. He's more familiar with these modules than I am -- he in fact suggested them to me.

What's your application/goal? Maybe someone here can recommend a way to achieve it.



Joined Jan 29, 2010
hi WM,
I also would like to know your application in using the HC12.
When using an ACK loop there are bound to be delays in the TX/RX loop.
What delay period would be acceptable.?

Thread Starter

Witold Markowski

Joined Aug 8, 2018
Basically I want to build a Home Automation System. I think I will use openHAB and a messaging system from MySensors.

My flat is on the 3rd floor and I have a small storage cell located in the basement of the building. The basement is located at floor -1 and I would like to plug this in home automation system as well.
Basically it will be wireless system. In my flat I want to use nRF24L01 chips but they have to small range to get access to the storage located in the basement, so I started to experiment with HC-12 which gives me quite good results.

Some time ago I have started to implement an experimental library that will provide a mesh topology for the sensors. It uses flooding mechanism to deliver packets between nodes (I know about pros and cons of this mechanism). For now two devices are supported: nRF24L01 and HC-12 but the abstraction layer allows to add support for other devices as well (I hope).

For test purposes I have prepared a ping functionality, to check if messages can be delivered. So far it works good but the long ACK loop of HC-12 can be a bottle neck in the system, especially when we want to have ACK that the packet has been delivered. In the system where we have more nodes, we can have a packet collision, because the transmission is not synchronized so well. The faster a packet is sent over the air, then the probability of collisions is lower.

However, in my solution HC-12 sends the data over the air with 15kps, so it may be not so bad. It just requires more real-life scenarios and tests to see how it will work. I'm not yet prepared for those tests - everything goes a bit slowly because I can not give a 100% of my free time to this project :)

Mark Hughes

Joined Jun 14, 2016
@Witold Markowski ,
That's no small project. Let me know when you're done with it and I'll ask the editors if it's something we can publish on the frontpage of the site. If not -- definitely put it in the forums.
On a side note -- do you have any plans for automated shades? I looked into it some time ago and they seemed quite expensive. I'm curious if they are at all affordable now.
Have a great week!