Double watermeter on NodeMCU
-
Objective of this project is to survey abnormal flowrate on the 2 main usage of water : home and garden (I had last year a abnormal bill of about 400m3 ....).
Existing installation :
- Raspberry Pi3
- Domoticz
- Livebox ADSL
- Router Synology RT1900ac
- Oregon sensor temperature
- OWL CM180
I use ESP8266 on a NodeMCU dev kit with MySensors 2.2 librarie
Power is provided by a standart USB supplyWatermeter : G. GIOANOLA USLF/20 with reed switch cable 2.5m3/h 1 pulse/liter
- 2 independants counter for each way, count of total volume (m3) and flowrate (l/mn)
- reset on board by push button for all counter
- separate soft reset for each way counters from Domoticz
- save counters on EEPROM every 5h (in case of long time WiFi lost)
- switch rebounce corrected by small soft
- send result by WiFi to Domoticz
Very simple schema :
And also box:
and sketch :
//============================================================== // DOUBLE WATERMETER using WiFi // // - Count Volume and Flowrate for 2 physical watermeter by reed switch // - send values every 1 mn through WiFi // - possible hard reset of the 2 counters by switch on board // - possible of soft reset for each counter from Domoticz // - save values every about each 5h on EEPROM (in case of lost local network) // - soft treatement about debouncing reed switch // // material and soft : // - watermeter G. GIOANOLA 2.5 m3/h - 1 pulse / liter // - ESP8266 on NodeMCU dev kit // - MySensors 2.20 librarie // - Domoticz 3.8153 // - Raspberry Pi 3 // - use a static IP in the local network // // Objectives : // Verify leakage and usage for home and garden, send alerte // // All constant on this sketch are adapted to a max flowrate of 2.5 m3/h // // Philippe Marsault / France //============================================================== // // References : // // MySensors Library // https://www.mysensors.org/download/sensor_api_20 // // Article decrivant la transmission EDF Linky Arduino en protocole OWL180 // http://domotique.web2diz.net/teleinfo-edf-arduino-sans-fil-avec-rfxcom/ // // Présentation de l’ESP8266 // https://www.ekito.fr/people/presentation-de-l-esp8266/ // // Utilisation de l'EEPROM // https://www.carnetdumaker.net/articles/stocker-des-donnees-en-memoire-eeprom-avec-une-carte-arduino-genuino/ // Sinon voir fonctions "savestate" et "loadstate" de la bibliothèque Mysensors // (save et load operent seulement sur 1 byte) // https://www.mysensors.org/apidocs-beta/group__MySensorsCoregrp.html#ga07bd2de06f11e34fca1fa77621d164ec // // NodeMcu v1.0 (ESP8266 12E) store/read a value from EEPROM // http://www.esp8266.com/viewtopic.php?p=66197 // // Documentation nodeMCU // https://nodemcu.readthedocs.io/en/master/ // https://tttapa.github.io/ESP8266/Chap01%20-%20ESP8266.html // // Chargement des caractéristiques de carte NodeMCU ESP12E // https://github.com/arduino/Arduino/wiki/Unofficial-list-of-3rd-party-boards-support-urls // // Building a WiFi Gateway using ESP8266 // https://www.mysensors.org/build/esp8266_gateway // https://projetsdiy.fr/mysensors-version2-decouverte-nouveautes-convertir-sketch/ // // Driver Windows 10 du CP210x (port USB de la carte NodeMCU) (pour raccordement au PC) // https://www.silabs.com/products/development-tools/software/usb-to-uart-bridge-vcp-drivers // // Utilisation des PIN avec Interrupt // http://www.electronicwings.com/nodemcu/nodemcu-gpio-interrupts-with-arduino-ide // Debouncing switch // https://www.microcontrollertips.com/debouncing-switches-in-hardware-and-software-faq/ // http://www.ganssle.com/debouncing-pt2.htm // // Charger le driver CH340G pour connecter NodeMCU a un PC Win 10 // Installer l'interface de developpement Arduino IDE sur https://www.arduino.cc // Connecter PC et carte Nodemcu avec un cable micro USB (pour smartphone) // programmation : appuyer sur la touche FLASH puis sur RESET et relacher FLASH // // Utilisation avec Domoticz // https://projetsdiy.fr/mysensors-v2-gateway-wifi-esp8266-jeedom-domoticz/#Preparer_le_programme_de_la_Gateway // Configurer avec une adresse IP fixe (option recommandée) // //============================================================== // // MYSENSORS librarie // /** * 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-2015 Sensnology AB * Full contributor list: https://github.com/mysensors/Arduino/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 * Contribution by a-lurker and Anticimex, * Contribution by Norbert Truchsess <norbert.truchsess@t-online.de> * Contribution by Ivo Pullens (ESP8266 support) * * DESCRIPTION * The EthernetGateway sends data received from sensors to the WiFi link. * The gateway also accepts input on ethernet interface, which is then sent out to the radio network. * * VERA CONFIGURATION: * Enter "ip-number:port" in the ip-field of the Arduino GW device. This will temporarily override any serial configuration for the Vera plugin. * E.g. If you want to use the defualt values in this sketch enter: 192.168.178.66:5003 * * LED purposes: * - To use the feature, uncomment any of the MY_DEFAULT_xx_LED_PINs in your sketch, only the LEDs that is defined is used. * - RX (green) - blink fast on radio message recieved. In inclusion mode will blink fast only on presentation recieved * - TX (yellow) - blink fast on radio message transmitted. In inclusion mode will blink slowly * - ERR (red) - fast blink on error during transmission error or recieve crc error * * See http://www.mysensors.org/build/esp8266_gateway for wiring instructions. * nRF24L01+ ESP8266 * VCC VCC * CE GPIO4 * CSN/CS GPIO15 * SCK GPIO14 * MISO GPIO12 * MOSI GPIO13 * GND GND * * Not all ESP8266 modules have all pins available on their external interface. * This code has been tested on an ESP-12 module. * The ESP8266 requires a certain pin configuration to download code, and another one to run code: * - Connect REST (reset) via 10K pullup resistor to VCC, and via switch to GND ('reset switch') * - Connect GPIO15 via 10K pulldown resistor to GND * - Connect CH_PD via 10K resistor to VCC * - Connect GPIO2 via 10K resistor to VCC * - Connect GPIO0 via 10K resistor to VCC, and via switch to GND ('bootload switch') * * Inclusion mode button: * - Connect GPIO5 via switch to GND ('inclusion switch') * * Hardware SHA204 signing is currently not supported! * * Make sure to fill in your ssid and WiFi password below for ssid & pass. */ // Enable debug prints to serial monitor //#define MY_DEBUG // Use a bit lower baudrate for serial prints on ESP8266 than default in MyConfig.h #define MY_BAUD_RATE 9600 // Enables and select radio type (if attached) //#define MY_RADIO_NRF24 --> mise en commentaire : pas de module radio //#define MY_RADIO_RFM69 //#define MY_RADIO_RFM95 #define MY_GATEWAY_ESP8266 #define MY_ESP8266_SSID "XXXXXXXXX" #define MY_ESP8266_PASSWORD "YYYYYYYYYYY" // Enable UDP communication //#define MY_USE_UDP // If using UDP you need to set MY_CONTROLLER_IP_ADDRESS below // Set the hostname for the WiFi Client. This is the hostname // it will pass to the DHCP server if not static. #define MY_ESP8266_HOSTNAME "NodeMCU controleur eau" // Enable MY_IP_ADDRESS here if you want a static ip address (no DHCP) #define MY_IP_ADDRESS 192,168,2,51 // If using static ip you can define Gateway and Subnet address as well #define MY_IP_GATEWAY_ADDRESS 192,168,2,1 #define MY_IP_SUBNET_ADDRESS 255,255,255,0 // The port to keep open on node server mode #define MY_PORT 5003 // How many clients should be able to connect to this gateway (default 1) // 2 counters and 2 switch for reset #define MY_GATEWAY_MAX_CLIENTS 4 // Controller ip address. Enables client mode (default is "server" mode). // Also enable this if MY_USE_UDP is used and you want sensor data sent somewhere. //#define MY_CONTROLLER_IP_ADDRESS 192, 168, 178, 68 // Enable inclusion mode //#define MY_INCLUSION_MODE_FEATURE // Enable Inclusion mode button on gateway //#define MY_INCLUSION_BUTTON_FEATURE // Set inclusion mode duration (in seconds) //#define MY_INCLUSION_MODE_DURATION 60 // Digital pin used for inclusion mode button //#define MY_INCLUSION_MODE_BUTTON_PIN 3 // Set blinking period for led on the board #define MY_DEFAULT_LED_BLINK_PERIOD 100 // Flash leds on rx/tx/err // Led pins used if blinking feature is enabled above //#define MY_DEFAULT_ERR_LED_PIN 16 // Error led pin //#define MY_DEFAULT_RX_LED_PIN 16 // Receive led pin //#define MY_DEFAULT_TX_LED_PIN 16 // the PCB, on board LED //-------------------------------------------------------------- // Table PIN / GPIO // https://github.com/esp8266/Arduino/issues/584 //-------------------------------------------------------------- #define D0 16 #define D1 5 // I2C Bus SCL (clock) #define D2 4 // I2C Bus SDA (data) #define D3 0 #define D4 2 // Same as "LED_BUILTIN", but inverted logic #define D5 14 // SPI Bus SCK (clock) #define D6 12 // SPI Bus MISO #define D7 13 // SPI Bus MOSI #define D8 15 // SPI Bus SS (CS) #define D9 3 // RX0 (Serial console) #define D10 1 // TX0 (Serial console) //-------------------------------------------------------------- // Call libraries //-------------------------------------------------------------- #if defined(MY_USE_UDP) #include <WiFiUdp.h> #endif #include <ESP8266WiFi.h> #include <MySensors.h> #include <SPI.h> #include <SoftwareSerial.h> #include <EEPROM.h> //-------------------------------------------------------------- // Declare and initialize MySensors variables // Volume (m3), flowrate (l/mn) and flowrate (m3/h) for flowmeter 1 and 2 // Binary used to reset counter A ou B //-------------------------------------------------------------- #define CHILD_ID_A 1 // Id of the compteur A #define CHILD_ID_B 2 // Id of the compteur B #define CHILD_ID_AR 3 // Id of the reset compteur A #define CHILD_ID_BR 4 // Id of the reset compteur B MyMessage flowMsg_A(CHILD_ID_A,V_FLOW); // flowrate (l/mn) MyMessage flowMsg_m3_A(CHILD_ID_A,V_VAR1); // flowrate (m3/h) MyMessage volumeMsg_A(CHILD_ID_A,V_VOLUME); // volume (m3) MyMessage flowMsg_B(CHILD_ID_B,V_FLOW); // flowrate (l/mn) MyMessage flowMsg_m3_B(CHILD_ID_B,V_VAR2); // flowrate (m3/h) MyMessage volumeMsg_B(CHILD_ID_B,V_VOLUME); // volume (m3) MyMessage light_msgA(CHILD_ID_AR, V_STATUS );// Reset watermeter A MyMessage light_msgB(CHILD_ID_BR, V_STATUS );// Reset watermeter B //-------------------------------------------------------------- // type of variables //-------------------------------------------------------------- const long delay_TX_volume = 60000; // delay (millisecondes) between send to Raspberry (every minutes) long ref_time_TX_ms; // Time reference to compute data transmission delay const long delay_EEPROM = 18000000; // delay (millisecondes) between save on EEPROM (every 5h) // 100.000 cycles -> 57 years long ref_time_EP_ms; // Time reference to compute EEPROM save const int eeprom_adr_vol_total = 0; // adress to write in EEPROM const int pulses_par_litre_A = 1; // pulses per liter (depending watermeter caracteristics) const int pulses_par_litre_B = 1; // pulses per liter (depending watermeter caracteristics) unsigned long vol_litres_total_A; // Total volume (liter) (4 octets) unsigned long vol_litres_total_B; // Total volume (liter) (4 octets) // utilisé dans la fonction void comptage () unsigned long pulses_compteur_total_A; // nombre d impulsions (4 octets) unsigned long pulses_compteur_total_B; // nombre d impulsions (4 octets) unsigned long pulses_compteur_debit_A; unsigned long pulses_compteur_debit_B; float litres_precis_A; // variable pour les compteurs à + de 1 impulsion par litre float litres_precis_B; // variable pour les compteurs à + de 1 impulsion par litre float volume_m3_A; // volume total en m3 float volume0_m3_A; // volume total en m3 pour calcul debit float volume_m3_B; // volume total en m3 float volume0_m3_B; // volume total en m3 pour calcul debit float flowrate_lmn_A; float flowrate_lmn_B; float flowrate_m3h_A; float flowrate_m3h_B; float coeff_flowrate; int val_A; int val_B; int val_old_A=HIGH; int val_old_B=HIGH; const int PIN_compteur_eau_A = D1; // broche D1 Input pin number to count water meter pulses const int PIN_compteur_eau_B = D2; // broche D2 Input pin number to count water meter pulses const int PIN_reset = D5; // broche D5 Input pin number to reset water meter pulses A & B const int PIN_LED_BUILTIN = D4; // broche D4 Led on board / inverted logic void setup() { //============================================================== // Fonction appelée lors de la mise sous tension de l'Arduino //============================================================== // INPUT is connected only by switch to GND pinMode(PIN_compteur_eau_A,INPUT_PULLUP); // use PIN_compteur_eau as INPUT pinMode(PIN_compteur_eau_B,INPUT_PULLUP); // use PIN_compteur_eau as INPUT pinMode(PIN_reset, INPUT_PULLUP); // use PIN_reset as INPUT // OUTPUT is not connected pinMode(PIN_LED_BUILTIN, OUTPUT); // use PIN link to the blue LED as OUTPUT (for blinking) // Initialize values Serial.begin(MY_BAUD_RATE); // Serial port board <-> PC for debug /* ----------------------------------------------------------------- Interrupt is NOT used to avoid switch rebounce count small code is implemented to limid rebounce counting in the loop ----------------------------------------------------------------- */ // Link between PIN, routine and type of signal for software interrupt //attachInterrupt(digitalPinToInterrupt(PIN_compteur_eau_A),count_pulses_A, FALLING); //attachInterrupt(digitalPinToInterrupt(PIN_compteur_eau_B),count_pulses_B, FALLING); //attachInterrupt(digitalPinToInterrupt(PIN_reset) ,reset_count_AB, FALLING); reset_count_A(); reset_count_B(); Serial.println(); Serial.println("== Compteur Eau v1.00 =="); // Restore volume values from EEPROM when module restart (power On) Serial.println("== EEPROM =="); EEPROM.begin(32); // max size needed for storage EEPROM.get(eeprom_adr_vol_total , vol_litres_total_A ); EEPROM.get(eeprom_adr_vol_total+4 , pulses_compteur_total_A); EEPROM.get(eeprom_adr_vol_total+8 , vol_litres_total_B ); EEPROM.get(eeprom_adr_vol_total+12, pulses_compteur_total_B); // Display volume to terminal PC (port USB emulation COM) Serial.print("Volume A : "); Serial.print(vol_litres_total_A); Serial.print(" -- Volume B : "); Serial.println(vol_litres_total_B); // Initialisation des volumes pour calcul du debit en entree de boucle litres_precis_A = float(vol_litres_total_A); litres_precis_B = float(vol_litres_total_B); volume_m3_A = litres_precis_A*0.001; volume_m3_B = litres_precis_B*0.001; volume0_m3_A = volume_m3_A; volume0_m3_B = volume_m3_B; // Blink led at the end of setup (10 times) LED_blink(10); Serial.println(""); Serial.println("----- End of Setup -----"); } void presentation() { /* // Send the sketch version information to the gateway and Controller sendSketchInfo("UV Sensor", "1.2"); // Register all sensors to gateway (they will be created as child devices) present(CHILD_ID_UV, S_UV); */ // Present locally attached sensors here // Send the sketch version information to the gateway and Controller sendSketchInfo("Water Meter", "1.0"); // Register this device as Waterflow sensor present(CHILD_ID_A, S_WATER, "Compteur A"); present(CHILD_ID_B, S_WATER, "Compteur B"); present(CHILD_ID_AR,S_DIMMER, "Reset Compteur A"); present(CHILD_ID_BR,S_DIMMER, "RESET Compteur B"); Serial.println("----- End of presentation -----"); } void receive(const MyMessage &message) { //When receiving a V_STATUS command, execute reset counter A if ( message.type == V_STATUS ) { Serial.println( "V_STATUS command received..." ); int lstate = message.getInt(); if (( lstate < 0 ) || ( lstate > 1 )) { Serial.println( "V_STATUS data invalid (should be 0/1)" ); return; } if ( lstate == 1 && message.sensor == 3) { Serial.println( "Reset command received watermeter A" ); reset_count_A(); return; } if ( lstate == 1 && message.sensor == 4) { Serial.println( "Reset command received watermeter B" ); reset_count_B(); return; } } else { Serial.println( "Invalid command received..." ); return; } } void loop() { //============================================================== // Infinite loop //============================================================== // RESET counter by switch ? int val=digitalRead(PIN_reset); if(val==LOW) { reset_count_A(); reset_count_B(); Print_volume(); LED_blink(1); // blink LED (and then wait to avoid switch rebounce) } // test for switch A int val_A=digitalRead(PIN_compteur_eau_A); if(val_A==LOW && val_old_A==HIGH ) { count_pulses_A(); // increment pulse counter delay(200); // wait to avoid rebounce val_old_A=LOW; } else { if(val_A==HIGH ) val_old_A=HIGH; } // test for switch B int val_B=digitalRead(PIN_compteur_eau_B); if(val_B==LOW && val_old_B==HIGH ) { count_pulses_B(); // increment pulse counter delay(200); // wait to avoid rebounce val_old_B=LOW; } else { if(val_B==HIGH ) val_old_B=HIGH; } // Calculate exact total volume (unit m3) - take in account pulse number for counter with >= 1 pulse/liter //calcul du volume exact total en m3 (tient compte du nombre d'impulsions - valable pour compteur a + de 1 pulse par litre) litres_precis_A = float(vol_litres_total_A)+ float(1.0/float(pulses_par_litre_A)*float(pulses_compteur_total_A)); litres_precis_B = float(vol_litres_total_B)+ float(1.0/float(pulses_par_litre_B)*float(pulses_compteur_total_B)); volume_m3_A = litres_precis_A*0.001; volume_m3_B = litres_precis_B*0.001; /* ----------------------------------------------------------------- Test time interval for transmission to Raspberry millis() -> number of milliseconde since module power ON reset every about 50 days ... ref_time_TX_ms -> time reference in the loop delay_TX_volume -> delay between transmissions to Raspberry (ms) ----------------------------------------------------------------- */ if (millis() - ref_time_TX_ms > delay_TX_volume){ // Compute flowrate as l/mn : volume difference divide by time // flowrate = 1000.0*60.0*1000.0*(volume_m3-volume0_m3)/float(millis() - ref_time_TX_ms) coeff_flowrate = 60000000.0/float(millis() - ref_time_TX_ms); flowrate_lmn_A = coeff_flowrate*(volume_m3_A-volume0_m3_A); flowrate_lmn_B = coeff_flowrate*(volume_m3_B-volume0_m3_B); // Equivalent m3/h flowrate_m3h_A = flowrate_lmn_A * 0.06 ; flowrate_m3h_B = flowrate_lmn_B * 0.06 ; // update time reference between transmissions ref_time_TX_ms = millis(); // update volume reference between transmissions volume0_m3_A = volume_m3_A; volume0_m3_B = volume_m3_B; // Display volume values on terminal PC (port USB emulation COM) Print_volume(); // Display flowrate values on terminal PC (port USB emulation COM) unit l/mn and m3/h Serial.print("Flowrate A (l/mn) : "); // send on serial port in ASCII format Serial.print(flowrate_lmn_A,2); // send value on serial port Serial.print(" (l/mn) ou "); Serial.print(flowrate_m3h_A,3); // send value on serial port Serial.print(" (m3/h) -- Flowrate B (l/mn) : "); Serial.print(flowrate_lmn_B,2); // send value on serial port Serial.print(" (l/mn) ou "); Serial.print(flowrate_m3h_B,3); // send value on serial port Serial.println(" (m3/h)"); // Send values to gateway with MySensors protocol send(volumeMsg_A.set(volume_m3_A, 3)); // Send volume value to gateway - format x.xxx send(volumeMsg_B.set(volume_m3_B, 3)); // Send volume value to gateway - format x.xxx send(flowMsg_A.set(flowrate_lmn_A, 1)); // Send flowrate value to gateway - format x.x (l/mn) send(flowMsg_B.set(flowrate_lmn_B, 1)); // Send flowrate value to gateway - format x.x (l/mn) // Values for database send(flowMsg_m3_A.set(flowrate_m3h_A, 1)); // Send flowrate value to gateway - format x.x (m3/h) VAR1 send(flowMsg_m3_B.set(flowrate_m3h_B, 1)); // Send flowrate value to gateway - format x.x (m3/h) VAR2 // Blink LED to indicate sending to gateway LED_blink(1); } /* ----------------------------------------------------------------- Save volume values on EEPROM ----------------------------------------------------------------- */ if (millis() - ref_time_EP_ms > delay_EEPROM){ // Message on terminal : save on EEPROM Serial.println(""); Serial.println("-- Sauvegarde sur EEPROM --"); //save current volume and pulses on EEPROM (permanent) // in case of loose of power supply or WiFi // Write reduce life time of EEPROM (max < 100 000 cycles) EEPROM.put(eeprom_adr_vol_total , vol_litres_total_A ); EEPROM.put(eeprom_adr_vol_total+4 , pulses_compteur_total_A); EEPROM.put(eeprom_adr_vol_total+8 , vol_litres_total_B ); EEPROM.put(eeprom_adr_vol_total+12, pulses_compteur_total_B); EEPROM.commit(); // Save changes to the flash (eeprom) Serial.println("-- EEPROM.put --- "); Print_volume(); // update time reference between transmissions ref_time_EP_ms = millis(); // Read again EEPROM to verify and print on terminal Serial.println("-- Verification ecriture sur EEPROM --"); EEPROM.get(eeprom_adr_vol_total , vol_litres_total_A ); EEPROM.get(eeprom_adr_vol_total+4 , pulses_compteur_total_A); EEPROM.get(eeprom_adr_vol_total+8 , vol_litres_total_B ); EEPROM.get(eeprom_adr_vol_total+12, pulses_compteur_total_B); Serial.println("-- EEPROM.get --- "); Print_volume(); } // End of loop } void count_pulses_A(){ //============================================================== // Take in account each pulse in a integer "pulses_compteur_total_A" // test if pulse count reach value for 1 liter //============================================================== pulses_compteur_total_A++; // increment pulse counter if (pulses_compteur_total_A >= pulses_par_litre_A) { // 1 L still count then reset pulse counter and increment volume counter pulses_compteur_total_A = 0; vol_litres_total_A++; } Serial.print("-- vol_litres_total_A : "); Serial.println(vol_litres_total_A); } void count_pulses_B(){ //============================================================== // Take in account each pulse in a integer "pulses_compteur_total_B" // test if pulse count reach value for 1 liter //============================================================== pulses_compteur_total_B++; // increment pulse counter if (pulses_compteur_total_B >= pulses_par_litre_B) { // 1 L still count then reset pulse counter and increment volume counter pulses_compteur_total_B = 0; vol_litres_total_B++; } Serial.print("-- vol_litres_total_B : "); Serial.println(vol_litres_total_B); } void reset_count_AB(){ //============================================================== // Reset counter A & B // (not used in this sketch witch switch) //============================================================== reset_count_A(); reset_count_B(); } void reset_count_A(){ //============================================================== // Reset counter B // Will be save in EEPROM after delay_EEPROM time //============================================================== pulses_compteur_total_A = 0; pulses_compteur_debit_A = 0; vol_litres_total_A = 0; flowrate_lmn_A = 0; volume0_m3_A = 0; volume_m3_A = volume0_m3_A; ref_time_TX_ms = millis(); // Initialize to current time for transmission ref_time_EP_ms = ref_time_TX_ms; // Initialize to current time for EEPROM save Serial.println(" ------ RESET COUNTER A ---- "); } void reset_count_B(){ //============================================================== // Reset counter B // Will be save in EEPROM after delay_EEPROM time //============================================================== pulses_compteur_total_B = 0; pulses_compteur_debit_B = 0; vol_litres_total_B = 0; flowrate_lmn_B = 0; volume0_m3_B = 0; volume_m3_B = volume0_m3_B; ref_time_TX_ms = millis(); // Initialize to current time for transmission ref_time_EP_ms = ref_time_TX_ms; // Initialize to current time for EEPROM save Serial.println(" ------ RESET COUNTER B ---- "); } void LED_blink(byte N_blink){ //============================================================== // Blink the led N_blink time // MY_DEFAULT_LED_BLINK_PERIOD ms On / MY_DEFAULT_LED_BLINK_PERIOD ms Off //============================================================== for(byte i = 0; i < N_blink; ++i) // Loop for N_blink blink { digitalWrite(PIN_LED_BUILTIN, LOW); // turn the LED on (LOW is the voltage level) delay(MY_DEFAULT_LED_BLINK_PERIOD); // time to wait (millisecond) digitalWrite(PIN_LED_BUILTIN, HIGH); // turn the LED off by making the voltage HIGH delay(MY_DEFAULT_LED_BLINK_PERIOD); // time to wait (millisecond) } } void Print_volume(){ //============================================================== // Print volumes on serial terminal //============================================================== Serial.println(""); Serial.print("volume total A (L) : "); Serial.print(vol_litres_total_A,3); // format x.xxx Serial.print(" -- volume total B (L) : "); Serial.println(vol_litres_total_B,3); // format x.xxx }