Site menu Arduino on air
e-mail icon
Site menu

Arduino on air

e-mail icon

2014.09.03

This article expresses the author's opinion at the time of writing. There are no guarantees of correctness, originality or current relevance. Copying the whole article is forbidden. Transcription of selected parts is allowed provided that author and this source are mentioned.

The dream of playing with radio (amateur or pirate) is still in the queue but an appetizer has arrived in order to quench the hunger for a while: a small 433Mhz radio module for Arduino.

The simplest kit with transmitter and receiver, that I bought, costs less than US$ 3. It just sends an on/off signal over the air, and you must calculate, build and solder the antenna yourself.

There are better kits, not that expensive (US$ 12), antenna included and they take care of all encoding-related challenges, delivering perfect, shrink-wrapped messages end-to-end. But then, there would be no fun :)

Such UHF-band radios can handle obstacles like walls, they are perceived as having "more range" due to this. For the same reason, some countries want to deploy 4G cell phone over 700MHz. Big countries like Australia and Brazil can use the extended range to deliver 4G connectivity to rural areas, etc.

My intrinsic objective of using radios with Arduino is to move my weather station to a better spot, outdoors but sheltered and in a shadow, for better readings. Keeping this naked boards off any other sensitive equipments is always a good idea, too.

And the extrinsic objective, as said before, is to feed the "radio bug" that, like photography, bites every nerd. That marvelous thing: it does not work and you don't have many direct means to discover in which of the 10 possible points of failure is the actual problem.

The transmitter (TX) simply turns "on" and "off" and is controlled like a blinking LED, with digitalWrite(). The receiver (RX) can be read with analogRead() or digitalRead(). Quite simple, right? And almost useless, because RX always gets a lot of noise. You can't even blink a LED remotely with confidence, unless you put the antennas right next each other (coupled by the near field).

How to overcome this problem? With software, that's how. It is a must to adopt and implement some digital modulation technique. The only thing to help us is the Arduino speed, so we can take samples from the radio in really high rates. Being a microcontroller, we can put Arduino to work 100% without worries.

RX module seems to have AGC (automatic gain control), so the received signal tends to zero right after TX goes off, and after a short while the noise begins to act up. I noted that because I fixed a software error that was turning on the TX for no good reason (it was an obsolete code that blinked a LED), and then the reception became much difficult.

Actually, this is the big problem of digital modulation: by reading a channel with only two possible values (0 and 1), you need to distinguish three states (0, 1 and "nil") and also discover where each bit begins, having only the bits themselves as clock.

At this point, I took a shortcut and adopted the VirtualWire library. It implements the transmission of reliable messages in a simple and clever way. It could be much more sophisticated (e.g. with error correction) but this shortcut was very welcome: being able to send data in a stage that you didn't even know if the modules were working at all, is priceless.

Yes, some day I will try to implement my own encoding scheme, possibly using more advanced techniques like FEC, encoding bits using DSSS (the poor cousin of CDMA).

As a bonus, VirtualWire uses interruptions instead of polling, both at TX and RX sides. That is, it does not "eat" 100% of CPU, so other activities can be run in parallel within the same microcontroller.

VirtualWire allows precise configuration of baud rate. Interestingly, a higher baud rate like 1200bps seems to work better than a very low one like 50bps. The simplicity of encoding shows its weakness here: a lower baud rate takes more time to send the message and allows more noise to stick around. A robust digital codec would keep the chirp rate at an optimal level regardless of bps.

The other problem, already mentioned, is that sending infrequently leads to bad reception, in spite of VirtualWire doing the homework and adding long preambles with each message in order to train the RX side. The solution I found is to send all the time, continuously, the same message. Brute-force error correction :)

Even if reception is very bad, sometimes it will break through. In my case, it is enough if it happens once very several minutes. With this advantage, I could move the RX board to a hidden spot, near a structural wall, that I already knew to be the worst possible place. And still it works.

In my use case, the scheme just needs to cross one concrete wall. TX is not that powerful, even though it can be fed up to 12V (more than twice the typical 5V). My antenna is a simple flexible wire, so there's a lot of room for improvement in that aspect, too.

e-mail icon