# Using cheap RF module encoding with UART in a commercial product

For my graduation project, I need to design a system that transmits several different data packets to the computer wirelessly. It needs to have a potential to be commercial product, so both functional and inexpensive. It doesn't have to be bi-directional.

I found cheap modules RFM110W and RFM210W, transmitter and receiver, respectively. Since I am trying to write whole firmware in AVR Assembly, to make it fast and easy (to not write encoding part of code), I ended up like this:

Edit: (in the picture, it is not 443 Mhz it is 433 Mhz)

With a little bit data handling, It works well at 1200 baudrate and data can be easily captured on serial monitor.

Because the UART is not for encoding RF signals, using it for encoding data seems like a little bit tricky. And I have concerns about using it in potentially commercial product.

Is it reliable for simple data transmission in the aspect of engineering?

If it's not, what are the potential problems I should be expecting to face with?

Edit:

FT232 USB to UART bridge datasheet

RFM110W Transmitter Module

Example romanblack.com

• What exactly is your concern? I would say UARTs are ubiquitous among commercial products, and is a fairly common way to transmit received RF data to another device. – DigitalNinja Oct 24 '17 at 17:47
• Edit your question with a link to the data sheets, please. – Brian Carlton Oct 24 '17 at 17:47
• I didn't know it is a common way. The modules does not have UART interface, if we are talking about same thing, it just seems like a hobbyist's trick to me. @DigitalNinja – Alnus Oct 24 '17 at 17:58
• Using the UART is popular among hobbyist because it is simple (especially for sharing ASCII data) and usually reliable when used correctly. – DigitalNinja Oct 24 '17 at 18:22
• @DigitalNinja Based on your comment, I think we are having misunderstanding here. I am not talking about UART itself, I am talking about wiring TX signal directly DATA pin on module or vice versa which has no UART, SPI or an other peripheral interface. Of course UART protocol is great for wired application (in some cases), not just an hobbyist thing. – Alnus Oct 24 '17 at 18:37

There's so far been zero information about your actual µC (microcontroller). So I'll just assume it's a super computer. If it's not then you're the one who gets to change the information so it matches.

Because the UART is not for encoding RF signals, using it for encoding data seems like a little bit tricky. And I have concerns about using it in potentially commercial product.

Using UART is alright, not the best but it works. It's like walking, rather than taking the train, to work. If anyone wonders what the train would be then it would be, for an example, 16QAM, or some other modulation.

Is it reliable for simple data transmission in the aspect of engineering?

There's absolutely zero error detection and correction happening what so ever. If you receive the value $43_{10}$ then that's the value you think was sent. If any bit changes sign during transit, which means that you got an error on one bit. Then you can't say that it has happened. That's awful. If your channel would've been a wire then it wouldn't have been as awful because the noise isn't as severe as in wireless channels.

Allow me to introduce you to error detection and correction, here's an answer on another question that contains some information as well.

First thing first, some notations and equations that will make this answer more compact.

Error correction code format = $[n,k,d]$
$\lfloor x \rfloor$ = round down x, if x = 5.43 then x = 5

$n =$ length of entire message (block length)
$k =$ message you want to send (message length)
$d =$ hamming distance (minimum number of bits that differ between two blocks)

Number of errors you can detect = $\lfloor d-1 \rfloor$
Number of error you can correct = $\lfloor \frac{d-1}{2} \rfloor$

Example: Hamming Code(3) has [7,4,3]
This means that if you want to send the information $0110_2$ then instead you will send $0110110_2$.

1 bit error:
If the receiver gets $\color{red}{1}110110$ then the receiver can convert it back into $0110$
If the receiver gets $01\color{red}{0}0110$ then the receiver can convert it back into $0110$
If the receiver gets $011011\color{red}{1}$ then the receiver can convert it back into $0110$

2 bit errors:
If the receiver gets $0\color{red}{00}0110$ then the receiver should ask for the message again
If the receiver gets $\color{red}{1}11\color{red}{1}110$ then the receiver should ask for the message again

Everyone who knows about error correction code will now be happy because I named "Hamming Code". The most famous of them all. Amusingly that's not the one I will recommend for you.

Now I know that you want an answer that "gets everything sorted", so I will attempt to do that, but I want you to know that there are many things that I'm not covering.

I assume you will send bits of 8 at a time, the hamming code is not "nice" in the sense that you will only use 7 bits out of 8, losing a whole bit's worth of information. So instead I advice you to use punctured hadamard code.

