Arduino multiple sensor wireless thermometer using 433Mhz/315Mhz RF modules

I always wanted a thermometer displaying the temperature of each room of the house and was thinking of buying a weather station to solve this. The problem was that most weather stations had one remote sensor and I needed at least 3.

I decided to build my own base station capable of displaying the temperature from multiple sensors around the house. I wanted the project to be cheap so I decided to use those 315/433Mhz receiver/transmitter pairs for under a dollar. For the display I chose a 1602 which has the I2C interface so I can interface it with only a few cables and for sensors/base station I chose Arduino nanos.

I was thinking of using the Arduino Wire library for the communication but as I wanted to be able to expand the project with remote power outlets at some later time I just chose to use the RC-Switch Library http://code.google.com/p/rc-switch/

 

The wiring of the modules is really easy, you just connect GND to the Arduino Groud, the VCC to +5V on the Arduino and the DATA to:

  • Remote sensor transmitter module DATA pin to Arduino D10
  • Base station receiver DATA pin to Arduino D2

Since I don’t need the temperature readings to be super precise the only thing I needed for the reading was a cheap 10K thermistor and a 10K resistor

 

sender

Wireless sensor code follows. The code contains code fragments from Arduino Playground http://playground.arduino.cc/ComponentLib/Thermistor2

In order to compile it you will need rc-switch library which you can download at http://code.google.com/p/rc-switch/.

# Remote sensor Arduino code
#include <RCSwitch.h>
#define ThermistorPIN 6 // Analog Pin 6

RCSwitch mySwitch = RCSwitch();
int sensorID = 2; //For the purpose of multiple sensors. Valid values would be 1..9


double ReadTemperature(){

int RawADC = analogRead(ThermistorPIN);
long Resistance; double Temp; // Dual-Purpose variable to save space.
Resistance=10000.0*((1024.0/RawADC) - 1); // Assuming a 10k Thermistor. Calculation is actually: Resistance = (1024 /ADC -1) * BalanceResistor

 Temp = log(Resistance);
 Temp = 1 / (0.001129148 + (0.000234125 * Temp) + (0.0000000876741 * Temp * Temp * Temp));
 Temp = Temp - 273.15; // Convert Kelvin to Celsius

 // Uncomment following line for the function to return Fahrenheit instead.
 //Temp = (Temp * 9.0)/ 5.0 + 32.0;
 return Temp;
}

void setup() {
 Serial.begin(9600);
 // Transmitter is connected to Arduino Pin #10 
 mySwitch.enableTransmit(10);
}

void loop() {
 double temp=ReadTemperature();
 Serial.println(temp);
 
 // A simple way of encoding sensor ID and value in one code
 long codetosend = temp*100+(sensorID*100000);
 
 mySwitch.send(codetosend, 24);
 delay(200);
}

The code above is not optimized at all for battery operation since I am powering those “sensors” through usb. If you want to make those more battery friendly there are a lot of useful guides on the internet. Serial prints are also not needed and can be removed. I was only using those for debugging purposes

Base Station

The base station consists of an I2C 1602 LCD Display, Arduino Nano3, 315/433Mhz receiver. Everyone needs to know the local temperature on the base station so again we need the same 10K thermistor connected the same way as in the Remote sensor

In order to compile the Base Station code you will need libraries Wire, LiquidCrystal_I2C and RCSwitch

Base station code follows:

# Base Station Arduino code
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <RCSwitch.h>

#define I2C_ADDR 0x27 // <<----- Add your address here. Find it from I2C Scanner
#define BACKLIGHT_PIN 3
#define En_pin 2
#define Rw_pin 1
#define Rs_pin 0
#define D4_pin 4
#define D5_pin 5
#define D6_pin 6
#define D7_pin 7
#define ThermistorPIN 6 // Analog Pin 6

