1 changed files with 165 additions and 0 deletions
@ -0,0 +1,165 @@
@@ -0,0 +1,165 @@
|
||||
// Enable debug prints to serial monitor
|
||||
#define MY_DEBUG |
||||
#define MY_RADIO_NRF24 |
||||
//#define MY_NODE_ID 7
|
||||
|
||||
#include <SPI.h> |
||||
#include <MySensors.h> |
||||
|
||||
// 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<int>(((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++; |
||||
} |
||||
} |
||||
Loading…
Reference in new issue