temporisation réglable simple

bonjour

Je suis débutant et après pas mal d'essais et de lectures suivant divers sources je tourne en rond:

Je souhaite actionner une électrovanne toute les 1 heure environ pendant plusieurs secondes.

Et je souhaite pouvoir régler cet intervalle et cette durée d'actionnement de la vanne à l'aide de 2 potentiomètres.

Vu que l'intervalle est long, j'ai compris que je ne peux pas utiliser la fonction DELAIS, sans quoi, les changements de réglage des potentiomètres ne seraient pas pris en compte immédiatement...

J'ai lu qu'il me faut alors utiliser la fonction MILLI.

Mais la je bloque car je n'arrive pas a comprendre comment et ou faire intervenir les valeurs issues de mes potentiomètres, notamment concernant le temps d'activation de l'électrovanne.

Si quelqu'un.e peut m'aider, ce serait très sympa.

Materiel:

*1 ARDUINO UNO avec une alimentation

*2 potentiomètre de 10k

*1 transistor

*1 électrovanne

Voici un petit exemple d'utilisation de millis dans ton cas :

unsigned long chrono = 0;
unsigned long attente = 3600000ul; // 1 heure en millisecondes

void setup() {
  // instructions du setup


  chrono = millis();
}

void loop() {
  long valeurPot1 = analogRead(pinPot1);
  long valeurPot2 = analogRead(pinPot2);
  // ici le calcul du temps d'attente en fonction des valeurs lues


  if (millis() - chrono > attente) {
    chrono = millis();
    // ici les choses à faire au bout de l'attente


  }
}

A compléter bien sûr avec le reste de ton code...

Merci beaucoup lesept
Je vais étudier ça et faire des essais.
Je te dirais lorsque j’ai testé
Merci encore

bonjour

J’ai enfin eu le temps de me pencher sur mon projet.
Comme mes connaissance sont trop juste pour arriver a suivre tes conseils lesept, j’ai encore cherché et je suis tombé sur le blog d’une personne qui parle de la fonction “elapsedmillis”:
http://www.wyman.fr/clignotement-sans-delay/

A partir du code proposé dans le blog, j’ai pondu celui la (QUI NE FONCTIONNE PAS…)

#include <elapsedMillis.h>

int LEDcligno = 13; // LED de la pin 13 materialisera la sortie
int EtatLEDcligno = HIGH;
int ChangeLEDcligno = 0;
elapsedMillis ComptCligno; //compteur
int pinpot1 =  A0;      // crée un identifiant pour la broche utilisée avec le potentiometre 1
int pinpot2 =  A2;      // crée un identifiant pour la broche utilisée avec le potentiometre 2

void setup()
{

pinMode(13, OUTPUT);
pinMode(pinpot1, INPUT);
pinMode(pinpot2, INPUT);
}
void loop()
{
unsigned long valeurPot1 = analogRead(pinPot1);
unsigned long valeurPot2 = analogRead(pinPot2);
ClignoLED(valeurPot1* 10, valeurPot2* 4000); // de 1 à 1023 msecondes x 10 soit environ 10s max pour l'ouverture de la vanne et 1 à 1023 x 4000 = environ 1h d'interval entre l'ouverture
}//loop
 
void ClignoLED (int on, int off)
{
int intervalle = ComptCligno - ChangeLEDcligno;
if (EtatLEDcligno == HIGH && intervalle > on)
{
    
// éteint 
    
EtatLEDcligno = LOW;
    
digitalWrite(LEDcligno, EtatLEDcligno);
    
ChangeLEDcligno = ComptCligno;
}
  
else if (EtatLEDcligno == LOW && intervalle > off) 
  
{
    
// allumé
    
EtatLEDcligno = HIGH;
    
digitalWrite(LEDcligno, EtatLEDcligno);
    
ChangeLEDcligno = ComptCligno;
  
}
intervalle = 0;//RAZ
}//void

Le compileur me renvois systématiquement l’erreur
“distri_V4.ino: Dans la fonction «void loop()»:
distri_V4.ino:19:39: error: «pinPot1» n’a pas été déclaré dans cette portée
distri_V4.ino:20:39: error: «pinPot2» n’a pas été déclaré dans cette portée”

J’ai tout esseyé pour déclarer ces potentiomètre mais un truc m’échappe…

Voila, je crois que j’ai toujours besoin d’un coup de pousse
Merci

pinpot1 n'est pas égal à pinPot1 ... Il faut choisir !

désolé lesept, je ne vois pas ce que tu veux dire

Compareint pinpot1 =  A0;avecvaleurPot1 = analogRead(pinPot1);Tu ne vois rien ?

oups, je viens de voir...
la majuscule... :blush:

je viens de le changer
Par contre je ne suis pas sur d'avoir déclaré ces pin/potentiomètre au bon endroit...
Enfin le compileur ne me reproche rien cette fois :slight_smile:

Sinon, pense tu que je suis sur la bonne voie?
Je vais essayer le programme dès que possible.

Je n'ai pas vu de problème dans ton code, mais je ne connais pas la bibliothèque que tu utilises et en regardant le source, c'est trop compliqué pour moi...

Le plus simple c'est de tester...

bonjour
Je viens de tester
Le temps d’ouverture fonctionne bien (de 0 à 10 secondes environ) mais le temps intervalle ne fonctionne pas bien du tout.
Je pensais que le potentiomètre pouvait avoir un problème (pourtant neuf) alors j’en ai essayé plusieurs et testé, la tension est pourtant progressive et stable.
J’ai ajouté les instruction pour voir ce qui se passe sur un moniteur série et la c’est bisard: la valeur de “valeurPot2” augmente jusqu’a la moitié de la cource du poentiometre puis décroit.
J’ai vérifié les branchement mais c’est le meme que le premier potentiometre 1 donc ok.
Je me suis dit que c’est peut etre un probleme de longueur de la valeur. J’ai essayé plusieurs facteur de multiplication dans valeurpot1. La valeur affichée parait correcte mais rien n’y fait… Le maximum d’intervalle que j’obtient est environ 40 secondes…
auriez vous une idée?
voila le code que j’utilise:

#include <elapsedMillis.h>

int LEDcligno = 13; // LED de la pin 13 materialisera la sortie
int EtatLEDcligno = HIGH;
int ChangeLEDcligno = 0;
elapsedMillis ComptCligno; //compteur
int pinpot1 =  A0;      // crée un identifiant pour la broche utilisée avec le potentiometre 1
int pinpot2 =  A2;      // crée un identifiant pour la broche utilisée avec le potentiometre 2

void setup()
{
Serial.begin(9600);
pinMode(13, OUTPUT);
pinMode(pinpot1, INPUT);
pinMode(pinpot2, INPUT);
}
void loop()
{
unsigned long valeurPot1 = analogRead(pinpot1) * 10;
unsigned long valeurPot2 = analogRead(pinpot2) * 4000;
ClignoLED(valeurPot1, valeurPot2); // de 1 à 1023 msecondes x 10 soit environ 10s max pour l'ouverture de la vanne et 1 à 1023 x 4000 = environ 1h d'interval entre l'ouverture
Serial.println("tps ouverture:");
Serial.println(valeurPot1);
Serial.println("interval en minutes:");
Serial.println(valeurPot2 / 60000);
delay (500);
}//loop end

void ClignoLED (int on, int off)
{
int intervalle = ComptCligno - ChangeLEDcligno;
if (EtatLEDcligno == HIGH && intervalle > on)
{
    
// éteint 
    
EtatLEDcligno = LOW;
    
digitalWrite(LEDcligno, EtatLEDcligno);
    
ChangeLEDcligno = ComptCligno;
}
  
else if (EtatLEDcligno == LOW && intervalle > off) 
  
{
    
// allumé
    
EtatLEDcligno = HIGH;
    
digitalWrite(LEDcligno, EtatLEDcligno);
    
ChangeLEDcligno = ComptCligno;
  
}
intervalle = 0;//RAZ
}//void

