Hello
Here is my last code for my gas meter. If it could help somebody
/*
* The MySensors Arduino library handles the wireless radio link and protocol
* between your home built sensors/actuators and HA controller of choice.
* The sensors forms a self healing radio network with optional repeaters. Each
* repeater and gateway builds a routing tables in EEPROM which keeps track of the
* network topology allowing messages to be routed to nodes.
*
* Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
* Copyright (C) 2013-2018 Sensnology AB
* Full contributor list: https://github.com/mysensors/MySensors/graphs/contributors
*
* Documentation: http://www.mysensors.org
* Support Forum: http://forum.mysensors.org
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*
*******************************
*
* REVISION HISTORY
* Version 1.0 - Henrik Ekblad
* Version 1.1 - GizMoCuz
*
* DESCRIPTION
* Use this sensor to measure volume and flow of your house water meter.
* You need to set the correct pulsefactor of your meter (pulses per m3).
* The sensor starts by fetching current volume reading from gateway (VAR 1).
* 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.
* http://www.mysensors.org/build/pulse_water
*/
// Enable debug prints to serial monitor
#define MY_DEBUG
// Enable and select radio type attached
#define MY_RADIO_RF24
#include <MySensors.h>
#define DIGITAL_INPUT_SENSOR 3 // The digital input you attached your sensor. (Only 2 and 3 generates interrupt!)
#define CHILD_ID 1 // Id of the sensor child
unsigned long loopNumber = 0;
unsigned long lastLoopSend = 0;
MyMessage volumeMsg(CHILD_ID, V_VOLUME);
MyMessage lastCounterMsg(CHILD_ID, V_VAR1);
volatile uint32_t pulseCount = 0;
bool pcReceived = false;
double volume = 0;
//=========================
// BATTERY MEASURER
// 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.2 // Vmin (radio Min Volt)=1.9V (564v)
#define VMAX 3.2 // Vmax = (2xAA bat)=3.0V (892v)
int batteryPcnt = 0; // Calc value for battery %
int batLoop = 0; // Loop to help calc average
int batArray[4]; // Array to store value for average calc.
int BATTERY_SENSE_PIN = A0; // select the input pin for the battery sense point
//=========================
void setup() {
// initialize our digital pins internal pullup resistor so one pulse switches from high to low (less distortion)
pinMode(DIGITAL_INPUT_SENSOR, INPUT_PULLUP);
pulseCount = 0;
// Fetch last known pulse count value from gw
request(CHILD_ID, V_VAR1);
//Battery
analogReference(INTERNAL);
Serial.print("With Battery VMax (100%) = "); Serial.print(VMAX); Serial.print("volts and Vmin (0%) = "); Serial.print(VMIN); Serial.println(" volts");
Serial.print("Battery Percent 25%/50%/75% calculates to: "); Serial.print(((VMAX - VMIN) / 4) + VMIN); Serial.print("/"); Serial.print(((VMAX - VMIN) / 2) + VMIN); Serial.print("/"); Serial.println(VMAX - ((VMAX - VMIN) / 4));
delay(1000);
int sensorValue = analogRead(BATTERY_SENSE_PIN);
delay(50);
float Vbat = sensorValue * VBAT_PER_BITS;
int batteryPcnt = static_cast<int>(((Vbat - VMIN) / (VMAX - VMIN)) * 100.);
Serial.print("Current battery are measured to (please confirm!): "); Serial.print(batteryPcnt); Serial.print(" % - Or "); Serial.print(Vbat); Serial.println(" Volts");
}
void presentation()
{
// Send the sketch version information to the gateway and Controller
sendSketchInfo("Gas Meter", "2.0");
// Register this device as Water flow sensor
present(CHILD_ID, S_GAS);
}
//=========================
// BATTERY MEASURER
void MeasureBattery() //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.print(" %"); Serial.print("Battery Voltage: "); Serial.print(Vbat); Serial.println(" Volts");
// Add it to array so we get an average of 3 (3x20min)
batArray[batLoop] = batteryPcnt;
if (batLoop > 2) {
batteryPcnt = (batArray[0] + batArray[1] + batArray[2] + batArray[3]);
batteryPcnt = batteryPcnt / 4;
if (batteryPcnt > 100) {
batteryPcnt = 100;
}
Serial.print("Battery Average (Send): "); Serial.print(batteryPcnt); Serial.println(" %");
sendBatteryLevel(batteryPcnt);
batLoop = 0;
}
else
{
batLoop++;
}
}
void loop() {
if (!pcReceived) {
//Last Pulsecount not yet received from controller, request it again
request(CHILD_ID, V_VAR1);
wait(1000);
return;
}
Serial.print("loopNumer=");
Serial.println(loopNumber);
if (loopNumber % 60 == 0) {
Serial.println("Measuring Battery");
//=========================
// BATTERY MEASURER
MeasureBattery();
//=========================
}
if (loopNumber % 10 == 0) {
Serial.println("Sending pulse Count");
volume = ((double)pulseCount / ((double)1000));
send(volumeMsg.set(volume,4));
send(lastCounterMsg.set(pulseCount));
}
Serial.println("I'm sleeping");
int8_t cause = sleep(digitalPinToInterrupt(DIGITAL_INPUT_SENSOR), FALLING, 60000);
Serial.print("WakeUp , cause:");
Serial.print(cause);
Serial.print("(pin interrupt :");
Serial.print(digitalPinToInterrupt(DIGITAL_INPUT_SENSOR));
Serial.println(";-1=timer)");
if (cause == digitalPinToInterrupt(DIGITAL_INPUT_SENSOR)) {
pulseCount++;
wait(100);
}
Serial.print("Pulsecount=");
Serial.println(pulseCount);
loopNumber++;
}
void receive(const MyMessage &message)
{
if (message.type==V_VAR1) {
uint32_t gwPulseCount=message.getULong();
pulseCount += gwPulseCount;
Serial.print("Received last pulse count from gw:");
Serial.println(pulseCount);
pcReceived = true;
}
}```