In my previous post, I experimented with sending measurements values from an Arduino UNO to a Raspberry Pi via a 433 MHz radio protocol. After testing the setup for a few days, I decided to make some improvements:
- Add an additional sensor for measuring outdoor temperatures. Now there will be four different sensor values transmitted from the Arduino to the Raspberry Pi.
- Add the possibility to send float values for more precision and, for adopting to the Swedish climate, allow negative values.
- On the receiver side (the Raspberry Pi), add storage of the values to a csv file so that the measurements can be visualized in graphs with Excel or a similar application.
- Improve the noise tolerance.
Outdoor temperature sensor
To my experimental Arduino board, I added a waterproof version of the DS18B20 sensor. It can handle negative temperatures and has an accuracy of ± 0.5 degrees C.
Handling decimals and negative values
My previous wireless protocol only considered positive integers stored in two bytes. But now, for a measurement with decimal precision, I multiply the measurement with 100 and use the highest bit as a flag for negative/positive value. On the receiver side, when a measurement of this type arrives, the sign bit is handled and the value is divided with 100.
The 433 MHz band and the very inexpensive transmitter and receiver that I use are quite sensitive to noise. I had already implemented a simple check sum for detecting some errors, but after using the setup for a one day measurement cycle, I realized that this was not sufficient. Some noise would still pass through and mess up the received sensor values, so I decided on an additional error handling:
- The transmitter sends each sensor value twice, with a two second delay in between
- For accepting a measurement as valid, the receiver code requires that two identical values are received in sequence.
The wireless library that I use (RCSwitch) allows automatic transmits (and I use that feature), but it is not sufficient. I need a small delay between each transmit for getting reliable values for the receiver.
Extending the Arduino breadboard
The receiver circuit that is connected to the Raspberry Pi stays the same as in the previous post, but the Arduino UNO’s breadboard gets a new temperature sensor, DS18B20. It has 3 cables: red = 5V, black (ground) and yellow (digital signal output). 5V and ground goes to Arduino’s 5V & ground. The output signal goes to Arduino’s digital pin 3. There is also a 4,7 kOhm pull-up resistor between 5V and the signal.
Programming the Arduino
To get the DS18B20 sensor to work with the Arduino, there are two libraries that can be used:
This page https://arduino-info.wikispaces.com/Brick-Temperature-DS18B20, has a very good description of the wiring and some example code.
I have modified my previous sensor/transmitter code so that the additional DS18B20 sensor is handled. All transmitted messages are now sent twice with a delay in between so that the receiver has a better chance of filtering out noisy signals. The new sensor’s value is a float and it gets a special encoding before it is sent to RCSwitch.
Programming the Raspberry Pi
The receiver code from the previous post now handles yet another measurement type, “Outdoor Temp”. To decode a float value from the two bytes, the highest bit is read to check if it is a negative value and then the value (with the highest bit cleared) is divided by 100.
The receiver code has also been extended with storage of the data to a comma-separated file. This file can be used in Excel or similar for viewing the data in graphs.
All code from this post can be downloaded from https://github.com/LarsBergqvist/ArduinoToRaspberry_via_433Mhz_RF.