-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathwatermeter_mysensors_v2.0_compatible
169 lines (143 loc) · 6.1 KB
/
watermeter_mysensors_v2.0_compatible
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
/*
* Sketch to read pulses from pulse meter;
* Only accepts a pulse change if the signal has been stable for more than x seconds;
* Only sends message to gateway after more than x seconds have passed since sending last message;
* Pulses are assumed to equal 1 liter of water
*
* Author Sandor Incze & Michel Schilthuizen
* Created 2016-05-29 * Version 1.0
* Created 2018-01-28 * Version 1.1 Mysensors 2.0+ Compatible
*
* Based on the flow reader sketch "WaterMeterPulseSensor" by
* Henrik Ekblad <[email protected]>
* Copyright (C) 2013-2015 Sensnology AB
* Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
*
* During testing in can be handy to be able to set the values in domoticz; You can do this by using the REST request below:
* (replace x.x.x.x and deviceid by relevant numbers
* http://x.x.x.x:8080/json.htm?type=command¶m=udevice&idx=deviceid&nvalue=0&svalue=0
*/
#define SKETCH_NAME "Watermeter 2.0.1+"
#define SKETCH_VERSION "1.01"
#define MY_DEBUG // Enable debug prints to serial monitor
#define IN_PIN 3 // PIN NUMBER OF DIGITAL OUTPUT TCRT5000
#define INTERRUPT_DEBOUNCE_DELAY 2
#define MY_RADIO_NRF24 // Enable and select radio type attached
// Flash leds on rx/tx/err
//#define MY_DEFAULT_LED_BLINK_PERIOD 300 // Set blinking period (in milliseconds)
//#define MY_DEFAULT_ERR_LED_PIN 4
//#define MY_DEFAULT_TX_LED_PIN 6 // I am using LED to display the activity TX on D5
//#define MY_DEFAULT_RX_LED_PIN 7 // I am using LED to display the activity RX on D6
#include <SPI.h>
#include <MySensors.h>
#define CHILD_ID_WATER 1 // ID of the Sensor
unsigned long SEND_FREQUENCY = 5000; // Minimum time between send (in milliseconds). We don't want to spam the gateway.
volatile double flow = 0;
boolean gw_received = false;
boolean seeninterrupt = false;
double flowSent =0;
unsigned long globalCounter =0;
unsigned long old_globalCounter =0;
unsigned long lastSent =0;
unsigned long lastPulse =0;
static volatile int last_pin_value = 0;
static volatile int stable_pin_value = 0;
static volatile int last_stable_pin_value = 0;
static unsigned long lastInterrupt = 0;
MyMessage flowMsg(CHILD_ID_WATER,V_FLOW);
MyMessage volumeMsg(CHILD_ID_WATER,V_VOLUME);
MyMessage lastCounterMsg(CHILD_ID_WATER,V_VAR1);
void setup() {
lastInterrupt = millis();
}
void presentation()
{
Serial.println(F("-- Init MySensors Brinks WTW"));
// Send the sketch version information to the gateway and Controller
sendSketchInfo(SKETCH_NAME, SKETCH_VERSION);
Serial.print(F("NodeID: "));
Serial.println(getNodeId());
present(CHILD_ID_WATER, S_WATER);
}
void loop() {
if (!gw_received) {
//Last Pulsecount not yet received from controller, request it again
Serial.println("Requesting as nothing was received from gateway yet!");
request(CHILD_ID_WATER, V_VAR1);
return;
}
else
{
int pin_value = digitalRead(IN_PIN);
// Calculate time passed since last interrupt
unsigned long timedifference = millis() - lastInterrupt;
// In case millis cycled to 0 (as it goes beyong max unsigned long) reset values
if (timedifference < 0)
{
lastInterrupt = 0;
timedifference = 0;
lastSent = 0;
}
if (pin_value != last_pin_value) //if the pin changes from high to low or low to high
{
Serial.println("Pin value different!");
lastInterrupt=millis();
last_pin_value = pin_value;
}
else if ((stable_pin_value != pin_value) && (timedifference >= (INTERRUPT_DEBOUNCE_DELAY * 1000))) //if stable pin is different from the pin and more than debounce delay has passed, switch stable pin
{
stable_pin_value = pin_value;
Serial.println("Stable pin value different!");
}
if ((stable_pin_value != last_stable_pin_value) && (stable_pin_value == HIGH))
{// Only raise counter if filtered pin value goes from 0 to 1
++globalCounter;
seeninterrupt = true;
Serial.print("Real Interrupt NOW; Global counter is now: "); // Debug Information will show the interrupt we will count.
Serial.println(globalCounter);
}
//reset last_stable_pin_value also when it has changed to LOW
if (stable_pin_value != last_stable_pin_value)
{
last_stable_pin_value = stable_pin_value;
}
//if we have seen an interrupt and the send frequency has passed, send message to gateway;
//Also send a message if last message has been sent more than x seconds ago and flow is still more than 0
if ( (gw_received) && (millis() - lastSent > SEND_FREQUENCY)
&& (seeninterrupt || flowSent > 0))
{
double liters = globalCounter - old_globalCounter;
float minutes_passed = 1.0 * (millis()- lastSent) / 60000.0;
double liters_per_minute = 1.0 * liters / minutes_passed;
flowSent = liters_per_minute;
Serial.print("Minutes Passed: ");
Serial.println(minutes_passed);
Serial.print("Aantal Liters: ");
Serial.println(liters);
Serial.print("Liters per Minuut: ");
Serial.println(liters_per_minute);
send(lastCounterMsg.set(globalCounter)); // Send globalcounter value to gw in VAR1
send(flowMsg.set(liters_per_minute, 2)); // Send flow value to gw
send(volumeMsg.set(1.0 * globalCounter / 1000, 3)); // Send volume value to gw and convert from dm3 to m3
seeninterrupt = false;
lastSent = millis();
old_globalCounter = globalCounter;
}
}
}
void receive(const MyMessage &message) {
unsigned long gwPulseCount = 0;
if (message.type==V_VAR1) {
gwPulseCount=message.getULong();
if (globalCounter != gwPulseCount)
{
globalCounter += gwPulseCount;
Serial.print("Received last pulse count from gw: ");
Serial.println(globalCounter);
//use line below to reset your counter in domoticz; We needed it ;-)
//globalCounter = 0;
gw_received = true;
old_globalCounter = globalCounter;
}
}
}