1

I'm playing with two HC-12 wireless communication modules. After setting AT+FU4, I tested the modules, but the communication appeared to be unreliable in one direction. I tried to simplify the code as much as possible, and here's what I got:

First board

The first board sends to HC-12 everything it can read from the serial. When it receives something back, it sends it to the serial.

#include <Arduino.h>

constexpr int8_t HC12TxPin { 0 }; constexpr int8_t HC12RxPin { 1 }; HardwareSerial HC12 { 1 };

void setup() { Serial.begin(115200); HC12.begin(1200, SERIAL_8N1, HC12RxPin, HC12TxPin); }

void writeBinary(Stream &stream, const byte b) { for (int8_t i = 7; i >= 0; --i) { stream.write(bitRead(b, i) ? '1' : '0'); } }

void send() { const auto byte = Serial.read(); if (byte != -1) { HC12.write(byte); HC12.flush(); Serial.print(F("Sending ")); Serial.write(byte); Serial.print(F(": ")); writeBinary(Serial, byte); Serial.print(F(" = ")); Serial.println(byte); Serial.flush(); } }

void receive() { const auto byte = HC12.read(); if (byte != -1) { Serial.print(F("Received : ")); writeBinary(Serial, byte); Serial.print(F(" = ")); Serial.println(byte); Serial.flush(); } }

void loop() { send(); receive(); }

Second board

The second board simply sends back everything it receives from the first device. It also displays to serial what it received.

#include <Arduino.h>
#include <SoftwareSerial.h>

SoftwareSerial HC12(10, 12);

void setup() { Serial.begin(115200); HC12.begin(1200); }

void loop() { const auto byte = HC12.read(); if (byte != -1) { HC12.write(byte); HC12.flush(); Serial.println(byte); Serial.flush(); } }

Execution

When I start both boards and send “Hello, World!” to the serial port of the first board, this is what I see:

First board:

---- Opened the serial port /dev/ttyUSB0 ----
17:53:00:476 ---- Sent utf8 encoded message: "Hello, World!" ----
17:53:00:488 -> Sending H: 01001000 = 72
17:53:00:499 -> Sending e: 01100101 = 101
17:53:00:511 -> Sending l: 01101100 = 108
17:53:00:520 -> Sending l: 01101100 = 108
17:53:00:531 -> Sending o: 01101111 = 111
17:53:00:542 -> Sending ,: 00101100 = 44
17:53:00:552 -> Sending  : 00100000 = 32
17:53:00:563 -> Sending W: 01010111 = 87
17:53:00:574 -> Sending o: 01101111 = 111
17:53:00:584 -> Sending r: 01110010 = 114
17:53:00:595 -> Sending l: 01101100 = 108
17:53:00:606 -> Sending d: 01100100 = 100
17:53:00:616 -> Sending !: 00100001 = 33
17:53:03:202 -> Received : 01001000 = 72
17:53:03:210 -> Received : 10110001 = 177
17:53:03:219 -> Received : 10110001 = 177
17:53:03:227 -> Received : 10111101 = 189
17:53:03:235 -> Received : 00000010 = 2
17:53:03:244 -> Received : 10111010 = 186
17:53:03:252 -> Received : 00100101 = 37
17:53:03:260 -> Received : 01000101 = 69
17:53:03:269 -> Received : 11111100 = 252

Second board:

---- Opened the serial port /dev/ttyUSB1 ----
17:53:01:811 -> 72
17:53:01:835 -> 177
17:53:01:859 -> 177
17:53:01:875 -> 189
17:53:01:892 -> 2
17:53:01:901 -> 186
17:53:01:910 -> 37
17:53:01:918 -> 69
17:53:01:927 -> 252

The very first byte, 72, is received correctly. But then, everything else seems to be mangled.

At first, I thought that this is just related to radio noise or some random information loss, but there is nothing random, actually. In fact, every time I do the test, I get the exact same data being received by the second device. The 1.3 s. delay between the moment the first byte is sent by the first board, and received by the second, also seems constant.

Comparing binary data, it looks like some bits were missing, but it's a guess—and doesn't actually make sense considering I can't find an exact match towards the end:

sent:     01001000011001010110110001101100011011110010110000100000010101110110111101110010011011000110010000100001
received: 01001000          10110001101100011011110         10000001010111010001001010100010111111100
                            (maybe here?)                   (maybe here?)   ↑ definitively something wrong!

What is happening here?

Arseni Mourzenko
  • 246
  • 1
  • 3
  • 11

1 Answers1

2

The library "SoftwareSerial" is not able to communicate in full-duplex.

After the first received byte your sketch on the second board starts to send. During the transmission time the second board cannot receive anything.

Therefore, it starts receiving again after the transmission finished, and consequently synchronizes on any bit with the value 0, as this marks the start bit.

This is the reason that some bytes are lost and the others are "garbage".


Side note: Your analysis of the bit stream is a good approach, but you missed some facts. Asynchronous serial communication has start bits, stop bits, and transfers the least significant bit first.

If you repeat the analysis with the correct bit stream, you will be able to reproduce this behavior.

the busybee
  • 2,408
  • 9
  • 18