It's parameters have the following properties: [$2^{k},k+1,2^{k-1}$], it's base 2! Great. So let's set n equal to 8, a whole byte, and see what the d and k becomes.

$n = 2^{k} = 8 \rightarrow k = 3 \rightarrow d = 4$, so the actual parameters we will be using are [8,4,4]. This means that we can detect 3 errors and correct 1 error. And we will also send twice the number of bits for every bit we actually want, so we will still send things in 1500 bps, but our actual data that we want to send and read will be going at 750 bps. But we will be able to detect some errors and correct one error. I call worth (you can increase the 750 bps by compressing the data first.. like zip files does. But that's an entirely other question).

Alright, so how are these codes made? by generator matrices which will be in modulus 2. So by sending data we multiply our 4 bit data with a generator matrix that will turn it into 8 bits. On the receiving end we multiply by a parity matrix that will give us all 0's if it's a perfect block. If there's any error then we will see some 1's somewhere. You might be wondering how you will have the time to multiply matrices on the fly, and my answer to that is that you use a LUT (Look Up Table).

So the parity matrix for punctured Hadamard code looks like the following for $k = 3$

$$\begin{pmatrix} 1 & 0 & 0 & 0 \\ 1 & 0 & 0 & 1 \\ 1 & 0 & 1 & 0 \\ 1 & 0 & 1 & 1 \\ 1 & 1 & 0 & 0 \\ 1 & 1 & 0 & 1 \\ 1 & 1 & 1 & 0 \\ 1 & 1 & 1 & 1 \\ \end{pmatrix}$$

As you can see it's just the regular bits for counting 0 to 7 and an extra column filled with 1's.

And the generator matrix will be the parity matrix transposed (this is not normal for block codes), the Hadamard code is special in the way it's generator matrix and parity matrix are missing the identity matrix. So I'm not sure but I think Hadamard code is one of the few (or maybe the only one?) where the generator matrix = parity matrix transposed.

So here's the generator matrix for clarity:

$$\begin{pmatrix} 1 & 1 & 1 & 1 & 1 & 1 & 1 & 1 \\ 0 & 0 & 0 & 0 & 1 & 1 & 1 & 1 \\ 0 & 0 & 1 & 1 & 0 & 0 & 1 & 1 \\ 0 & 1 & 0 & 1 & 0 & 1 & 0 & 1 \\ \end{pmatrix}$$

So let's simulate what you will actually be doing, this way you can read this answer several times and eventually it will hit home, I hope.

On wikipedia they use $w = sG$ where I assume w is the codeword, aka block, s is the message to be sent and G is the Generator matrix.

So say you want to transmit the bits $0101_2$, then you would simply perform this multiplication:

$$\tiny{ \begin{pmatrix} 0 & 1 & 0 & 1 \\ \end{pmatrix} × \begin{pmatrix} 1 & 1 & 1 & 1 & 1 & 1 & 1 & 1 \\ 0 & 0 & 0 & 0 & 1 & 1 & 1 & 1 \\ 0 & 0 & 1 & 1 & 0 & 0 & 1 & 1 \\ 0 & 1 & 0 & 1 & 0 & 1 & 0 & 1 \\ \end{pmatrix} = \begin{pmatrix} 0 & 1 & 0 & 1 & 1 & 0 & 1 & 0 \\ \end{pmatrix} }$$

As you can see, it's an XOR operation, aka mod 2, so 1+1 = 0, 1+0 = 1 and 1×1 = 1, 1×0 = 0. Or, you could store it in a LUT, it's just 16 possible outputs, and they are all 8 bits wide.

Then on the receiving end you just perform the multiplication by the parity matrix. Or you use a LUT, which I advice you to do if you are using a µC. If you had an FPGA then you could just calculate it in parallel. The LUT would take up 256 bytes of ram, one index for every possible combination, and inside of the registers you would say what the bits actually meant, and those that have 1 error you would convert to the correct bits in the LUT, by hand.

You can either do that for all the bits, just use a LUT and be fine with that, or maybe you want to check first if there is anything wrong with the bits, and then use the LUT.

So let's change one bit of the transmitted message to represent an error on a bit, it doesn't matter if I change a 1 to 0 or a 0 to a 1, a change is a change in XOR-world.

So say we send this:

$$\begin{pmatrix} 0 & 1 & 0 & 1 & 1 & 0 & 1 & 0 \\ \end{pmatrix}$$

$$\begin{pmatrix} 0 & 1 & 0 & 1 & \color{red}{0} & 0 & 1 & 0 \\ \end{pmatrix}$$

Let's see what happens when we multiply it with the Parity Matrix.

$$\tiny{ \begin{pmatrix} 0 & 1 & 0 & 1 & 0 & 0 & 1 & 0 \\ \end{pmatrix} × \begin{pmatrix} 1 & 0 & 0 & 0 \\ 1 & 0 & 0 & 1 \\ 1 & 0 & 1 & 0 \\ 1 & 0 & 1 & 1 \\ 1 & 1 & 0 & 0 \\ 1 & 1 & 0 & 1 \\ 1 & 1 & 1 & 0 \\ 1 & 1 & 1 & 1 \\ \end{pmatrix} = \begin{pmatrix} \color{red}{1} & \color{red}{1} & \color{green}{0} & \color{green}{0} \\ \end{pmatrix} }$$

Had there been no errors then it would've been $\color{green}{0000}_2$. But since there were some error we got some 1's. So if we would've received all 0's => those 4 bits are good, otherwise use LUT. Hmm, now when I'm thinking about it, if you are using a µC then you always want to use a LUT, calculating this multiplication with the parity matrix is way too expensive time-wise. But on an FPGA or some other hardware.. it would've been cheaper memory-wise and faster time-wise.

I think I should stop this answer here, it should get you sorted. If there's anything you're unsure about, write a comment and I will update this answer.

The main issue with UART in radio is the crappy error detection. UART only synchronizes once per data byte: it expects a start bit, then 8 data bits, then one or two stop bits. If the stop bit is where it should be in relation to the start bit, the UART is happy. If not, you get framing errors by the UART hardware.

But the UART does not check if every bit in between start and stop is of the correct length. This means that UART hardware is poor at detecting bit errors. Because of this, various low quality detection schemes have been invented over the years, such as "parity bit". But simple probability theory proves "parity" to be amateur nonsense - a parity bit cannot per definition have a better error detection than 50/50, because there could be bit errors in the parity bit itself. And of course elsewhere in the data too.

Upon realizing that parity is nonsense, people then started to include data constants as part of the data protocol. Which increases overhead and will, again, prove to be horrible by probability theory.

The only semi-professional UART solution is to put a CRC in the higher level protocol. This improves error detection a lot, but CRC will still struggle to find double bit errors or worse. Radio errors are most likely of a burst error nature. A UART protocol with CRC will never be 100% reliable.

What can be done instead, is to use various forms of modulation and digital encoding that enables the receiver to measure each bit length and place error detection closer to the hardware.

What you probably want as a student, is to pick a radio module which handles this for you. Then you can communicate with it over UART, SPI, I2C etc and the radio module will translate it to a modulated signal and handle the data packets over the air.

• I did try very hard to find the inexpensive module that handles all this processes. I found some transceiver modules that are expensive (to me), hard to implement or hard to access. Example; RFM12BW from HopeRF. But unfortunately I couldn't find it at Digikey and didn't get any e-mail response from HopeRF. I cannot get this module from rf-solutions.co.uk in place where I live(Turkey) because £2.61 module itself and £94.30 shipping + £19.38 VAT, £116.29 Total. I have inspect so many modules, most of them result with this. I am really open the suggestion of the affordable and accessible modules – Alnus Oct 26 '17 at 17:00
• @Archaeon Moment of realization: you get what you pay for. Although £2.61 for a working 433MHz transceiver with everything on board is cheap, depending on RF characteristics quality. Anyway, shopping recommendations are unfortunately considered off-topic on this site. – Lundin Oct 27 '17 at 7:02
• Because of working frequency (sub-GHz) or quality of IC that is used? – Alnus Oct 27 '17 at 14:12
• @Archaeon Quality of the IC. You can get fairly high quality sub-GHz radio ICs nowadays from a number of manufacturers. I haven't used HopeRF, but they have some parts that look decent at least on paper. (From what I've heard from colleagues, their customer support is however non-existent.) – Lundin Oct 27 '17 at 14:22
• I see. I have already experienced that non-existent customer support, you are right. But I think they use Silicon Labs's or Nordic Semi's ICs because datasheets of their products are about %90 copy-pasted. – Alnus Oct 27 '17 at 14:53