merci encore

Bonjour,

A mon avis dans la multiplication par 4000 tu dépasses la capacité d'un int
Remplaces 4000 par 4000UL pour faire la multiplication en unsigned long.

Moi, je ne connais pas la biblio ellapsedMillis, alors je l'ai refait à ma sauce :

int LEDcligno = 13; // LED de la pin 13 materialisera la sortie
bool EtatLEDcligno = HIGH;
int pinpot1 =  A0;      // crée un identifiant pour la broche utilisée avec le potentiometre 1
int pinpot2 =  A2;      // crée un identifiant pour la broche utilisée avec le potentiometre 2
unsigned long chronoAllume = 0;
unsigned long chronoEteint = 0;

void setup() {
  Serial.begin(9600);
  while (!Serial);
  pinMode(LEDcligno, OUTPUT);
  digitalWrite (LEDcligno, EtatLEDcligno);
  pinMode(pinpot1, INPUT);
  pinMode(pinpot2, INPUT);
  chronoAllume = millis();
}

void loop() {
  // calcul du temps d'attente en fonction des valeurs lues
  unsigned long dureeAllume = analogRead(pinpot1) * 10;
  unsigned long dureeEteint = analogRead(pinpot2) * 4000;

  // si led allumée et durée pot1 dépassée :
  if (millis() - chronoAllume > dureeAllume && EtatLEDcligno) {
    Serial.print(millis() - chronoAllume);
    Serial.println(" : on eteint");
    chronoEteint = millis();
    EtatLEDcligno = !EtatLEDcligno;
    digitalWrite (LEDcligno, EtatLEDcligno);
  }

  // si led éteinte et durée pot2 dépassée :
  if (millis() - chronoEteint > dureeEteint && !EtatLEDcligno) {
    Serial.print(millis() - chronoEteint);
    Serial.println(" : on allume");
    chronoAllume = millis();
    EtatLEDcligno = !EtatLEDcligno;
    digitalWrite (LEDcligno, EtatLEDcligno);
  }
}

A tester, mais ça me semble plus simple comme ça...

Merci beaucoup Kamill et Lesept
En effet, les essais que j'ai fais avec le programme utilisant ellapsedmillis semblaient toujours coincer au moment ou la valeur de l'intervalle (issue de pot 1) devenait trop grande.
Avec le moniteur serie, la valeur la plus grande que j'ai vu ressemble au maximum de "unsigned long".
Mais ce que je ne coprend pas c'est que cette valeur équivaux à plus de 1000h si onl'atribu au temps en millisecondes.
hors l'intervalle que j'ai chronométré n'a jamais dépassé les 12seconde environ.
L'astuce de Kamill me fait penser que c'est effectivement quelque part dans le processus de calcul que cette grande valeur n'a pas assez d'espace...
Bref, je vais essayé de metre "UL" comme tu le dit Kamil.

Sinon, entre temps, ne comprenant rien non plus au fonctionnement de "ELAPSEDMILLIS" j'ai essayé d'adapter un autre programme. que je vous mets à la suite.
Et devinez... il donne exactement le même problème.
Ca me fait penser encore une fois que le problème est celui que Kamill soupçonne...
Je vais donc refaire des essais en suivant vos conseils.
tant qu'à faire je vais rester sur les programme avec "millis" qui sont plus à ma porter...

// These variables store the flash pattern
// and the current state of the LED.  from: https://learn.adafruit.com/multi-tasking-the-arduino-part-1/using-millis-for-timing

int ledPin =  13;      // the number of the LED pin
int ledState = LOW;             // ledState used to set the LED
int pinpot1 =  A0;      // crée un identifiant pour la broche utilisée avec le potentiometre 1
int pinpot2 =  A2;      // crée un identifiant pour la broche utilisée avec le potentiometre 2
unsigned long previousMillis = 0;        // will store last time LED was updated

