Gestion des "millis"

bonjours a tous.
Voici mon problème, je possède une barrière photoélectrique (fonctionnement contact sec NO-NC lors de la coupure du faisceau) et celle-ci (après coupure du faisceau) actionne un relais pendant 1 seconde après un temps d'attente de 15min. mon code de base avec un "délai" de 15s dans l'exemple (pour une question de facilité) fonctionne bien. Cependant j'aimerais que durant ce laps de temps si le faisceau et recouper le temps se réinitialise, il me faut donc une fonction 'millis" mais je suis perdu sur le fonctionnement de celle-ci

voici mon code depart

[code]


const int BUTTON_PIN = 7;
const int RELAY_PIN  = 3;

void setup() {
  Serial.begin(9600);
  pinMode(BUTTON_PIN, INPUT_PULLUP);
  pinMode(RELAY_PIN, OUTPUT);
}



void loop() {
  int buttonState = digitalRead(BUTTON_PIN);

  if (buttonState == LOW) {
    delay(10000);
    digitalWrite(RELAY_PIN, HIGH);
    delay(1000);
  }
  else if (buttonState == HIGH) {
    digitalWrite(RELAY_PIN, LOW);
  }
}
[/code]

ainsi qu'un autre en "millis" mais lorsque j'active mon bouton (photocellule) celui-ci active direct le relais pendant 1s et s'éteint

[code]


const int  BUTTON_PIN = 7;
const int RELAY_PIN  = 3;
unsigned long temps;
unsigned long temps1;


void setup() {
  Serial.begin(9600);
  pinMode(BUTTON_PIN, INPUT_PULLUP);
  pinMode(RELAY_PIN, OUTPUT);

}
void loop() {

  if ( digitalRead(BUTTON_PIN) == LOW )

  {
    temps = millis();

    if (millis() + temps >= 15000)

      digitalWrite(RELAY_PIN, HIGH);
    temps1 = millis();
  }

  if (millis() - temps1 >= 1000)
  {
    digitalWrite(RELAY_PIN, LOW);
  }
}
[/code]

est-ce quelqu'un pourrait m'aider car je bloque totalement.
merci d'avance a tous le monde

Ce que tu as codé corresponds à peu près à ça,

  • si le bouton est appuyé, tu mémorises le temps dans la variable "temps", tu regardes si le temps que tu viens de mémoriser quelques microsecondes plutôt est supérieur à 1500ms, si c'est le cas tu active la broche RELAY_PIN et tu mémorise le temps courant dans temps1
  • si le temps courant est supérieur de 1000ms au temps mémorisé dans temp1, tu désactives la broche RELAY_PIN

ceci étant répété en boucle par l'appel infinie de la fonction loop.

Si tu mets le code qui teste le "chrnometre"/temps dans un if, ton teste sera fait uniquement si la condition du "if" est à vrai.

merci de ta réponse, je suis désolé mais après plusieurs autres essais cela ne fonctionne toujours pas

Non, je ne pense pas.
Regarde, il y a un signe +

Pour faire une attente de 15s, il faudrait faire une soustraction.


Maintenant, si j'ai bien compris ce que tu veux.
  • on lit l'état de BUTTON_PIN
  • si un événement se produit on déclenche une temporisation de 15min (ou 15s ici)
  • si aucun événement et les 15min (ou 15s) sont passées on enclenche un relais pour 1s
  • si le relais est actif et les 1s sont écoulées on coupe le relais
  • on boucle sur le test

C'est bien ça?

Pour moi, il y a un trou dans la raquette.
Que fait-on si le relais est enclenché et qu'il y a un événement?

Cet une application qui se prête bien à l'utilisation d'une machine à état

Je ne comprends pas ta réponse.
les deux instructions(temps = ... et if (...)) étant consécutive, le temps donnée par les deux appels à millis ne doit pas être séparé de grand chose ?

Comme c'est une somme, 7.5s après le début du programme cette condition if (millis() + temps >= 15000 sera toujours vrai.
Ceci n'empêche pas que, comme tu l'as dit, l'enchaînement des tests ne correspond pas à ce que @roro12100 veut faire.

salut.
oui c'est bien ce que je souhaite faire avec en plus

  • si un évènement se produit alors que la tempo de 15 min (ici 15s) est active, on recommence la tempo

je ne me suis pas posé cette question encore vu que le relais n'est actif que 1s

merci de votre aide

Je ne peut pas deviner, ce que tu as essayé, si tu ne donne pas ton code, ce qu'il produit et ce que tu as attends, il sera difficile de t'aider :frowning:

As tu compris ce que moi et @fdufnews t'avons indiqué ?

Personnellement si tu es débutant je prendrais la problématique avec un autre angle.

  • mets en place une temporisation de 15s avant d'activer quelque chose (ex une LED ou ton relais).
  • modifie alors le code pour que la temporisation lorsque soit active suivant l'état d'une variable de type Booléen
  • Modifie alors le code pour que l'état de la précédent variable dépendent de l'activation du bouton BUTTON_PIN

Ha ok, je ne me suis pas du tout occupé de l'opérateur dans la condition, du fait que deux millis consécutif n'a pas vraiment de sens, enfin du moins ici :slight_smile:

C'est déjà inclus dans le pseudo code que j'ai mis. A chaque fois que l'on satisfait la condition si un événement se produit on déclenche une temporisation de 15min une temporisation est déclenchée donc si elle était en cours, on met à jour le temps de départ et donc la temporisation repart pour 15 min.

oui j'ai compris et oui effectivement je suis débutant je n'est fais jusqu’à présent que des code très simple.
je viens de suivre ton conseil commencé par créer une tempo avant d'activer une led.
mon code fonctionne quand j'active mon bouton ma tempo s'enclenche si je re-appuis celle-ci redémarre et après la tempo la led s'éteint

[code]


const int  BUTTON_PIN = 7;
const int RELAY_PIN  = 3;
unsigned long temps;
unsigned long temps1;


void setup() {
  Serial.begin(9600);
  pinMode(BUTTON_PIN, INPUT_PULLUP);
  pinMode(RELAY_PIN, OUTPUT);

}
void loop() {

  if ( digitalRead(BUTTON_PIN) == LOW ) {
    temps = millis();
    digitalWrite(RELAY_PIN, HIGH);
  }

  if (millis() - temps >= 15000) {
    digitalWrite(RELAY_PIN, LOW);
  }


}
[/code]

je continu de creuser dans cette direction

Très bien bien du coup maintenant, tu peux passer à l'étape suivante.
Lorsque tu appuis sur le bouton, tu n'active plus le relais, mais tu fait passer une variable(ex tempoActive) de false à true.
tu modifie ton chronomètre pour, pour que la condition soit si tempoActive est vrai et que ton chronomètre est supérieur à 15s, tu active ton relais et affecte une variable tempoRelache à vrai et lance un second chronomètre.

Tu duplique ton précédent chronomètre en utilisant dans celui-ci tempoRelache, la variable du second relais et le relâchement de ton relais.

Bien sûre, il y a une quantité infinie de code possible pour faire la même chose, ce n'est qu'un exemple, simple à coder :slight_smile:

je suis arrivé a ce code cependant j'ai toujours un souci. une fois téléversé la boucle se lance automatiquement sans appuis sur le bouton et la led s'allume au bout de 15s. J'ai du louper quelque chose

[code]


const int  BUTTON_PIN = 7;
const int RELAY_PIN  = 3;
unsigned long temps;
unsigned long temps1;
bool tempoActive = false;
bool tempoRelache = false;


void setup() {
  Serial.begin(9600);
  pinMode(BUTTON_PIN, INPUT_PULLUP);
  pinMode(RELAY_PIN, OUTPUT);

}
void loop() {


  if ( digitalRead(BUTTON_PIN) == LOW ) {
    tempoActive = true;
    temps = millis();
  }

  if (tempoActive = true && millis() - temps >= 15000) {
    digitalWrite(RELAY_PIN, HIGH);
    tempoRelache = true;
    temps1 = millis();
  }
  if (tempoRelache = true && millis() - temps1 >= 1000) {
    digitalWrite(RELAY_PIN, LOW);

  }

}
[/code]

