Ajout de tempo dans un projet

bonjour,
je viens vers vous aujourd'hui car je bloque un peut sur un projet.

il s'agit d'un système d'alimentation de pompe de puit que l'on alimente x temps tous les y temps
(x et y dépendent de deux potentiomètres de réglage de temp)

seul hic a mon code actuel: lors de l'activation de la fonction il y as une boucle entre ON et OFF ou la pompe reste éteinte alors que je voudrais quelle s'allume aussitot.

et de plus vu que j'utilise la fonction millis:() je souhaiterais ajouter un decompte a chaque changement d'etat .

voici le code actuel:

#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,16,2);
int Pompepuit = 9; // LED de la pin 9 materialisera la sortie
bool EtatPompepuit = HIGH;
int tempOff =  A0;      // crée un identifiant pour la broche utilisée avec le potentiometre 1
int tempOn =  A2;      // crée un identifiant pour la broche utilisée avec le potentiometre 2
unsigned long chronoOn = 0;
unsigned long chronoOff = 0;
int modeManu = 10;//mode manuel
int modeAuto = 11;//mode auto
int cuve1pleine = 12;//mode capteur cuve 1 pleine
int counter1;


void setup() {
  Serial.begin(9600);
  while (!Serial);
  pinMode(Pompepuit, OUTPUT);
 // pinMode(12, INPUT);
  digitalWrite (Pompepuit, EtatPompepuit);
  pinMode(tempOff, INPUT);
  pinMode(tempOn, INPUT);
  pinMode(modeManu, INPUT);
  pinMode(modeAuto, INPUT);
  pinMode(cuve1pleine, INPUT);
  chronoOn = millis();
  lcd.init();
}

void loop(){
 // calcul du temps d'attente en fonction des valeurs lues
  unsigned long dureeOff = analogRead(tempOff) * 3500UL;
  unsigned long dureeOn = analogRead(tempOn) * 3500UL;
 //4 chiffre =seconde:4000=4 seconde

  if(digitalRead(7)==1){
  
    lcd.setCursor(0,0);
    lcd.print("temp ON");
    lcd.setCursor(9,0);
    lcd.print(dureeOn/60000);
    lcd.setCursor(13,0);
    lcd.print("min");
    lcd.setCursor(0,1);
    lcd.print("temp OFF");
    lcd.setCursor(9,1);//120
    lcd.print(dureeOff/60000);
    lcd.setCursor(13,1);
    lcd.print("min");
  
  
   if (dureeOn/60000<100)
      lcd.setCursor(11,0);
      lcd.print(" ");
  
   if (dureeOn/60000<10)
      lcd.setCursor(10,0);
      lcd.print(" ");
  
    if (dureeOff/60000<100)
      lcd.setCursor(11,1);
      lcd.print(" ");
  
    if (dureeOff/60000<10)
      lcd.setCursor(10,1);
      lcd.print(" ");
  }
  else {
    lcd.clear();
   }

 if (digitalRead(modeManu) ==1){
  pompage();
 }
 else {
 if (digitalRead(modeAuto) ==1){
  if (digitalRead(cuve1pleine)==0){
    pompage();
  }
  else {
    digitalWrite(Pompepuit,1);
    lcd.noBacklight();
  }
 }else {
    digitalWrite(Pompepuit,1);
    lcd.noBacklight();
 }
  }
  }
 
void pompage(){
 lcd.backlight();
 // calcul du temps d'attente en fonction des valeurs lues
  unsigned long dureeOff = analogRead(tempOff) * 3500UL;
  unsigned long dureeOn = analogRead(tempOn) * 3500UL;
 //4 chiffre =seconde:4000=4 seconde

   // si led éteinte et durée pot2 dépassée :
  if (millis() - chronoOn > dureeOn && !EtatPompepuit) {
    chronoOff = millis();
    chronoOn = millis();
    EtatPompepuit = !EtatPompepuit;
    digitalWrite (Pompepuit, EtatPompepuit);
  } 
  // si led allumée et durée pot1 dépassée :
  if (millis() - chronoOff > dureeOff && EtatPompepuit) {
    chronoOn = millis();
    chronoOff = millis();
    EtatPompepuit = !EtatPompepuit;
    digitalWrite (Pompepuit, EtatPompepuit);
   // if (EtatPompepuit ==0)
   // lcd.print(
    
  }


}
  

Bonjour mickaguesnet

Voilà une façon de réaliser la chose, en se basant sur la variable booléenne EtatPompepuit.
J'ai repris une partie de ton programme comme démo "accélérée".


int counter1 = 0;

unsigned long dureeOff;
unsigned long dureeOffMillis;
unsigned long dureeOn;
unsigned long dureeOnMillis;;