void setup() 
{
Serial.begin(9600);
  // set the digital pin as output:
pinMode(ledPin, OUTPUT);      
pinMode(pinpot1, INPUT);
pinMode(pinpot2, INPUT);

}

void loop()
{
unsigned long valeurPot1 = analogRead(pinpot1) * 10;
unsigned long valeurPot2 = analogRead(pinpot2) * 4000;
unsigned long OnTime = valeurPot1;           // milliseconds of on-time
unsigned long OffTime = valeurPot2;          // milliseconds of off-time

Serial.println("tps ouverture:");
Serial.println(valeurPot1);
Serial.println("interval en heures:");
Serial.println(valeurPot2 / 3600000);
Serial.println("interval en minutes:");
Serial.println(valeurPot2 / 60000);
Serial.println("interval");
Serial.println(valeurPot2);
delay (400);

  // check to see if it's time to change the state of the LED
  unsigned long currentMillis = millis();
 
  if((ledState == HIGH) && (currentMillis - previousMillis >= OnTime))
  {
    ledState = LOW;  // Turn it off
    previousMillis = currentMillis;  // Remember the time
    digitalWrite(ledPin, ledState);  // Update the actual LED
  }
  else if ((ledState == LOW) && (currentMillis - previousMillis >= OffTime))
  {
    ledState = HIGH;  // turn it on
    previousMillis = currentMillis;   // Remember the time
    digitalWrite(ledPin, ledState);	  // Update the actual LED
  }
}

analogRead renvoie au pire 1023, ce qui est proche de 1000. Tu multiplies l'analogRead par 4000, qui est proche de 3600 (secondes dans une heure).

Donc au maximum, la durée sera proche de 1000 * 3600 millisecondes soit une heure (1h 8minutes et 12 secondes). Ça ne peut pas faire 1000 heures.

Si tu as des intervalles maximum de 12 secondes, c'est que ton analogRead te renvoie une donnée bien plus faible que 1023. Affiche la valeur du analogRead, tu verras ce qu'elle vaut au maximum. Ça peut venir de ta référence de tension ou de la tension au bornes du potentiomètre.

Tu peux essayer :

unsigned long valeurPot1 = analogRead(pinpot1) * 10ul;
unsigned long valeurPot2 = analogRead(pinpot2) * 4000ul;

mais je pense que le problème ne vient pas de là. Si tu as un multimètre, mesure la tension aux bornes du potentiomètre...

lesept:
mais je pense que le problème ne vient pas de là.

Je suis sur que le problème vient de là, le calcul est fait en entier et il y a débordement. Mais il y a peut être d’autres problèmes.

OK, tu as raison. Lorsque je ne mets pas ul
unsigned long valeurPot2 = analogRead(pinpot2) * 4000;valeurPot2 vaut 28768 pour un analogRead de 1023, mais avec ul
unsigned long valeurPot2 = analogRead(pinpot2) * 4000ul;valeurPot2 vaut bien 4092000. Étonnant, je pensais que la définition en unsigned long suffirait…

En C/C++ la manière dont est faite le calcul ne dépend pas de la variable de réception, mais uniquement du type des opérandes.

oups je me suis emmêlé les pinceaux dans les calculs...
mais en tout cas, ca marche!!!
C'est bien UL qui manquait après 4000.
Apparemment, j'ai la chance de ne pas avoir d'autre erreur.
Je continu a tester avant de valider définitivement. Notamment je vais chronométrer et brancher un compteur mécanique (le système a papa quoi). Comme ça je serais sur que ça marche de A à Z.
Je viens de tester et le moniteur série indique bien 68min au maximum

C'est grâce a votre aide.
J'ai appris des choses mais je vois que j'ai encore un sacré boulot avant de maîtriser un minimum...
Une fois validé je mettrais le code sur "project hub" au cas ou ça puisse être utile à un autre néophyte...
En tout cas, c'est vraiment chouette de votre part de donner ce genre de coup de pouce!!

Content d'avoir pu t'aider. Bonne continuation.