Software apps and online services

Hand tools and fabrication machines

Story

Summary

You can buy a remote Oregon sensor THGN123N for about $20 or you can build your own temperature/humidity wireless sensor that implements Oregon protocol V2.1 for about $9 and have fun!

First of all, we need accurate temperature/humidity sensor to check the weather outside. In my previous project the sensor si7021 has shown perfect results, so I recommend this sensor one more time: it has great accuracy, small form-factor and low power consumption.

Second, we need mobile platform with low power requirements that can run on the batteries for a long time. Again, in the previous project such a platform has been successfully built. We can use atmega328p-pu chip, running at 1 MHz. The power consumption of this system is about 5 micro Amps!

Third, we need the software library for sending the signals using appropriate protocol. This library is based on the software created by Domonique Pierre, the author of software, emulated Oregon V2.1 protocol.

The power-efficient Arduino

There are several articles in the Internet about running Arduino controller on the batteries. For example, this article describes how to run the Arduino pro mini on batteries for long time. You need to cut-off the green power led that consumes about 10 mA. Unfortunately, you can destroy your Arduino board while trying to cut the desired wire, like I did. I believe it is better to build own Arduino from the scratch without any lLED at all. In this case, you can also decrease the power consumption by slowing down the controller CPU. Please, read the very detailed tutorial about creating own Arduino board running at 1 MHz and consuming as low as 5 micro Amps.

The software library

At the beginning, I tried to use pure library written by Domonique Pierre. Unfortunately, the controller speed is not sufficient to send the data in the time limits required by the protocol. To make the library faster, direct port manipulation was implemented in the new version of the library. In the Atmega 328 controller there are two output ports, B and D. In the library you can see two different classes for each port, directPortB and directPortD. The constructor for OregonSensor class automatically selects appropriate port based on the transmission pin number. There are direct port manipulation functions to send "one" and "zero" signal according by the Oregon protocol that allows to speed-up the signal transmission.

Conclusion

There are two interesting components in the project:

power-efficient Arduino controller that can run over a half-year on two AA batteries.

Schematics

The transmitter Schematics

Code

The transmitter sketch

Arduino

#include<WlessOregonV2.h>/* Humidity/Temperature sensor si7021@atmega328p-pu chip running at 1 MGz powered by the two AA batteries * Emulates Oregon V2.1 protocol to send the data * The voltage regulator ams1117-adj, supplies constant 1.24 volts to battPIN pin when is powered up through the powerPIN * The higher the value read on battPIN the lower the battery. * arduine reads 380 at 3.3 volts on battery, and 569 at 2.22 volts on the battery*/#include<avr/sleep.h>#include<avr/power.h>#include<avr/wdt.h>#include<Wire.h>#include<SI7021.h>constbyteledPin=7;// Pin for indicator LEDconstbytetransPin=11;// Pin for the radio transmitterconstbytebattPin=15;// A1, Pin to read battery levelconstbytepowerPIN=8;// Pin the voltage regulator to be poweredconstuint16_tlow_battery=550;// The limit for low batterySI7021sensor;OregonSensoros(transPin,0x20,0xBA,true);voidenterSleep(void){set_sleep_mode(SLEEP_MODE_PWR_DOWN);// the lowest power consumptionsleep_enable();sleep_mode();// Now enter sleep mode.// The program will continue from here after the WDT timeout. sleep_disable();// First thing to do is disable sleep.power_all_enable();// Re-enable the peripherals.}volatileintf_wdt=1;voidsetup(){// Serial.begin(9600);pinMode(ledPin,OUTPUT);pinMode(battPin,INPUT);pinMode(powerPIN,OUTPUT);digitalWrite(powerPIN,LOW);// Switch off the external voltage regulator on ams1117os.init();delay(15000);// Sleep to flash new programm// Setup the WDTMCUSR&=~(1<<WDRF);// Clear the reset flag// In order to change WDE or the prescaler, we need to// set WDCE (This will allow updates for 4 clock cycles).WDTCSR|=(1<<WDCE)|(1<<WDE);WDTCSR=1<<WDP0|1<<WDP3;// set new watchdog timeout prescaler value 8.0 secondsWDTCSR|=_BV(WDIE);// Enable the WD interrupt (note no reset).delay(100);// Allow for serial print to complete.sensor.begin();}voidloop(){staticintawake_counter=1;staticintcheck_battery=0;staticboolbatteryOK=true;if(f_wdt==1){f_wdt=0;--awake_counter;if(awake_counter<=0){// Send Weather dataawake_counter=5;// Check the battery level every 100 wake ups 100*5*8s = 4000 secondsif(batteryOK&&(check_battery==0)){// The battery cannot repare by itself!digitalWrite(powerPIN,HIGH);// power up the external voltage regulator that supply 1.24 volts to battPINdelay(10);uint16_tbattLevel=analogRead(battPin);// 0 <= battLevel <= 1023digitalWrite(powerPIN,LOW);// switch off the external voltage regulator//Serial.println(battLevel, DEC);batteryOK=(battLevel<low_battery);}++check_battery;if(check_battery>100)check_battery=0;inttemperature=sensor.getCelsiusHundredths();if(temperature>0)temperature+=5;elsetemperature-=5;temperature/=10;bytehumidity=sensor.getHumidityPercent();digitalWrite(ledPin,HIGH);// Switch on the check led before transmitionos.sendTempHumidity(temperature,humidity,batteryOK);digitalWrite(ledPin,LOW);}enterSleep();}}ISR(WDT_vect){if(f_wdt==0)f_wdt=1;}