Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
MySensors
// 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
You can’t perform that action at this time.