From 5dde74354f231d0b18c1e30a54ec6722b4438710 Mon Sep 17 00:00:00 2001 From: scayac Date: Thu, 23 Jun 2022 21:55:52 +0200 Subject: [PATCH] Premier commit --- Raingauge-MySensors.ino | 165 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 165 insertions(+) create mode 100644 Raingauge-MySensors.ino diff --git a/Raingauge-MySensors.ino b/Raingauge-MySensors.ino new file mode 100644 index 0000000..5b31f1b --- /dev/null +++ b/Raingauge-MySensors.ino @@ -0,0 +1,165 @@ +// Enable debug prints to serial monitor +#define MY_DEBUG +#define MY_RADIO_NRF24 +//#define MY_NODE_ID 7 + +#include +#include + +// Running this in Domoticz stable version 2.5 will not work - upgrade to beta. + +#define DIGITAL_INPUT_SENSOR 3 // The reed switch you attached. (Only 2 and 3 generates interrupt!) +#define INTERRUPT DIGITAL_INPUT_SENSOR-2 // Usually the interrupt = pin -2 (on uno/nano anyway) + +#define CHILD_ID 1 // Id of the sensor child +#define SKETCH_NAME "Rain Gauge" // Change to a fancy name you like +#define SKETCH_VERSION "1.1" // Your version + +//unsigned long SLEEP_TIME = 18*60000; // Sleep time (in milliseconds). +unsigned long SLEEP_TIME = 20000; // use this instead for debug + +float hwRainVolume = 0; // Current rainvolume calculated in hardware. +int hwPulseCounter = 0; // Pulsecount recieved from GW +float fullCounter = 0; // Counts when to send counter +float bucketSize = 0.32; // Bucketsize mm, needs to be 1, 0.5, 0.25, 0.2 or 0.1 +boolean pcReceived = false; // If we have recieved the pulscount from GW or not +boolean reedState; // Current state the reedswitch is in +boolean oldReedState; // Old state (last state) of the reedswitch +unsigned long lastSend =0; // Time we last tried to fetch counter. + +MyMessage volumeMsg(CHILD_ID,V_RAIN); +MyMessage lastCounterMsg(CHILD_ID,V_VAR1); + +//========================= +// BATTERY VOLTAGE DIVIDER SETUP +// 1M, 470K 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)/470e3)*1.1 = Vmax = 3.44 Volts +// 3.44/1023 = Volts per bit = 0.003363075 +#define VBAT_PER_BITS 0.003363075 +#define VMIN 2.0 // Vmin (radio Min Volt)=1.9V (564v) +#define VMAX 4.2 // Vmax = (2xAA bat)=3.0V (892v) +int batteryPcnt = 0; // Calc value for battery % +int batLoop = 0; // Loop to help calc average +int batArray[3]; // Array to store value for average calc. +int BATTERY_SENSE_PIN = A0; // select the input pin for the battery sense point +//========================= + +void presentation() { + + // Send the Sketch Version Information to the Gateway + sendSketchInfo(SKETCH_NAME, SKETCH_VERSION); + + // Register this device as Rain sensor (will not show in Domoticz until first value arrives) + present(CHILD_ID, S_RAIN); +} + + +void setup() +{ + // use the 1.1 V internal reference + analogReference(INTERNAL); // For battery sensing + + pinMode(DIGITAL_INPUT_SENSOR, INPUT_PULLUP); // sets the reed sensor digital pin as input + + reedState = digitalRead(DIGITAL_INPUT_SENSOR); // Read what state the reedswitch is in + oldReedState = reedState; // Set startup position for reedswitch + + Serial.println("Startup completed"); +} + +void loop() +{ +unsigned long currentTime = millis(); + + //See if we have the counter/pulse from Domoticz - and ask for it if we dont. + if (!pcReceived && (currentTime - lastSend > 5000)) { + request(CHILD_ID, V_VAR1); + lastSend=currentTime; + return; + } + if (!pcReceived) { + return; + } + +//Read if the bucket tipped over +reedState = digitalRead(DIGITAL_INPUT_SENSOR); +boolean tipped = oldReedState != reedState; + + //BUCKET TIPS! + if (tipped==true) { + Serial.println("The bucket has tipped over..."); + oldReedState = reedState; + hwRainVolume = hwRainVolume + bucketSize; + send(volumeMsg.set((float)hwRainVolume,1)); + wait(1000); + fullCounter = fullCounter + bucketSize; + + //Count so we send the counter for every 1mm + if(fullCounter >= 1){ + hwPulseCounter++; + send(lastCounterMsg.set(hwPulseCounter)); + wait(1000); + fullCounter = 0; + } + + } + + if (tipped==false) { + + //No bucket tipped over last sleep-period, check battery then... + //batM(); + } + +lastSend=currentTime; +sleep(INTERRUPT, CHANGE, SLEEP_TIME); +//The interupt can be CHANGE or FALLING depending on how you wired the hardware. +} + +//Read if we have a incoming message. +void receive(const MyMessage &msg) { + if (msg.type==V_VAR1) { + hwPulseCounter = msg.getULong(); + hwRainVolume = hwPulseCounter; + pcReceived = true; + Serial.print("Received last pulse count from gw: "); + Serial.println(hwPulseCounter); + } +} + +void batM(){ //The battery calculations + + delay(500); + // Battery monitoring reading + int sensorValue = analogRead(BATTERY_SENSE_PIN); + delay(500); + + // Calculate the battery in % + float Vbat = sensorValue * VBAT_PER_BITS; + int batteryPcnt = static_cast(((Vbat-VMIN)/(VMAX-VMIN))*100.); + Serial.print("Battery percent: "); Serial.print(batteryPcnt); Serial.println(" %"); + + // Add it to array so we get an average of 3 (3x20min) + batArray[batLoop] = batteryPcnt; + + if (batLoop > 1) { + batteryPcnt = (batArray[0] + batArray[1] + batArray[2]); + batteryPcnt = batteryPcnt / 3; + + if (batteryPcnt > 100) { + batteryPcnt=100; + } + + Serial.print("Battery Average (Send): "); Serial.print(batteryPcnt); Serial.println(" %"); + sendBatteryLevel(batteryPcnt); + batLoop = 0; + + //Sends 1 per hour as a heartbeat. + send(volumeMsg.set((float)hwRainVolume,1)); + send(lastCounterMsg.set(hwPulseCounter)); + } + else + { + batLoop++; + } +}