unsigned long displayTempo = 1000;     // Toutes les secondes
unsigned long displayMillis = millis();

bool EtatPompepuit;

void setup() 
{
	Serial.begin(9600);
	while (!Serial);

	EtatPompepuit = false;
}

void loop()
{
	// calcul du temps d'attente en fonction des valeurs lues
	dureeOff = 5000;     // analogRead(tempOff) * 3500UL;
	dureeOn = 3000;     // analogRead(tempOn) * 3500UL;
	//4 chiffre =seconde:4000=4 seconde

	if (!EtatPompepuit && (millis()-dureeOffMillis >= dureeOff))     // Si durée OFF terminée
	{
		Serial.println("ON");
		counter1 ++;
		dureeOnMillis = millis();
		EtatPompepuit = true;
	}

	if (EtatPompepuit && (millis()-dureeOnMillis >= dureeOn))     // Si durée On terminée
	{
		Serial.println("OFF");
		dureeOffMillis = millis();
		EtatPompepuit = false;
	
	}

	if (millis()-displayMillis >= displayTempo)
	{
		Serial.println("Compteur : " + String(counter1));
		
		displayMillis = millis();
	}
}

J'ai ajouté l'affichage de counter1 dans la console.

Cordialement
jpbbricole

Bonjour Jpbbricole

Merci pour l’aide j’essaierai dans l’après-midi
Et je regarderai pour bien comprendre les modifications

rebonjour
merci pour le bout de code

mais il me semble m'être mal expliqué je ne cherchais pas a compter le nombre d'allumage et arrêt de la pompe mais plutôt un affichage du temps restant avant changement d'état
exemple :
la pompe est réglée pour fonctionner 5 min toute les 10 minutes avec les potentiomètres
quand on regarde l'écran on voit le temps s'écouler genre 4 min avant arrêt ou 8 min avant de la redémarrer

encore merci pour l'aide

Bonsoir mickaguesnet

Ou c'est moi :wink:, je regarde ça

A+
Cordialement
jpbbricole

Bonjour mickaguesnet

Essaies ceci:

// https://forum.arduino.cc/t/ajout-de-tempo-dans-un-projet/999714/4
unsigned long dureeOff;
unsigned long dureeOffMillis;
unsigned long dureeOn;
unsigned long dureeOnMillis;;

unsigned long displayTempo = 10000;     // Toutes les 10 secondes
unsigned long displayMillis = millis() + displayTempo;

bool EtatPompepuit;

void setup() 
{
	Serial.begin(9600);

	delay(1000);
	EtatPompepuit = true;
}

void loop()
{
	// calcul du temps d'attente en fonction des valeurs lues
	dureeOff = 300000;     // 5 minutes // analogRead(tempOff) * 3500UL;
	dureeOn = 180000;     // 3 minutes // analogRead(tempOn) * 3500UL;
	//4 chiffre =seconde:4000=4 seconde

	if (!EtatPompepuit && (millis()-dureeOffMillis >= dureeOff))     // Si durée OFF terminée
	{
		Serial.println(F("ON"));

		dureeOnMillis = millis();
		EtatPompepuit = true;
	}

	if (EtatPompepuit && (millis()-dureeOnMillis >= dureeOn))     // Si durée On terminée
	{
		Serial.println(F("OFF"));
		dureeOffMillis = millis();
		EtatPompepuit = false;
	
	}

	if (millis()-displayMillis >= displayTempo)
	{		
		displayInfo();
		displayMillis = millis();
	}
}

void displayInfo()
{
	float tempsRestant;
	if (EtatPompepuit)     // Si pompe en marche
	{
		tempsRestant = (dureeOn-(millis()-dureeOnMillis))/60000.0;
		Serial.print(F("Pompe ON encore "));
		Serial.println(String(tempsRestant) + " minutes.");
	}
	else     // Si pompe arrêtée
	{
		tempsRestant = (dureeOff-(millis()-dureeOffMillis))/60000.0;
		Serial.print(F("Pompe OFF encore "));
		Serial.println(String(tempsRestant) + " minutes.");
	}
}

Les temps sont 3 minutes (180000) ON et 5 minutes (300000) OFF
et il s'affiche:

Pompe ON encore 0.48 minutes.
Pompe ON encore 0.32 minutes.
Pompe ON encore 0.15 minutes.
OFF
Pompe OFF encore 4.98 minutes.
Pompe OFF encore 4.82 minutes.
Pompe OFF encore 4.65 minutes.
Pompe OFF encore 4.48 minutes.
Pompe OFF encore 4.32 minutes.
...
Pompe OFF encore 0.65 minutes.
Pompe OFF encore 0.48 minutes.
Pompe OFF encore 0.32 minutes.
Pompe OFF encore 0.15 minutes.
ON
Pompe ON encore 2.98 minutes.
Pompe ON encore 2.82 minutes.
Pompe ON encore 2.65 minutes.
...
Pompe ON encore 0.48 minutes.
Pompe ON encore 0.32 minutes.
Pompe ON encore 0.15 minutes.
OFF
Pompe OFF encore 4.98 minutes.
Pompe OFF encore 4.82 minutes.
Pompe OFF encore 4.65 minutes.

Toutes les 10 secondes (displayTempo)

A+
Cordialement
jpbbricole

Bonjour jpbbricole

Merci pour le coup de main
J’ai vu et compris le code que tu m’as laissé

Seul bemol j’ai commencé quelques essais en réel avec mon installation et les potentiomètres

Et a certains moments il affiche :
-0.03 minutes avant arret
-715980 minutes avant arret

Il refait un décompte environ 30 secondes
Et change son état

Ceci pourrait venir de la modification du programme que j’ai effectué ?

Bonsoir mickaguesnet

Je contrôle ça.

A+
Cordialement
jpbbricole

Bonsoir mickaguesnet

Mets moi ton programme avec les potentiomètres.

A+
Cordialement
jpbbricole

Bonjour jpbbricole
voici le code que j'ai pour mes essais

#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,16,2);
int Pompepuit = 9; // LED de la pin 9 materialisera la sortie
int tempOff =  A0;      // crée un identifiant pour la broche utilisée avec le potentiometre 1
int tempOn =  A2;      // crée un identifiant pour la broche utilisée avec le potentiometre 2
int modeManu = 10;//mode manuel
int modeAuto = 11;//mode auto
int cuve1pleine = 12;//mode capteur cuve 1 pleine

bool EtatPompepuit;

unsigned long chronoOn = 0;
unsigned long chronoOff = 0;
unsigned long dureeOff;
unsigned long dureeOn;
unsigned long displayTempo = 5000;     // Toutes les 5 secondes
unsigned long displayMillis = millis() + displayTempo;





void setup() {
  Serial.begin(9600);
  while (!Serial);
  pinMode(Pompepuit, OUTPUT);
  digitalWrite (Pompepuit, EtatPompepuit);
 // pinMode(12, INPUT);
  pinMode(tempOff, INPUT);
  pinMode(tempOn, INPUT);
  pinMode(modeManu, INPUT);
  pinMode(modeAuto, INPUT);
  pinMode(cuve1pleine, INPUT);
  chronoOn = millis();
  lcd.init();
}

void loop(){
 // calcul du temps d'attente en fonction des valeurs lues
dureeOff = analogRead(tempOff) *  500UL;    //3500UL;
dureeOn = analogRead(tempOn) *    500UL;    //3500UL;
 //4 chiffre =seconde:4000=4 seconde

  //if(digitalRead(7)==1){
  
  /*  lcd.setCursor(0,0);
    lcd.print("temp ON");
    lcd.setCursor(9,0);
    lcd.print(dureeOn/60000);
    lcd.setCursor(13,0);
    lcd.print("min");
    lcd.setCursor(0,1);
    lcd.print("temp OFF");
    lcd.setCursor(9,1);//120
    lcd.print(dureeOff/60000);
    lcd.setCursor(13,1);
    lcd.print("min");
  
  
   if (dureeOn/60000<100)
      lcd.setCursor(11,0);
      lcd.print(" ");
  
   if (dureeOn/60000<10)
      lcd.setCursor(10,0);
      lcd.print(" ");
  
    if (dureeOff/60000<100)
      lcd.setCursor(11,1);
      lcd.print(" ");
  
    if (dureeOff/60000<10)
      lcd.setCursor(10,1);
      lcd.print(" ");
  
  //else {
   // lcd.clear();
   //}
*/
 if (digitalRead(modeManu) ==1){
  pompage();
 }
 else {
 if (digitalRead(modeAuto) ==1){
  if (digitalRead(cuve1pleine)==0){
    pompage();
  }
  else {
    digitalWrite(Pompepuit,1);
    lcd.noBacklight();
  }
 }else {
    digitalWrite(Pompepuit,1);
    lcd.noBacklight();
 }
  }
  }
 
void pompage(){
 lcd.backlight();
 // calcul du temps d'attente en fonction des valeurs lues
  dureeOff = analogRead(tempOff) * 500UL;    //3500UL;
  dureeOn = analogRead(tempOn) *   500UL;   //3500UL;
 //4 chiffre =seconde:4000=4 seconde

  // si led allumée et durée pot1 dépassée :
  if (!EtatPompepuit && (millis() - chronoOff >= dureeOff)) {
    chronoOn = millis();
    //chronoOff = millis();
    Serial.println(F("Off"));
    EtatPompepuit =true;
    digitalWrite (Pompepuit, EtatPompepuit);
   // if (EtatPompepuit ==0)
   // lcd.print(
    
  }
   // si led éteinte et durée pot2 dépassée :
  if (EtatPompepuit && (millis() - chronoOn >= dureeOn)) {
    chronoOff = millis();
   // chronoOn = millis();
     Serial.println(F("On"));
    EtatPompepuit =false;
    digitalWrite (Pompepuit, EtatPompepuit);
  } 
 
 if (millis()-displayMillis >= displayTempo)
  {
    displayInfo();
    displayMillis = millis();
  }
}
void displayInfo()
{
  float tempsRestant;
  if (EtatPompepuit)     // Si pompe en marche
  {
    tempsRestant = (dureeOff-(millis()-chronoOff))/60000.0;
    lcd.setCursor(0,0);
    lcd.print("Pompe Off encore ");
    lcd.setCursor(0,1);
    lcd.println(String(tempsRestant) + " minutes");
    Serial.print("Pompe Off encore ");
    Serial.println(String(tempsRestant) + " minutes.");

  }
  else     // Si pompe arrêtée
  {
    tempsRestant = (dureeOn-(millis()-chronoOn))/60000.0;
    
    lcd.setCursor(0,0);
   lcd.print("Pompe On encore ");
   lcd.setCursor(0,1);
    lcd.println(String(tempsRestant) + " minutes");
     Serial.print("Pompe On encore ");
    Serial.println(String(tempsRestant) + " minutes.");

  }
}
  

A+

sur le code que tu m'as envoyé tu notais Serial.println(F("On"));
a quoi correspond (F(...)?

Merci

Bonjour mickaguesnet

Ca sert à préserver la mémoire dynamique de l'Arduino, endroit où "tourne" ton programme. Ca place ta chaîne de caractère en mémoire flash.

Cordialement
jpbbricole

la spec est un peu incomplète, par exemple il faudrait savoir ce qu'il se passe si on joue avec les potentiomètres pendant la phase active. Est-ce pris en compte directement ?

Bonjour mickaguesnet

Je n'ai pas tout testé, je n'ai pas ton installetion, mais je pense que celà provient de ça:

dureeOff = analogRead(tempOff) *  500UL;    //3500UL;
dureeOn = analogRead(tempOn) *    500UL;    //3500UL;

Tu as le risque d'avoir des temps à 0, il faut délimiter les possibilités avec un constrain().

dureeOff = analogRead(tempOff);
dureeOff = constrain(dureeOff, 10, 1023) * 500UL;
dureeOn = analogRead(tempOn);
dureeOn = constrain(dureeOn, 10, 1023) * 500UL;

Essaies ça.

Cordialement
jpbbricole

attention au débordement sur petit arduino, il faut écrire 1023ul * 500 par exemple pour forcer le calcul en unsigned long. (sinon c'est fait par défaut en int et sur UNO c'est 2 octets seulement on ne peut pas aller au delà de 32767)

attention aussi à constrain, c'est une macro et donc il vaut mieux éviter de passer un appel de fonction en paramètre

La macro c'est

#define constrain(amt,low,high) ((amt)<(low)?(low):((amt)>(high)?(high):(amt)))

donc quand vous faites

constrain(analogRead(tempOff) *  500UL, 100, 1023 * 500);

vous écrivez en fait

((analogRead(tempOff) *  500UL)<(100)?(100):((analogRead(tempOff) *  500UL)>(1023 * 500)?(1023 * 500):(analogRead(tempOff) *  500UL)))

ce qui fait que vous lisez potentiellement 3 fois le analogRead() et pouvez avoir des valeurs qui ont variées

Bonjour J-M-L

C'est corrigé, j'avais pas lu la remarque. :cry:
Ainsi, la plage va de 5000 à 511500.

Cordialement
jpbbricole

je suppose que c'est plutôt

dureeOff = analogRead(tempOff);
dureeOff = constrain(dureeOff, 10, 1023) * 500UL;
dureeOn = analogRead(tempOn);
dureeOn = constrain(dureeOn, 10, 1023) * 500UL;

que vous vouliez écrire

Bonjour J-M-L

Oui, merci, je fais 2 choses à la fois et, à mon âge, ça ne pardonne pas toujours. :wink:

Cordialement
jpbbricole

merci pour le retour !!

j'enverrai une copie de mon moniteur pour que le problème soit plus compréhensif

ce morceau est a ajouter a la zone d'initialisation de la carte ou au moment de faire appel a la lecture du potentiometre?