Permalink
Cannot retrieve contributors at this time
Name already in use
A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
TempHygroTX868/examples/TX868_HTU21_LowPower/TX868_HTU21_LowPower.ino
Go to fileThis commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
180 lines (152 sloc)
3.92 KB
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Production code to build a weather sensor/transmitter | |
* similar to the S300 by ELV. | |
* | |
* It measures temperature and humidity with a HTU21D sensor | |
* and transmits these values using the TX868. | |
* The address of the transmitter may be configured with a DIP switch. | |
* The processor is put into power down sleep and waked up | |
* by the watchdog timer periodically to reduce power consumption. | |
* | |
* Required libraries: | |
* - TempHygroTX868: https://github.com/skaringa/TempHygroTX868 | |
* - SparkFunHTU21D: https://github.com/sparkfun/SparkFun_HTU21D_Breakout_Arduino_Library | |
* | |
* Hardware setup: | |
* - TX868 Data pin connected to digital pin 5 | |
* - HTU21D SDA connected to A4 and SCL to A5 | |
* - 3 DIP switches are connected to digital pins 7, 8, 9 with one contact | |
* and to ground with the other contact | |
*/ | |
#include <TempHygroTX868.h> | |
#include <Wire.h> | |
#include <SparkFunHTU21D.h> | |
#include <avr/sleep.h> | |
#include <avr/power.h> | |
HTU21D htu; | |
TempHygroTX868 tx; | |
// transmission timer: | |
// it holds the number of seconds remaining until the next transmission | |
volatile int nextTxTimer; | |
// pin of build-in signal LED | |
#define LED 13 | |
// lowest pin of DIP switch | |
#define SWITCH 7 | |
// you may define DEBUG macro here | |
// to get debug output at the serial line | |
void setup() | |
{ | |
#ifdef DEBUG | |
Serial.begin(9600); | |
Serial.println(); | |
Serial.println("Address\tHumidity (%)\tTemperature (C)"); | |
#endif | |
htu.begin(); | |
tx.setup(5); // transmitter is at data pin 5 | |
pinMode(LED, OUTPUT); // signal LED | |
nextTxTimer = 0; | |
/* Setup the Watchdog timer */ | |
// clear the reset flag | |
MCUSR &= ~(1<<WDRF); | |
// enable configuration changes | |
WDTCSR |= (1<<WDCE) | (1<<WDE); | |
// set new watchdog timeout prescaler value to maximum | |
WDTCSR = 1<<WDP0 | 1<<WDP3; | |
// Enable the watchdog interrupt | |
WDTCSR |= _BV(WDIE); | |
} | |
void loop() | |
{ | |
// are we required to send? | |
if (nextTxTimer <= 9) { | |
// yes - delay remaining time | |
delay(nextTxTimer * 1000); | |
// reset time to next transmission | |
#ifdef DEBUG | |
nextTxTimer = 30; | |
#else | |
nextTxTimer = tx.getPause(); | |
#endif | |
// read address from DIP switch | |
byte addr = readSwitch(); | |
#ifdef DEBUG | |
Serial.print(addr); | |
Serial.print("\t"); | |
#endif | |
tx.setAddress(addr); | |
// read sensor and transmit | |
sendData(); | |
} | |
// go into power down sleep | |
pwrDownSleep(); | |
} | |
/* | |
* Read address from DIP switch | |
*/ | |
byte readSwitch() | |
{ | |
pinMode(SWITCH, INPUT_PULLUP); | |
pinMode(SWITCH+1, INPUT_PULLUP); | |
pinMode(SWITCH+2, INPUT_PULLUP); | |
delay(1); | |
byte val = digitalRead(SWITCH+2); | |
val <<= 1; | |
val |= digitalRead(SWITCH+1); | |
val <<= 1; | |
val |= digitalRead(SWITCH); | |
// disconnect pullups to save power | |
pinMode(SWITCH, INPUT); | |
pinMode(SWITCH+1, INPUT); | |
pinMode(SWITCH+2, INPUT); | |
return val; | |
} | |
/* | |
* Read data from sensor and transmit. | |
*/ | |
void sendData() | |
{ | |
digitalWrite(LED, HIGH); | |
float humidity = htu.readHumidity(); | |
float temperature = htu.readTemperature(); | |
#ifdef DEBUG | |
Serial.print(humidity); | |
Serial.print("\t"); | |
Serial.println(temperature); | |
#endif | |
delay(100); | |
if (humidity < 900 && temperature < 900) { | |
// valid reading | |
tx.send(temperature, humidity); | |
} | |
digitalWrite(LED, LOW); | |
} | |
/* | |
* Interrupt service routine triggered by watchdog. | |
*/ | |
ISR(WDT_vect) | |
{ | |
// Watchdog oscillator freq is about 116 kHz | |
// at 3 V and 25 °C | |
// Therefore time between interrupts is | |
// 1,048,576 / 116,000 = 9.039 seconds. | |
// So decrement the transmission timer by this value. | |
nextTxTimer -= 9; | |
} | |
/* | |
* Go into power down mode | |
*/ | |
void pwrDownSleep() | |
{ | |
byte adcsra = ADCSRA; | |
ADCSRA = 0; // disable the ADC - saves 80 µA | |
set_sleep_mode(SLEEP_MODE_PWR_DOWN); | |
sleep_enable(); | |
cli(); // stop interrupts | |
sleep_bod_disable(); // disable brown-out detection | |
sei(); // enable interrupts | |
sleep_cpu(); | |
// At this point the CPU is sleeping until watchdog bites | |
sleep_disable(); | |
power_all_enable(); | |
ADCSRA = adcsra; // restore ADCSRA | |
} |