Pluviomètre arduino + nrf24l01 MySensors
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

165 lines
5.6 KiB

// 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++;
}
}