Electronic – arduino – Best way to send sensor readings over simple RF connection

arduinoattinyRFwireless

I have bought a pair of simple 315MHz TX/RX modules. I want to use these to connect a battery powered ATTiny85 to an Arduino base station. The ATTiny needs to regularly wake up and send a sensor reading to the base station.

In theory I should be able to simply write data to the TX and read it from the RX module. However, how do I ensure that I write/read at the correct rate? What code do I need to use to transmit at a particular speed (bytes/second)? What is the best way of doing error correction/detection?

Since I want the transmitter to be battery powered could I use a transistor to turn off VCC to the TX module when idle. What will the RX module receive when the TX module is powered down?

Best Answer

Those modules basically make the receiver pin wiggle in response to how you drive the transmitter pin. They know nothing about what you think wiggling the pin means, and don't contain a UART. More details weren't immediately obvious without digging. That's your job, so I didn't bother to go further. You should provide a link to the datasheet, not the product splash page.

These modules work on AM modulation. The short writeup says ASK, but it's probably just on/off keying of the transmitter (which is technically a subset of ASK). The problem with this scheme is that the receiver can't inherently know the level for when the transmitter is on. It therefore most likely looks at recent received signal strengths and picks a value in the middle to decide between on and off. This is called data slicing.

If you are not regularly transmitting ons and offs, the receiver looses track of what levels on and off are, and can no longer data slice correctly. This is usually dealt with in two ways. First, a preamble is sent. This contains a bunch of ons and offs in rapid succession so that the receiver can settle on a good data slicer threshold. It is expected that some or all of these bits are not correctly interpreted by the receiver, so are therefore not really "received". The second strategy is to send data so that there is always a recent on and off for the receiver to refer to. Some receivers, particularly cheap ones that do the data slicing in analog, just slice about the low pass filtered average received signal strength. For such receivers, you not only need to vary between on and off frequently, but the average needs to be close to 1/2 on.

This is why manchester encoding is so popular for such RF links. I won't go into manchester encoding here since this is well known and you will have no problem finding lots of information on it out there. One nice feature of manchester code is that it averages to 1/2 on over each bit. A bit is divided into two halves. On-off may mean 1 and off-on 0. Manchester is probably the best easiest to do encoding scheme.

You can use a UART, but you have to be careful and you will give up some bandwidth (battery power). Look at what a UART will transmit. If you send the characters immediately following each other, then each one will take 10 bit times. There will be a start bit, 8 data bits, and a stop bit. The start and stop bit are always opposite polarity. You can arrange to use codes in the remaining 8 bits that have a equal number of 0s and 1s to keep the data slicer threshold in the middle. This means you only get to send 4 bits of information in each UART character. You'll also have to think about the preamble carefully.

In general, you should assume any one RF transmission has a significant chance of bit errors. This means some kind of checksum is a good idea. You can send data in packets, and include something like a 16 or 20 bit CRC checksum with each packet. If the packet is not received intact, then it is discarded like it never happened.

The system also has to deal with the random noise received when the transmitter is powered down. In that case the receiver threshold will drop and it will start data slicing whatever random noise it picks up. With a properly designed preamble and checksum, you can make the chance of random noise looking like valid data vanishingly small.