Il faudrait peut-être penser à mettre tempoActive à false lorsque les 15s sont écoulées.

Pareil pour tempoRelache lorsque la seconde est écoulée à son tour

Dans le setup() il faut mettre la sortie RELAY_PIN telle que le relais soit inactif.

bonjour a tous.
voila modif faite mais toujours le même problème.
une fois téléversé je redémarre ma carte et au bout de 15s ma led sur le pin (relay-pin) s'allume et reste allumé, alors que je n'est pas appuyé sur le bouton.
quand j’appuie sur le bouton ma led s'éteint (comme si le code démarré correctement) pendant 15s et se rallume mais ne s'éteint pas après 1s

[code]


const int  BUTTON_PIN = 7;
const int RELAY_PIN  = 3;
unsigned long temps;
unsigned long temps1;
bool tempoActive = false;
bool tempoRelache = false;


void setup() {
  Serial.begin(9600);
  pinMode(BUTTON_PIN, INPUT_PULLUP);
  pinMode(RELAY_PIN, OUTPUT);
  digitalWrite(RELAY_PIN, LOW);
}

void loop() {

  if ( digitalRead(BUTTON_PIN) == LOW  ) {
    tempoActive = true;
    temps = millis();
  }

  if (tempoActive = true && millis() - temps >= 15000) {
    digitalWrite(RELAY_PIN, HIGH);
    tempoRelache = true;
    tempoActive = false;
    temps1 = millis();
  }

  if (tempoRelache = true && millis() - temps1 >= 1000) {
    digitalWrite(RELAY_PIN, LOW);
    tempoRelache = false;
  }
}
[/code]

je mettrais plutôt un == pour ça.....

Comme l'indique @fdufnews,cela ne correspond pas à ce que tu veux faire.
l'opérateur "=" fait une affectation de valeur, alors que "==" test l'égalité et renvois un booleen.
Du coup la première fois que tu passe sur cette instruction, la valeur "true" est affectée à la variable tempoActive et la première partie de la condition est donc toujours vrai.
Même quand au bout de 15s tu va affecter "false" à tempoActive, au prochain passage la variable va changer de valeur pour repasser à vrai et la première partie de la condition sur encore à vrai :slight_smile:

merci les gars tous fonctionne sans vous j'y serais pas arrivé.
par contre il ma fallu deux essais car au premier coup quand @fdufnews m'a dit de rajouter "==" a "tempoActive = true" sa n'a rien changer du tout et je n'avais pas testé au deux lignes "if (tempoActive = true && millis() - temps >= 15000) {".
@terwal merci pour toutes ses explications.
Je n'est plus qu'a mettre tout sa au concret et finir mon projet.
Encore merci a vous deux vous êtes trop fort et j'ai appris beaucoup

[code]


const int  BUTTON_PIN = 7;
const int RELAY_PIN  = 3;
unsigned long temps;
unsigned long temps1;
bool tempoActive = false;
bool tempoRelache = false;


void setup() {
  Serial.begin(9600);
  pinMode(BUTTON_PIN, INPUT_PULLUP);
  pinMode(RELAY_PIN, OUTPUT);

}

void loop() {

  if ( digitalRead(BUTTON_PIN) == LOW  ) {
    tempoActive = true;
    temps = millis();
  }

  if (tempoActive == true && millis() - temps >= 15000) {
    digitalWrite(RELAY_PIN, HIGH);
    tempoRelache = true;
    tempoActive = false;
    temps1 = millis();
  }

  if (tempoRelache == true && millis() - temps1 >= 1000) {
    digitalWrite(RELAY_PIN, LOW);
    tempoRelache = false;
  }
}
[/code]

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