Create Meterkast.ino
This commit is contained in:
commit
991836005e
319
Meterkast.ino
Normal file
319
Meterkast.ino
Normal file
@ -0,0 +1,319 @@
|
||||
// Use this sensor to measure KWH and Watt of your house meeter
|
||||
// You need to set the correct pulsefactor of your meeter (blinks per KWH).
|
||||
// The sensor starts by fetching current KWH value from gateway.
|
||||
// Reports both KWH and Watt back to gateway.
|
||||
//
|
||||
// Unfortunately millis() won't increment when the Arduino is in
|
||||
// sleepmode. So we cannot make this sensor sleep if we also want
|
||||
// to calculate/report watt-number.
|
||||
|
||||
// Enable debug prints to serial monitor
|
||||
#define MY_DEBUG
|
||||
|
||||
// Enable and select radio type attached
|
||||
#define MY_RADIO_NRF24
|
||||
|
||||
//#include <SPI.h>
|
||||
#include <MySensors.h>
|
||||
#include <Bounce2.h>
|
||||
|
||||
#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 W_DIGITAL_INPUT_SENSOR 4 // The digital input you attached your sensor. (Only 2 and 3 generates interrupt!)
|
||||
|
||||
//#define P_PULSE_FACTOR 1000 // Nummber of blinks per KWH of your meeter
|
||||
#define W_PULSE_FACTOR 2000 // Nummber of blinks per m3 of your meter (One rotation/liter)
|
||||
|
||||
#define SLEEP_MODE false // Watt-value can only be reported when sleep mode is false.
|
||||
//#define MAX_WATT 10000 // Max watt value to report. This filetrs outliers.
|
||||
#define W_MAX_FLOW 40 // Max flow (l/min) value to report. This filters outliers.
|
||||
|
||||
//#define P_CHILD_ID 1 // Id of the sensor child
|
||||
#define W_CHILD_ID 2 // Id of the sensor child
|
||||
|
||||
//unsigned long P_SEND_FREQUENCY = 20000; // Minimum time between send (in milliseconds). We don't wnat to spam the gateway.
|
||||
unsigned long W_SEND_FREQUENCY = 60000; // Minimum time between send (in milliseconds). We don't wnat to spam the gateway.
|
||||
|
||||
//Deurbel
|
||||
unsigned long T_DEURBEL_ON = 700;
|
||||
unsigned long t_deurbel;
|
||||
boolean deurbel_on = false;
|
||||
boolean Bel_Disabled = false;
|
||||
|
||||
//MySensor gw;
|
||||
boolean W_pcReceived = false;
|
||||
|
||||
double W_ppl = ((double)W_PULSE_FACTOR)/1000; // Pulses per liter
|
||||
volatile unsigned long W_pulseCount = 0;
|
||||
volatile unsigned long W_lastBlink = 0;
|
||||
volatile double W_flow = 0;
|
||||
unsigned long W_oldPulseCount = 0;
|
||||
unsigned long W_newBlink = 0;
|
||||
double W_oldflow = 0;
|
||||
double W_volume =0;
|
||||
double W_oldvolume =0;
|
||||
unsigned long W_lastPulse =0;
|
||||
|
||||
boolean W_puls = false;
|
||||
boolean W_prevpuls = false;
|
||||
|
||||
unsigned long W_lastSend;
|
||||
|
||||
MyMessage flowMsg(W_CHILD_ID,V_FLOW);
|
||||
MyMessage volumeMsg(W_CHILD_ID,V_VOLUME);
|
||||
MyMessage lastCounterMsg(W_CHILD_ID,V_VAR1);
|
||||
|
||||
//Deur en deurbel
|
||||
#define d1_BUTTON_PIN 5 // Arduino Digital I/O pin for button/reed switch voordeur
|
||||
#define d2_BUTTON_PIN 6 // Arduino Digital I/O pin for button/reed switch deurbel drukker
|
||||
#define d1_CHILD_ID 11 // Id voordeur contact
|
||||
#define d2_CHILD_ID 12 // Id deurbel drukker
|
||||
|
||||
#define O_DEURBEL_PIN 7 // Output relais deurbel
|
||||
#define O_BUZZER_PIN 8 // Output buzzer
|
||||
#define BEL_CHILD_ID 12 // ID deurbel relais
|
||||
#define DIS_DEURBEL_CHILD_ID 13 // ID deurbel disable
|
||||
#define BUZZER_CHILD_ID 99 // ID Buzzer
|
||||
|
||||
//Declare deuren
|
||||
Bounce d1_debouncer = Bounce();
|
||||
int d1_oldValue=-1;
|
||||
Bounce d2_debouncer = Bounce();
|
||||
int d2_oldValue=-1;
|
||||
|
||||
|
||||
MyMessage d1_msg(d1_CHILD_ID,V_TRIPPED);
|
||||
MyMessage d2_msg(d2_CHILD_ID,V_LIGHT);
|
||||
MyMessage BEL_msg(BEL_CHILD_ID, V_LIGHT);
|
||||
MyMessage DIS_DEURBEL_msg(DIS_DEURBEL_CHILD_ID, V_LIGHT);
|
||||
MyMessage BUZZER_msg(BUZZER_CHILD_ID, V_LIGHT);
|
||||
|
||||
void setup()
|
||||
{
|
||||
pinMode(W_DIGITAL_INPUT_SENSOR, INPUT); // set pin to input
|
||||
digitalWrite(W_DIGITAL_INPUT_SENSOR, HIGH); // turn on pullup resistors
|
||||
|
||||
// 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(100);
|
||||
|
||||
// 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(20);
|
||||
|
||||
// Setup the deurbel relais
|
||||
pinMode(O_DEURBEL_PIN,OUTPUT);
|
||||
digitalWrite(O_DEURBEL_PIN, false);
|
||||
|
||||
// Setup the buzzer
|
||||
pinMode(O_BUZZER_PIN,OUTPUT);
|
||||
|
||||
W_lastSend=millis();
|
||||
}
|
||||
|
||||
void presentation()
|
||||
{
|
||||
// Send the sketch version information to the gateway and Controller
|
||||
sendSketchInfo("Meterkast", "2.1");
|
||||
|
||||
// Register this device as power sensor
|
||||
present(W_CHILD_ID, S_WATER);
|
||||
|
||||
// Fetch last known pulse count value from gw
|
||||
request(W_CHILD_ID, V_VAR1);
|
||||
|
||||
//present Voordeur
|
||||
present(d1_CHILD_ID, S_DOOR);
|
||||
//present Deurbel drukknop
|
||||
present(d2_CHILD_ID, S_LIGHT);
|
||||
//present Deurbel disable
|
||||
present(DIS_DEURBEL_CHILD_ID, S_LIGHT);
|
||||
send(DIS_DEURBEL_msg.set(0));
|
||||
//present Deurbel relais
|
||||
present(BEL_CHILD_ID, S_LIGHT);
|
||||
//present BUZZER
|
||||
present(BUZZER_CHILD_ID, S_LIGHT);
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
unsigned long now = millis();
|
||||
//unsigned long currentTime = millis();
|
||||
|
||||
//Read watermeter input
|
||||
W_puls = digitalRead(W_DIGITAL_INPUT_SENSOR);
|
||||
if (W_puls != W_prevpuls)
|
||||
{
|
||||
Serial.println("Water puls ontvangen");
|
||||
W_onPulse();
|
||||
W_prevpuls = W_puls;
|
||||
}
|
||||
|
||||
// Only send values at a maximum frequency or woken up from sleep
|
||||
bool W_sendTime = now - W_lastSend > W_SEND_FREQUENCY;
|
||||
if (W_pcReceived && W_sendTime)
|
||||
{
|
||||
if (W_flow != W_oldflow)
|
||||
{
|
||||
W_oldflow = W_flow;
|
||||
|
||||
Serial.print("l/min:");
|
||||
Serial.println(W_flow);
|
||||
|
||||
// Check that we dont get unresonable large flow value.
|
||||
// could hapen when long wraps or false interrupt triggered
|
||||
if (W_flow<((unsigned long)W_MAX_FLOW))
|
||||
{
|
||||
send(flowMsg.set(W_flow, 2)); // Send flow value to gw
|
||||
}
|
||||
}
|
||||
|
||||
// No Pulse count received in 2min
|
||||
if(now - W_lastPulse > 120000){
|
||||
W_flow = 0;
|
||||
}
|
||||
|
||||
// Pulse count has changed
|
||||
if (W_pulseCount != W_oldPulseCount) {
|
||||
W_oldPulseCount = W_pulseCount;
|
||||
|
||||
Serial.print("W_pulsecount:");
|
||||
Serial.println(W_pulseCount);
|
||||
|
||||
send(lastCounterMsg.set(W_pulseCount)); // Send pulsecount value to gw in VAR1
|
||||
|
||||
double W_volume = ((double)W_pulseCount/((double)W_PULSE_FACTOR));
|
||||
if (W_volume != W_oldvolume) {
|
||||
W_oldvolume = W_volume;
|
||||
|
||||
Serial.print("volume:");
|
||||
Serial.println(W_volume, 3);
|
||||
|
||||
send(volumeMsg.set(W_volume, 3)); // Send volume value to gw
|
||||
}
|
||||
}
|
||||
|
||||
W_lastSend = now;
|
||||
}
|
||||
else if (W_sendTime && !W_pcReceived)
|
||||
{
|
||||
// No count received. Try requesting it again
|
||||
request(W_CHILD_ID, V_VAR1);
|
||||
W_lastSend=now;
|
||||
}
|
||||
|
||||
//Door switch 1
|
||||
d1_debouncer.update();
|
||||
// Get the update value
|
||||
int d1_value = d1_debouncer.read();
|
||||
//If door status changed
|
||||
if (d1_value != d1_oldValue)
|
||||
{
|
||||
// Send in the new value
|
||||
send(d1_msg.set(d1_value==HIGH ? 1 : 0));
|
||||
d1_oldValue = d1_value;
|
||||
}
|
||||
|
||||
//Door switch 2 - Deurbel
|
||||
d2_debouncer.update();
|
||||
// Get the update value
|
||||
int d2_value = d2_debouncer.read();
|
||||
//If door status changed
|
||||
if (d2_value != d2_oldValue)
|
||||
{
|
||||
|
||||
if (d2_value == HIGH)
|
||||
{
|
||||
digitalWrite(O_DEURBEL_PIN, false);
|
||||
deurbel_on = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(Bel_Disabled==false)
|
||||
{
|
||||
Serial.print("!! Deurbel !!");
|
||||
digitalWrite(O_DEURBEL_PIN, true);
|
||||
t_deurbel = millis();
|
||||
deurbel_on = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Send in the new value
|
||||
send(d2_msg.set(d2_value==HIGH ? 0 : 1));
|
||||
d2_oldValue = d2_value;
|
||||
}
|
||||
|
||||
if(deurbel_on == true && (t_deurbel + T_DEURBEL_ON < now))
|
||||
{
|
||||
digitalWrite(O_DEURBEL_PIN, false);
|
||||
deurbel_on = false;
|
||||
}
|
||||
|
||||
if(W_lastSend > now)
|
||||
W_lastSend = now;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Check incomming messages
|
||||
void receive(const MyMessage &message)
|
||||
{
|
||||
//If last know water value
|
||||
if (message.sensor==W_CHILD_ID && message.type==V_VAR1) {
|
||||
W_pulseCount = W_oldPulseCount = message.getLong();
|
||||
Serial.print("Received last W_pulse count from gw:");
|
||||
Serial.println(W_pulseCount);
|
||||
W_pcReceived = true;
|
||||
}
|
||||
|
||||
//Message of type V_LIGHT ?
|
||||
if (message.type==V_LIGHT)
|
||||
{
|
||||
if (message.sensor==DIS_DEURBEL_CHILD_ID)
|
||||
{
|
||||
if(message.getBool()==1)
|
||||
{
|
||||
Bel_Disabled = true;
|
||||
Serial.println("Domoticz --> Deurbel Disabled !!");
|
||||
}
|
||||
else
|
||||
{
|
||||
Bel_Disabled = false;
|
||||
Serial.println("Domoticz --> Deurbel Enabled !!");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
//Puls from watermeter
|
||||
void W_onPulse()
|
||||
{
|
||||
Serial.println("Watermeter");
|
||||
|
||||
unsigned long W_newBlink = micros();
|
||||
unsigned long W_interval = W_newBlink-W_lastBlink;
|
||||
|
||||
W_lastBlink = W_newBlink;
|
||||
|
||||
if (W_interval!=0)
|
||||
{
|
||||
W_lastPulse = millis();
|
||||
if (W_interval<250000L)
|
||||
{
|
||||
// Sometimes we get interrupt on RISING, 500000 = 0.5sek debounce ( max 120 l/min)
|
||||
return;
|
||||
}
|
||||
W_flow = (60000000.0 /W_interval) / W_ppl;
|
||||
W_pulseCount++;
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user