Two Chronometers Code

Hello Everyone, I hope someone can help me. I want to display two chronometers, The first one is on when we open water, means a impulsion is detected til 1 minute after there is no detection. the second one only is incrementing when we open water, the moment we close the water is stops, and then stops completly after 1 minute where there is no detection. Here is what I came up with but it's not giving exactly what I want. Can someone please help me.

#include <ArduinoBLE.h>
const int hallsensor = 2;
const int tsampling = 1;
const unsigned long maxIdleTime = 60000; // Durée maximale sans impulsion (1 minute)
volatile int NbTopsFan = 0;
float Q = 0.0;
float Calc = 0.0;
unsigned long startTimeTotal = 0;
unsigned long startTimeWaterRunning = 0;
unsigned long lastImpulseTime = 0;
bool isWaterRunning = false;
bool isIdle = false;

BLEService dataService("19B10000-E8F2-537E-4F6C-D104768A1214"); // Random 128-bit UUID for the service
BLECharacteristic dataCharacteristic("19B10001-E8F2-537E-4F6C-D104768A1214", BLERead, 20); // Random 128-bit UUID for the characteristic


void rpm() {
  NbTopsFan++;}


void printDigits(unsigned long digits) {
  if (digits < 10) {
    Serial.print("0");
  }
  Serial.print(digits);
}

void setup() {
  Serial.begin(9600);
  pinMode(hallsensor, INPUT);
  attachInterrupt(digitalPinToInterrupt(hallsensor), rpm, RISING);
  startTimeTotal = millis();

  if (!BLE.begin()) {
    Serial.println("Erreur BLE");
    while (1);
  }

  BLE.setLocalName("NanoBLE");
  BLE.setAdvertisedService(dataService);
  dataService.addCharacteristic(dataCharacteristic);
  BLE.addService(dataService);
  BLE.advertise();

  Serial.println("En attente de connexion BLE...");
}

void loop() {
  BLEDevice central = BLE.central();
  NbTopsFan = 0;
  delay(tsampling * 1000);
  Q = NbTopsFan / (20.0 * tsampling);
  Calc = (Q / 60) + Calc;

  String To_App = String(Q, 3) + "," + String(Calc, 3);
  Serial.println(To_App);
  dataCharacteristic.writeValue(To_App.c_str(), To_App.length());

  unsigned long currentTime = millis();
  unsigned long elapsedTotal = currentTime - startTimeTotal;

  if (Q > 0) {
    // Mise à jour de la durée totale de la douche
    unsigned long secondsTotal = (elapsedTotal / 1000) % 60;
    unsigned long minutesTotal = (elapsedTotal / (1000 * 60)) % 60;
    unsigned long hoursTotal = (elapsedTotal / (1000 * 60 * 60)) % 24;

    Serial.print("Durée de la douche : ");
    printDigits(hoursTotal);
    Serial.print(":");
    printDigits(minutesTotal);
    Serial.print(":");
    printDigits(secondsTotal);
    Serial.println();
  }

  if (isWaterRunning) {
    // Mise à jour de la durée d'écoulement de l'eau
    unsigned long elapsedWaterRunning = currentTime - startTimeWaterRunning;
    unsigned long secondsWaterRunning = (elapsedWaterRunning / 1000) % 60;
    unsigned long minutesWaterRunning = (elapsedWaterRunning / (1000 * 60)) % 60;
    unsigned long hoursWaterRunning = (elapsedWaterRunning / (1000 * 60 * 60)) % 24;

    Serial.print("Durée d'écoulement d'eau : ");
    printDigits(hoursWaterRunning);
    Serial.print(":");
    printDigits(minutesWaterRunning);
    Serial.print(":");
    printDigits(secondsWaterRunning);
    Serial.println();

     // Vérifier si aucune impulsion n'a été détectée pendant la durée maximale
    if (elapsedWaterRunning >= maxIdleTime) {
      isWaterRunning = false;
      isIdle = true;
    }
  } else {
    // Vérifier si une impulsion a été détectée après une période d'inactivité
    if (isIdle && Q > 0) {
      isWaterRunning = true;
      startTimeWaterRunning = currentTime;
      isIdle = false;
    }
  }

  // Vérifier si aucune impulsion n'a été détectée pendant la durée maximale
  if (elapsedTotal >= maxIdleTime) {
    isWaterRunning = false;
    isIdle = false;
  }
}

Two questions:
1 What is it doing that it shouldn't?
2 What is it NOT doing that it should?
Please answer as completely as possible. Later we'll need schematics and pics.
TYVM!

1 Like

Great Questions, First, The first chronometer Start even when the water is closed. the second one doesnt respect the condition, it means even when I stop the water, in other words, even when there is no impulsion detection, It keeps going.

What starts and stops? Button? Sensor? Time?

Since we've veered into hardware, now is time to show wires and wiring schematic. (hand drawn preferred, please)

I have a sensor connected to Pin2, It calculates Flowrate. When I say Start and stop, I mean the seconds and minutes of my Chronometers. I want My first chronometer to only start when I open the water and I want it to stop 1 minute after I close the water.
I want my second chronometer to be conditionned by the Nbtopfan (The impulsions of the flowrate sensor) When I close the water, the second chronometer stops when I open the water keeps going. And then the chronometer stops counting 1 minute after the water stops

Before worrying about the "chronometers" (timers?), are you sure that your detection of the water flowing or not flowing is working?

Yes I can see the values of Q and Calc

You appear to have two chronometers. One is based on Q>0 and one is based on isWaterRunning.

 if (Q > 0) {
    // Mise à jour de la durée totale de la douche
    unsigned long secondsTotal = (elapsedTotal / 1000) % 60;
    unsigned long minutesTotal = (elapsedTotal / (1000 * 60)) % 60;
    unsigned long hoursTotal = (elapsedTotal / (1000 * 60 * 60)) % 24;

    Serial.print("Durée de la douche : ");
    printDigits(hoursTotal);
    Serial.print(":");
    printDigits(minutesTotal);
    Serial.print(":");
    printDigits(secondsTotal);
    Serial.println();
  }

  if (isWaterRunning) {
    // Mise à jour de la durée d'écoulement de l'eau
    unsigned long elapsedWaterRunning = currentTime - startTimeWaterRunning;
    unsigned long secondsWaterRunning = (elapsedWaterRunning / 1000) % 60;
    unsigned long minutesWaterRunning = (elapsedWaterRunning / (1000 * 60)) % 60;
    unsigned long hoursWaterRunning = (elapsedWaterRunning / (1000 * 60 * 60)) % 24;

    Serial.print("Durée d'écoulement d'eau : ");
    printDigits(hoursWaterRunning);
    Serial.print(":");
    printDigits(minutesWaterRunning);
    Serial.print(":");
    printDigits(secondsWaterRunning);
    Serial.println();

Which are you calling the "First" and which are you calling the "Second"?

Durée de la douche : The first one.
Durée d'écoulement d'eau : Second One.
I can change labels if french can be confusing.

The first chronometer Start even when the water is closed

if (Q > 0)

Q is a floating point variable and when it is initialized to 0 it may be a very small number so it may be >0 before water is turned on.
Try something like this and see if the chronometer does not start without water flow.
if(Q >= .01){

Indeed!

Another example where a diagram would provide a much clearer description!

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.