RCSwitch mySwitch = RCSwitch();
LiquidCrystal_I2C lcd(I2C_ADDR,En_pin,Rw_pin,Rs_pin,D4_pin,D5_pin,D6_pin,D7_pin);


double ReadTemperature(){
int RawADC = analogRead(ThermistorPIN);
long Resistance; double Temp; // Dual-Purpose variable to save space.
Resistance=10000.0*((1024.0/RawADC) - 1); // Assuming a 10k Thermistor. Calculation is actually: Resistance = (1024 /ADC -1) * BalanceResistor

 Temp = log(Resistance);
 Temp = 1 / (0.001129148 + (0.000234125 * Temp) + (0.0000000876741 * Temp * Temp * Temp));
 Temp = Temp - 273.15; // Convert Kelvin to Celsius

 // Uncomment following line for the function to return Fahrenheit instead.
 //Temp = (Temp * 9.0)/ 5.0 + 32.0;
 return Temp;
}

void setup() {
 delay(600);
 lcd.begin (16,2); // <<----- My LCD is 16x2
 Serial.begin(9600);
 mySwitch.enableReceive(0); // Receiver on inerrupt 0 => that is pin #2

 // Switch on the backlight
 lcd.setBacklightPin(BACKLIGHT_PIN,POSITIVE);
 lcd.setBacklight(HIGH);
 lcd.home (); // go home
}

#define ThermistorPIN 6 // Analog Pin 6
double temp;
double rc=0;
void loop() {
 double temp=ReadTemperature();
 // End of Line
 Serial.println(temp);
 lcd.setCursor ( 0, 0 );
 lcd.print(temp);
 lcd.print("C");
 rc=0;

 for (int i=0;i<100;i++){
 // TRY TO READ VALUE 100 times!
 if (mySwitch.available()) {
  int value = mySwitch.getReceivedValue();
  if (value == 0) {
  Serial.print("Unknown encoding");
 } else {
 rc = mySwitch.getReceivedValue();
  // Process value from Remote sensor 2 and display reading on the right line1
  if (abs(rc)>=150000 && abs(rc)<250000){
   rc=(rc-200000)/100;
   lcd.setCursor ( 10, 0 );
   lcd.print(rc);
   lcd.print("C");
   }
  // Process value from Remote sensor 3 and display it on the left line 2
  if (abs(rc)>=250000&& abs(rc)<350000){
   rc=(rc-300000)/100;
   lcd.setCursor ( 0, 1 );
   lcd.print(rc);
   lcd.print("C");
  }
 }
 }
 delay(10);
 }
 //Update delay
 delay(2500);
 lcd.clear();
}

The code only manages 1 local and 2 remote sensors but you can add more by just adding the respective code just like the one for sensor 2 &3. Hint:  Don’t forget to set a unique sensor ID in the remote sensor code ;-)

Wiring the Base Station

Display  – we need an I2C display so it only needs 4 wires: GND, VCC, SDA and SCL

Connect GND to ground on the Arduino and VCC to the 5V of the Arduino, SDA to A4 and SCL to A5

Receiver

Connect GND to ground on the Arduino and VCC to the 5V of the Arduino, DATA to D2 on the Arduino

Thermistor

Connect the thermistor and resistor just like on the remote sensor, reading on pin A6

Sourcing the parts:

Resistor, thermistor and cables are widely available in local electronics stores

I2C 1602 Display

Arduino Nano v3

433Mhz Transmitter and Receiver pair

P.S. If you are looking at the code and thinking what are we doing to encode the values and sensor ID in one code and  how do we handle negative values when the code we transmit is always positive?   Well :)  it is not that easy to understand but you can figure it out by looking at the code a bit more. You just need to know that the effective temperature range is from -499.99 to 499.99 by design. E.g. Remote sensors cannot transmit values outside of this range

Done! Enjoy your multi sensor thermometer

I just found those great 433 Mhz antennas for the modules. With those the range of the sensors increases dramatically! Just solder them on the antenna spot and you’re done