MySensors
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
// Enable debug prints to serial monitor. | |
#define MY_DEBUG | |
#define MY_SERIAL | |
#ifdef MY_SERIAL | |
#define DEBUG(input) {Serial.print(input);} | |
#define DEBUGln(input) {Serial.println(input);} | |
#define SERIALFLUSH() {Serial.flush();} | |
#else | |
#define DEBUG(input); | |
#define DEBUGln(input); | |
#define SERIALFLUSH(); | |
#endif | |
// Enable and select radio type attached. | |
#define MY_RADIO_RFM69 | |
#define MY_RFM69_FREQUENCY RF69_433MHZ | |
#define MY_IS_RFM69HW | |
#define MY_RFM69_NETWORKID 2 | |
#define MY_NODE_ID AUTO | |
#include <MySensors.h> | |
#include "SparkFunHTU21D.h" // Get it here https://github.com/sparkfun/SparkFun_HTU21D_Breakout_Arduino_Library. | |
#define RADIO_ERROR_LED_PIN 4 // Error led pin. | |
#define RADIO_RX_LED_PIN 6 // Receive led pin. | |
#define RADIO_TX_LED_PIN 5 // the PCB, on board LED. | |
// Battery settings. | |
#define BATT_READ_LOOPS 1 // Read and report battery voltage every this many sleep cycles. | |
#define BATT_MIN_V 2000 | |
#define BATT_MAX_V 5000 | |
// Wait times | |
#define LONG_WAIT 100 | |
#define SHORT_WAIT 50 | |
#define SKETCH_NAME "HTU21D" | |
#define SKETCH_VERSION "v0.01" | |
// Define Sensors ids. | |
#define ID_S_TEMP 0 | |
#define ID_S_HUM 1 | |
#define ID_S_BAT 2 | |
// Global Vars. | |
HTU21D mySensor; | |
unsigned long SLEEP_TIME = 60000; // Sleep time between reads (in milliseconds). | |
bool metric = true; | |
byte battReadLoops = 0; | |
int oldBatteryPcnt = 0; | |
// Instanciate Messages objects. | |
MyMessage msg_S_TEMP(ID_S_TEMP, V_TEMP); | |
MyMessage msg_S_HUM(ID_S_HUM, V_HUM); | |
MyMessage msg_S_BAT(ID_S_BAT, V_VOLTAGE); | |
void setup() { | |
mySensor.begin(); | |
} | |
void presentation() { | |
// Send the Sketch Version Information to the Gateway. | |
sendSketchInfo(SKETCH_NAME, SKETCH_VERSION); | |
wait(LONG_WAIT); | |
// Get controller configuration | |
metric = getControllerConfig().isMetric; | |
DEBUGln(metric ? "Metric":"Imperial"); | |
wait(LONG_WAIT); | |
// Register all sensors to the gateway (they will be created as child devices). | |
present(ID_S_TEMP, S_TEMP, "Temperature", true); | |
wait(LONG_WAIT); | |
present(ID_S_HUM, S_HUM, "Humidity", true); | |
wait(LONG_WAIT); | |
present(ID_S_BAT, S_MULTIMETER, "Voltage", true); | |
wait(LONG_WAIT); | |
} | |
void loop() { | |
// Read Sensors. | |
temperature(); | |
wait(LONG_WAIT); | |
humidity(); | |
wait(LONG_WAIT); | |
battery(); | |
wait(LONG_WAIT); | |
// Sleep. | |
smartSleep(SLEEP_TIME); | |
} | |
// This is called when a new time value was received. | |
void receiveTime(unsigned long controllerTime) { | |
Serial.print("Time value received: "); | |
Serial.println(controllerTime); | |
} | |
void temperature() { | |
double T = mySensor.readTemperature(); | |
DEBUGln("Temperature is: "); | |
DEBUGln(T); | |
if (T < 998) { | |
send(msg_S_TEMP.set(T, 2)); | |
} | |
} | |
void humidity() { | |
double H = mySensor.readHumidity(); | |
DEBUGln("Humidity is: "); | |
DEBUGln(H); | |
send(msg_S_HUM.set(H, 2)); | |
} | |
void battery() { | |
// Send battery level every BATT_READ_LOOPS cycles. | |
if (battReadLoops-- <= 0) { | |
int batteryPcnt = batteryPct(); | |
if (oldBatteryPcnt != batteryPcnt) { | |
// Power up radio after sleep | |
sendBatteryLevel(batteryPcnt); | |
oldBatteryPcnt = batteryPcnt; | |
} | |
battReadLoops = BATT_READ_LOOPS - 1; | |
} | |
} | |
void receive(const MyMessage &message) { | |
switch (message.type) { | |
default: | |
DEBUGln("Unknown/UnImplemented message type: "); | |
DEBUGln(message.type); | |
} | |
} | |
int batteryPct() { | |
// Convert voltage to percentage. | |
int vcc = readVcc(); | |
send(msg_S_BAT.set(vcc)); | |
int pct = min(map(vcc, BATT_MIN_V, BATT_MAX_V, 0, 100), 100); | |
if (pct > 100) pct = 100; | |
return pct; | |
} | |
long readVcc() { | |
// Read 1.1V reference against AVcc | |
// set the reference to Vcc and the measurement to the internal 1.1V reference | |
#if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) | |
ADMUX = _BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1); | |
#elif defined (__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__) | |
ADMUX = _BV(MUX5) | _BV(MUX0); | |
#elif defined (__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__) | |
ADMUX = _BV(MUX3) | _BV(MUX2); | |
#else | |
ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1); | |
#endif | |
delay(2); // Wait for Vref to settle | |
ADCSRA |= _BV(ADSC); // Start conversion | |
while (bit_is_set(ADCSRA,ADSC)); // measuring | |
uint8_t low = ADCL; // must read ADCL first - it then locks ADCH | |
uint8_t high = ADCH; // unlocks both | |
long result = (high<<8) | low; | |
result = 1125300L / result; // Calculate Vcc (in mV); 1125300 = 1.1*1023*1000 | |
return result; // Vcc in millivolts | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment