Sunday, January 26, 2014

434Mhz RF Transmitter/Receiver with the Arduino Micro

I wanted to experiment with the RF Link transmitter/receiver for my wireless projects. With the temperature around here going from below 0 to 60 degrees, a wireless temperature sensor would be nice! The project is to get data from an analog temperature sensor and use an RF link to transmit the data to a receiving device.

The Parts List:

Temperature Sensor and RF Transmitter:
Arduino Micro Board  ($22.95) 

RF Receiver side data collection and processing:
RF Link Receiver - 4800bps (434MHz) ($4.95)
 Arduino Mega 2560 I had this on hand, however a Micro, Uno or other Arduino board can be used instead as long as it has a UART + USB Serial (if you want to use it).


Total Estimated Cost ~  ($29 for Transmitter  +$28 for Receiver)

Click here to get the code for this project



Circuit Setup

The RF Link receiver and transmitter pair are the interesting part of this project. With these two guys, you can add one way communications with only a UART on each side.  I choose to use the Arduino board serial since I happened to have a couple of boards on hand and using the serial interface from these boards is very easy compared to the other ways of getting the serial data these components (i.e. software serial or virtual wire). This RF Link pair gets A LOT of noise, and that noise comes in as garbage data that has to be filtered out using a protocol that is robust enough to recognize the data you want to send and receive. The protocol and filtering is the key to getting reliable data from these guys!


Hooking up the RF Link Receiver


Here is the pin out for the RF Link receiver from the datasheet. Even though it has 8 pins, It's really four connections, Ground, 5V power, Digital Out to the RX of the serial port and the antenna on Pin 8.



Connections:
Pins 1, 6, 8    -> Ground  from Arduino Mega
Pin 8              -> 13 cm wire to act as an antenna
Pins 4, 5         -> 5V from Arduino Mega
Pin 2              -> Connected to RX3 (pin 15 on the Arduino Mega)



Hooking up the RF Link Transmitter to the Arduino Micro


Here is the datasheet for the RF Transmitter module. This module only has 4 pins so it's pretty easy to hookup. I used 5V to power it from the Micro but it can actually take up to 12V if you want better range!

Connections:
GND  -> Ground on Arduino Micro
DataIn -> TX pin on Arduino Micro
Vcc     -> 5V from Arduino Micro
ANT   -> 13 cm wire used as an antenna


Hooking up the TMP36 Temperature Sensor

Adafruit has an excellent tutorial to explain how to hook up the temperature sensor and much more Adafruit TMP36 sensor tutorial.



Connections:
Vcc   -> 3.3V on Arduino Micro                 (TMP36 Pin 1 on left when looking at flat side of sensor)
Vout  -> A0 analog input on Arduino Micro (TMP36 Center Pin)
Gnd   -> Ground on Arduino Micro             (TMP36 Pin 3 on right when looking at flat side of sensor)

The datasheet also shows a 0.1uF power supply coupling capacitor from the supply voltage pin to ground. I added this directly accross the leads on the TMP36 to help regulate any input voltage fluctuation. (not shown in picture below).
I also used the Analog Reference voltage at 3.3V instead of the 5V default by connecting the 3.3V pin on the Micro to the AREF pin (just to the right of the 3.3V pin).

CAUTION: If you connect the GND pins and Vcc pins backwards, your TMP36 will get very very hot and eventually this will burn out your sensor!


RF Transmitter and Temperature Sensor Circuit

The Code

The challenge in creating an RF link with these components is filtering out the bad data so that you can more reliably get the data you want!  These guys make a pretty noisy RF link so you can expect to get lots of garbage data (at least when using 5V to power the transmitter). The way to filter out the garbage data is to establishing a protocol for sending and receiving data.

Basically, a protocol is an agreed upon data format that is unlikely to occur in random data. Having a protocol allows the receiving code to know what to expect. There are a lot of ways to do this. You might send begin and end markers around the data and check to make sure you got both on the receiving side. A protocol may also send and check the size of the data packet along with the data to help the receiving side verify that the amount of data received is correct. The transmission could include the CRC of the data packet and the receiver could check it on the other end to verify that the data received is what was expected.
You can't prevent the receiver from getting bad data, but you can decide what the receiver will do with it.

I choose to establish a very simple protocol for my project using the word "Temp" as a sequence of characters that will proceed each temperature reading sent by the Transmitter. The temperature reading is a decimal and can be either a positive or negative number. So the only valid data the receiver should ever expect to get would look something like:
Temp70.58

The receiving code will exclude all data that doesn't match the expected data format established above. Ascii character codes are used for filter data. If the word Temp is not received or if bad data that doesn't meet the criteria for expected data, the data should be ignored. The received data is not always perfect so validation still needs to be added to ensure that only good data is used. Also, the transmitter is set to send a new value every 5 seconds, this is probably more often then I would like but it is good for testing!