Below the new code, it also uses the eprom memory to load/save the pulsecount, which is much better then requesting this from the host software (domoticz),ThinkPad wrote:I think i am already seeing that. Connected 'MYSController' to the Ethernet gateway i made, and i see the application constantly scrolling, only thing it displays is:
RECV REQ VAR1
Nice, looking forward to it! Let us know if we can help in any way
in case its down for whatever reason
A new beta is building at the moment (will take at least 15 minutes), please let us know if you got it working !
Code: Select all
//
// Use this sensor to measure volume and flow of your house watermeter.
// You need to set the correct pulsefactor of your meter (pulses per m3).
// The sensor starts by reading the pulse count reading from the eprom.
// Reports both volume and flow 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 flow.
//
#include <SPI.h>
#include <MySensor.h>
#define DIGITAL_INPUT_SENSOR 3 // The digital input you attached your sensor. (Only 2 and 3 generates interrupt!)
#define PULSE_FACTOR 1000 // Nummber of blinks per m3 of your meter (One rotation/liter)
#define SLEEP_MODE false // flowvalue can only be reported when sleep mode is false.
#define MAX_FLOW 40 // Max flow (l/min) value to report. This filters outliers.
#define CHILD_ID 1 // Id of the sensor child
unsigned long SEND_FREQUENCY = 20000; // Minimum time between send (in milliseconds). We don't want to spam the gateway.
#define EPROM_PULSECOUNT_1_STATE 1
#define EPROM_PULSECOUNT_2_STATE 2
#define EPROM_PULSECOUNT_3_STATE 3
#define EPROM_PULSECOUNT_4_STATE 4
MySensor gw;
MyMessage flowMsg(CHILD_ID,V_FLOW);
MyMessage volumeMsg(CHILD_ID,V_VOLUME);
double ppl = ((double)PULSE_FACTOR)/1000; // Pulses per liter
volatile unsigned long pulseCount = 0;
volatile unsigned long lastBlink = 0;
volatile double flow = 0;
boolean pcReceived = false;
unsigned long oldPulseCount = 0;
unsigned long newBlink = 0;
double oldflow = 0;
double volume;
double oldvolume;
unsigned long lastSend;
unsigned long lastPulse;
unsigned long currentTime;
boolean metric;
void setup()
{
gw.begin();
// Send the sketch version information to the gateway and Controller
gw.sendSketchInfo("Water Meter", "1.1");
// Register this device as Waterflow sensor
gw.present(CHILD_ID, S_WATER);
//Retreive our last pulse count value from the eprom
pulseCount = oldPulseCount = LoadLastPulseCount();
lastSend = millis();
attachInterrupt(1, onPulse, RISING);
}
void loop()
{
gw.process();
currentTime = millis();
// Only send values at a maximum frequency or woken up from sleep
bool sendTime = (currentTime - lastSend) > SEND_FREQUENCY;
if (SLEEP_MODE || sendTime)
{
lastSend=currentTime;
if (!SLEEP_MODE && flow != oldflow) {
oldflow = flow;
//Serial.print("l/min:");
//Serial.println(flow);
// Check that we dont get unresonable large flow value.
// could hapen when long wraps or false interrupt triggered
if (flow<((unsigned long)MAX_FLOW)) {
gw.send(flowMsg.set(flow, 2)); // Send flow value to gw
}
}
// No Pulse count in 2min
if(currentTime - lastPulse > 120000){
flow = 0;
}
// Pulse count has changed
if (pulseCount != oldPulseCount) {
oldPulseCount = pulseCount;
SaveLastPulseCount(pulseCount);
//Serial.print("pulsecount:");
//Serial.println(pulseCount);
double volume = ((double)pulseCount/((double)PULSE_FACTOR));
if (volume != oldvolume) {
//Serial.print("volume:");
//Serial.println(volume, 3);
gw.send(volumeMsg.set(volume, 3)); // Send volume value to gw
oldvolume = volume;
}
}
}
if (SLEEP_MODE) {
gw.sleep(SEND_FREQUENCY);
}
}
unsigned long LoadLastPulseCount()
{
int PCount_1=gw.loadState(EPROM_PULSECOUNT_1_STATE);
int PCount_2=gw.loadState(EPROM_PULSECOUNT_2_STATE);
int PCount_3=gw.loadState(EPROM_PULSECOUNT_3_STATE);
int PCount_4=gw.loadState(EPROM_PULSECOUNT_4_STATE);
//check if valid
if ((PCount_1==0xFF)&&(PCount_2==0xFF)&&(PCount_3==0xFF)&&(PCount_4==0xFF))
return 0;//never saved before
unsigned long PulseCount=(PCount_1<<24)|(PCount_2<<16)|(PCount_3<<8)|PCount_4;
//Serial.print("Last Pulsecount: ");
//Serial.println(PulseCount);
return PulseCount;
}
void SaveLastPulseCount(unsigned long PulseCount)
{
int PCount_1=(PulseCount&0xFF000000)>>24;
int PCount_2=(PulseCount&0xFF0000)>>16;
int PCount_3=(PulseCount&0xFF00)>>8;
int PCount_4=PulseCount&0xFF;
gw.saveState(EPROM_PULSECOUNT_1_STATE, PCount_1);
gw.saveState(EPROM_PULSECOUNT_2_STATE, PCount_2);
gw.saveState(EPROM_PULSECOUNT_3_STATE, PCount_3);
gw.saveState(EPROM_PULSECOUNT_4_STATE, PCount_4);
}
void onPulse()
{
if (!SLEEP_MODE)
{
unsigned long newBlink = micros();
unsigned long interval = newBlink-lastBlink;
if (interval!=0)
{
lastPulse = millis();
if (interval<500000L) {
// Sometimes we get interrupt on RISING, 500000 = 0.5sek debounce ( max 120 l/min)
return;
}
flow = (60000000.0 /interval) / ppl;
}
lastBlink = newBlink;
}
pulseCount++;
}