Created
June 14, 2017 20:45
-
-
Save subutux/90b7b96f26c3155a1a1fab1035a50e7c to your computer and use it in GitHub Desktop.
This file contains hidden or 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 | |
#define MY_DEBUG | |
// Enable and select radio type attached | |
#define MY_RADIO_NRF24 | |
//#define MY_RADIO_RFM69 | |
//#define MY_RS485 | |
#include <SPI.h> | |
#include <MySensors.h> | |
#include <DHT.h> | |
#include <Wire.h> | |
#include <BH1750.h> | |
BH1750 lightSensor; | |
int BATTERY_SENSE_PIN = A0; // select the input pin for the battery sense point | |
int oldBatteryPcnt = 0; | |
// Set this to the pin you connected the DHT's data pin to | |
#define DHT_DATA_PIN 3 | |
// Set this offset if the sensor has a permanent small offset to the real temperatures | |
#define SENSOR_TEMP_OFFSET 0 | |
// Sleep time between sensor updates (in milliseconds) | |
// Must be >1000ms for DHT22 and >2000ms for DHT11 | |
static const uint64_t UPDATE_INTERVAL = 30000; | |
// Force sending an update of the temperature after n sensor reads, so a controller showing the | |
// timestamp of the last update doesn't show something like 3 hours in the unlikely case, that | |
// the value didn't change since; | |
// i.e. the sensor would force sending an update every UPDATE_INTERVAL*FORCE_UPDATE_N_READS [ms] | |
static const uint8_t FORCE_UPDATE_N_READS = 10; | |
#define CHILD_ID_HUM 0 | |
#define CHILD_ID_TEMP 1 | |
#define CHILD_ID_VOLT 3 | |
#define CHILD_ID_LIGHT 5 | |
// Disable repeater for now | |
//#define MY_REPEATER_FEATURE | |
float lastTemp; | |
float lastHum; | |
uint8_t nNoUpdatesTemp; | |
uint8_t nNoUpdatesHum; | |
uint8_t nNoUpdatesLux; | |
uint8_t nNoUpdatesBattP; | |
uint8_t nNoUpdatesBattV; | |
bool metric = true; | |
unsigned long Timer = 0; | |
const long IntervalReadSensor = 12000.; | |
const long IntervalReadBatt = 30000; | |
unsigned long TimerBatt = 0; | |
MyMessage msgHum(CHILD_ID_HUM, V_HUM); | |
MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP); | |
MyMessage msgVolt(CHILD_ID_VOLT, V_VOLTAGE); | |
MyMessage msgLux(CHILD_ID_LIGHT, V_LEVEL); | |
uint16_t lastlux; | |
float lastvolt; | |
DHT dht; | |
void presentation() | |
{ | |
// Send the sketch version information to the gateway | |
sendSketchInfo("Temp en vocht tuin", "2.1"); | |
// Register all sensors to gw (they will be created as child devices) | |
present(CHILD_ID_HUM, S_HUM); | |
present(CHILD_ID_TEMP, S_TEMP); | |
present(CHILD_ID_VOLT, S_MULTIMETER); | |
present(CHILD_ID_LIGHT, S_LIGHT_LEVEL); | |
metric = getControllerConfig().isMetric; | |
} | |
void setup() | |
{ | |
// use the 1.1 V internal reference | |
#if defined(__AVR_ATmega2560__) | |
analogReference(INTERNAL1V1); | |
#else | |
analogReference(INTERNAL); | |
#endif | |
// Low Power mode | |
lightSensor.begin(BH1750_ONE_TIME_HIGH_RES_MODE); | |
dht.setup(DHT_DATA_PIN); // set data pin of DHT sensor | |
if (UPDATE_INTERVAL <= dht.getMinimumSamplingPeriod()) { | |
Serial.println("Warning: UPDATE_INTERVAL is smaller than supported by the sensor!"); | |
} | |
// Sleep for the time of the minimum sampling period to give the sensor time to power up | |
// (otherwise, timeout errors might occure for the first reading) | |
sleep(dht.getMinimumSamplingPeriod()); | |
} | |
void loop() | |
{ | |
// Force reading sensor, so it works also after sleep() | |
dht.readSensor(true); | |
int sensorValue = analogRead(BATTERY_SENSE_PIN); | |
// 1M, 300K divider across battery and using internal ADC ref of 1.1V | |
// Sense point is bypassed with 0.1 uF cap to reduce noise at that point | |
// ((1e6+470e3)/300e3)*1.1 = Vmax = 4.7 Volts | |
// 4.7/1023 = Volts per bit = 0.00459433 | |
int batteryPcnt = sensorValue / 10; | |
#ifdef MY_DEBUG | |
float batteryV = sensorValue * 0.00459433; | |
Serial.print("Battery Voltage: "); | |
Serial.print(batteryV); | |
Serial.println(" V"); | |
Serial.print("Battery percent: "); | |
Serial.print(batteryPcnt); | |
Serial.println(" %"); | |
#endif | |
if (oldBatteryPcnt != batteryPcnt) { | |
// Power up radio after sleep | |
sendBatteryLevel(batteryPcnt); | |
oldBatteryPcnt = batteryPcnt; | |
} | |
if (lastvolt != batteryV){ | |
send(msgVolt.set(batteryV, 2)); | |
lastvolt = batteryV; | |
} | |
lightSensor.configure(BH1750_ONE_TIME_HIGH_RES_MODE); | |
delay(200); // Library says 120 ms to wait for startup, 200 just to be sure | |
uint16_t lux = lightSensor.readLightLevel();// Get Lux value | |
#ifdef MY_DEBUG | |
Serial.print("LUX: "); | |
Serial.println(lux); | |
#endif | |
if (lux != lastlux || nNoUpdatesLux == FORCE_UPDATE_N_READS) { | |
send(msgLux.set(lux)); | |
#ifdef MY_DEBUG | |
Serial.print("LUX: "); | |
Serial.println(lux); | |
#endif | |
lastlux = lux; | |
} | |
// Get temperature from DHT library | |
float temperature = dht.getTemperature(); | |
if (isnan(temperature)) { | |
Serial.println("Failed reading temperature from DHT!"); | |
} else if (temperature != lastTemp || nNoUpdatesTemp == FORCE_UPDATE_N_READS) { | |
// Only send temperature if it changed since the last measurement or if we didn't send an update for n times | |
lastTemp = temperature; | |
if (!metric) { | |
temperature = dht.toFahrenheit(temperature); | |
} | |
// Reset no updates counter | |
nNoUpdatesTemp = 0; | |
temperature += SENSOR_TEMP_OFFSET; | |
send(msgTemp.set(temperature, 1)); | |
#ifdef MY_DEBUG | |
Serial.print("T: "); | |
Serial.println(temperature); | |
#endif | |
} else { | |
// Increase no update counter if the temperature stayed the same | |
nNoUpdatesTemp++; | |
} | |
// Get humidity from DHT library | |
float humidity = dht.getHumidity(); | |
if (isnan(humidity)) { | |
Serial.println("Failed reading humidity from DHT"); | |
} else if (humidity != lastHum || nNoUpdatesHum == FORCE_UPDATE_N_READS) { | |
// Only send humidity if it changed since the last measurement or if we didn't send an update for n times | |
lastHum = humidity; | |
// Reset no updates counter | |
nNoUpdatesHum = 0; | |
send(msgHum.set(humidity, 1)); | |
#ifdef MY_DEBUG | |
Serial.print("H: "); | |
Serial.println(humidity); | |
#endif | |
} else { | |
// Increase no update counter if the humidity stayed the same | |
nNoUpdatesHum++; | |
} | |
// Sleep for a while to save energy | |
sleep(UPDATE_INTERVAL); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment