commit 55efb5e220f3552eefed984ed246789179e64528 Author: Frank Date: Thu Dec 30 13:34:25 2021 +0100 Create Garage.ino diff --git a/Garage.ino b/Garage.ino new file mode 100644 index 0000000..fa77598 --- /dev/null +++ b/Garage.ino @@ -0,0 +1,342 @@ +//Sensor +//Garage + +// Enable debug prints to serial monitor +//#define MY_DEBUG + +// Enable and select radio type attached +#define MY_RADIO_NRF24 +//#define MY_RADIO_RFM69 + +// Enable repeater functionality for this node +#define MY_REPEATER_FEATURE + +#include +#include +#include +#include +#include +#include + +//Defines +#define HUMIDITY_SENSOR_DIGITAL_PIN 7 +#define CHILD_ID_HUM 6 +#define CHILD_ID_TEMP 5 + +#define ONE_WIRE_BUS 8 // Pin where dallase sensor is connected +#define MAX_ATTACHED_DS18B20 5 +OneWire oneWire(ONE_WIRE_BUS); +DallasTemperature temp_sensors(&oneWire); +float lastTemperature[MAX_ATTACHED_DS18B20]; +int numSensors=0; + +#define d1_BUTTON_PIN 4 // Arduino Digital I/O pin for button/reed switch +#define d2_BUTTON_PIN 5 // Arduino Digital I/O pin for button/reed switch + +#define d1_CHILD_ID 11 // Id of the sensor child +#define d2_CHILD_ID 12 // Id of the sensor child + +#define P_DIGITAL_INPUT_SENSOR 3 // The digital input you attached your light sensor. (Only 2 and 3 generates interrupt!) +#define P_INTERRUPT P_DIGITAL_INPUT_SENSOR-2 // Usually the interrupt = pin -2 (on uno/nano anyway) +#define P_PULSE_FACTOR 1000 // Nummber of blinks per KWH of your meeter +#define MAX_WATT 30000 // Max watt value to report. This filetrs outliers. +#define P_CHILD_ID 20 // Id of the sensor child + +unsigned long P_SEND_FREQUENCY = 60000; // Minimum time between send (in milliseconds). We don't wnat to spam the gateway. +unsigned long P_CHECK_ZERO = 120000; // Check frequency if there is still some powerconsumption + +double P_ppwh = ((double)P_PULSE_FACTOR)/1000; // Pulses per watt hour +boolean P_pcReceived = false; + +volatile unsigned long P_pulseCount = 0; +volatile unsigned long P_lastBlink = 0; +volatile unsigned long P_watt = 0; +unsigned long P_oldPulseCount = 0; +unsigned long P_oldWatt = 1; +double P_oldKwh; +unsigned long P_lastSend; + +DHT dht; +float lastTemp; +float lastHum; +boolean metric = true; + +unsigned long currentTime; +unsigned long P_lastBlinkmillis; +unsigned long SEND_FREQUENCY = 300000; +unsigned long lastSend; + +//Declare deuren +Bounce d1_debouncer = Bounce(); +int d1_value; +int d1_oldValue=-1; +Bounce d2_debouncer = Bounce(); +int d2_oldValue=-1; +int d2_value; + +// Change to V_LIGHT if you use S_LIGHT in presentation below +MyMessage msg_Hum(CHILD_ID_HUM, V_HUM); +MyMessage msg_Temp(CHILD_ID_TEMP, V_TEMP); + +MyMessage msg_dallas(0,V_TEMP); + +MyMessage d1_msg(d1_CHILD_ID,V_TRIPPED); +MyMessage d2_msg(d2_CHILD_ID,V_TRIPPED); + +MyMessage wattMsg(P_CHILD_ID,V_WATT); +MyMessage kwhMsg(P_CHILD_ID,V_KWH); +MyMessage pcMsg(P_CHILD_ID,V_VAR1); + +void setup() +{ + //Setup DHT22 + dht.setup(HUMIDITY_SENSOR_DIGITAL_PIN); + + //Setup Dallas + // Startup OneWire + temp_sensors.begin(); + // Fetch the number of attached temperature sensors + numSensors = temp_sensors.getDeviceCount(); + Serial.print("Dallas Sensors : "); + Serial.println(numSensors); + + attachInterrupt(P_INTERRUPT, P_onPulse, RISING); + P_lastSend=millis(); + + // Setup the door switchs 1 + pinMode(d1_BUTTON_PIN,INPUT); + // Activate internal pull-up + digitalWrite(d1_BUTTON_PIN,HIGH); + // After setting up the button, setup debouncer + d1_debouncer.attach(d1_BUTTON_PIN); + d1_debouncer.interval(200); + + // Setup the door switch 2 + pinMode(d2_BUTTON_PIN,INPUT); + // Activate internal pull-up + digitalWrite(d2_BUTTON_PIN,HIGH); + // After setting up the button, setup debouncer + d2_debouncer.attach(d2_BUTTON_PIN); + d2_debouncer.interval(200); + + metric = getControllerConfig().isMetric; + lastSend = 0; +} + + +void presentation() +{ + // Send the sketch version information to the gateway and Controller + sendSketchInfo("Garage", "2.0"); + + present(CHILD_ID_HUM, S_HUM); + present(CHILD_ID_TEMP, S_TEMP); + + for (int i=0; i P_CHECK_ZERO) + { + P_watt = 0.0; + } + + // Only send values at a maximum frequency or woken up from sleep + bool P_sendTime = currentTime - P_lastSend > P_SEND_FREQUENCY; + if (P_pcReceived && P_sendTime) + { + Serial.println("Send data power..."); + // New watt value has been calculated + if (P_watt != P_oldWatt) + { + // Check that we dont get unresonable large watt value. + // could hapen when long wraps or false interrupt triggered + if (P_watt<((unsigned long)MAX_WATT)) + { + send(wattMsg.set(P_watt)); // Send watt value to gw + } + Serial.print("Watt:"); + Serial.println(P_watt); + P_oldWatt = P_watt; + } + + // Pulse cout has changed + if (P_pulseCount != P_oldPulseCount) + { + send(pcMsg.set(P_pulseCount)); // Send pulse count value to gw + double P_kwh = ((double)P_pulseCount/((double)P_PULSE_FACTOR)); + P_oldPulseCount = P_pulseCount; + if (P_kwh != P_oldKwh) + { + send(kwhMsg.set(P_kwh, 4)); // Send kwh value to gw + P_oldKwh = P_kwh; + } + } + P_lastSend = currentTime; + } + else if (P_sendTime && !P_pcReceived) + { + // No count received. Try requesting it again + request(P_CHILD_ID, V_VAR1); + P_lastSend = currentTime; + } + + // delay(dht.getMinimumSamplingPeriod()); + //Send data only every 5 minuts + if ((currentTime - lastSend) > SEND_FREQUENCY) + { + lastSend=currentTime; + float temperature = dht.getTemperature(); + if (isnan(temperature)) + { + Serial.println("Failed reading temperature from DHT"); + } + else if (temperature != lastTemp) + { + lastTemp = temperature; + if (!metric) + { + temperature = dht.toFahrenheit(temperature); + } + send(msg_Temp.set(temperature, 1)); + Serial.print("T: "); + Serial.println(temperature); + } + + float humidity = dht.getHumidity(); + if (isnan(humidity)) + { + Serial.println("Failed reading humidity from DHT"); + } + else if (humidity != lastHum) + { + lastHum = humidity; + send(msg_Hum.set(humidity, 1)); + Serial.print("H: "); + Serial.println(humidity); + } + + // Fetch temperatures from Dallas sensors + temp_sensors.requestTemperatures(); + + // Read temperatures and send them to controller + for (int i=0; i(static_cast((getConfig().isMetric?temp_sensors.getTempCByIndex(i):temp_sensors.getTempFByIndex(i)) * 10.)) / 10.; + float temperature = static_cast(static_cast((getControllerConfig().isMetric?temp_sensors.getTempCByIndex(i):temp_sensors.getTempFByIndex(i)) * 10.)) / 10.; + + // Only send data if temperature has changed and no error + if (lastTemperature[i] != temperature && temperature != -127.00) { + Serial.print("Dallas : "); + Serial.print(i); + Serial.print(" = "); + Serial.println(temperature); + // Send in the new temperature + send(msg_dallas.setSensor(i).set(temperature,1)); + lastTemperature[i]=temperature; + } + } + } + + //Door switch 1 + d1_debouncer.update(); + // Get the update value + d1_value = d1_debouncer.read(); + + if (d1_value != d1_oldValue) { + // Send in the new value + send(d1_msg.set(d1_value==HIGH ? 1 : 0), true); + wait(500); +// d1_oldValue = d1_value; + } + + //Door switch 2 + d2_debouncer.update(); + // Get the update value + d2_value = d2_debouncer.read(); + + if (d2_value != d2_oldValue) { + // Send in the new value + send(d2_msg.set(d2_value==HIGH ? 1 : 0), true); + wait(500); +// d2_oldValue = d2_value; + } + + //If milis goes to 0 + if(P_lastSend > currentTime) + P_lastSend = currentTime; + if(lastSend > currentTime) + lastSend = currentTime; + if(P_lastBlinkmillis > currentTime) + P_lastBlinkmillis = currentTime; + +} + +// Check incomming messages +void receive(const MyMessage &message) +{ + if (message.isAck()) + { + Serial.println("This is an ack from gateway"); + + //Check if Ack is from d1 + if(d1_oldValue != d1_value) + { + d1_oldValue = d1_value; + } + + //Check if Ack is from d2 + if(d2_oldValue != d2_value) + { + d2_oldValue = d2_value; + } + + } + + //If last know power value + if (message.sensor==P_CHILD_ID && message.type==V_VAR1) + { + P_pulseCount = P_oldPulseCount = message.getLong(); + Serial.print("Received last P_pulse count from gw:"); + Serial.println(P_pulseCount); + P_pcReceived = true; + } +} + +//Interrupt from powermeter +void P_onPulse() +{ + Serial.println("Powermeter"); + + unsigned long P_newBlink = millis(); + unsigned long P_interval = P_newBlink-P_lastBlink; + if (P_interval<10L) + { + // Sometimes we get interrupt on RISING + return; + } + P_watt = (3600000.0 /P_interval) / P_ppwh; + P_lastBlink = P_newBlink; + + P_lastBlinkmillis = millis(); + P_pulseCount++; +} +