Exercice : fonction millis() pour retarder allumage LED ?

Toutes les discussions sur l'Arduino !

Modérateur : MOD

Répondre
Avatar du membre
François D
Intarissable !
Messages : 4301
Enregistré le : mer. 27 déc. 2006, 22:26
Echelle pratiquée : [0]
Localisation : JOUE
Âge : 58

Exercice : fonction millis() pour retarder allumage LED ?

Message par François D » jeu. 16 mai 2019, 23:01

Bonjour,

Si je parcours et contribue +/- souvent sur d'autres sujets du forum, je m'aventure pour la 1ère fois ici :oops: :oops:
Je découvre ARDUINO pour animer surtout le TCO et les quelques signaux de mes modules. Je progresse étape par étape avec des petits exercices très simples mais je bloque depuis plusieurs jours sur un code utilisant la fonction millis().

Ce que je veux faire :
- sur le TCO : un interrupteur-poussoir ON/OFF (appelé interrupteur 1) est couplé à une LED appelée LED1,
- sur le réseau : un signal comportant une LED violette (LEDcarreViolet) et une LED blanche (LEDblanc)
- si l'interrupteur-poussoir est ouvert (OFF), l'itinéraire n'est pas sélectionné et le signal Cv est fermé (LEDcarreViolet est allumée)
- En appuyant sur l'nterrupteur-poussoir (ON) , je sélectionne l'itinéraire.
- LED1 clignote alors 3 fois puis reste allumée de manière fixe pour simuler sur le TCO l'enclenchement de l'itinéraire,
- Une fois que LED1 est allumée au fixe, LEDcarreViolet reste encore allumée pendant une durée fixée arbitrairement à 7 secondes puis...
- LEDcarreViolet s'éteint et LEDblanc s'allume au fixe.
- Quand l'interrupteur repasse sur OFF, LED1 s'éteint, et le signal repasse à LEDcarreviolet (destruction de l'itinéraire)

Je veux utiliser la fonction millis() pour la partie du programme qui temporise l'allumage de LEDblanc. (c'est le but de mon exercice).

Pour mieux comprendre mes lignes de la fonction loop(), je me suis fait un "logigramme" ...
Arduino logigramme LR4.jpg
...pourtant ça ne marche pas complètement. le programme fonctionne bien dans sa première partie (allumage et clignotement de LED1) mais il n'y a aucun 'allumage temporisé de LEDblanc ni extinction de LEDcarreViolet comme si la fonction millis() était totalement ignorée

Où est à votre avis l'erreur dans le code ?

Merci d'avance !


// fait clignoter un interrupteur fermé pendant un nombre choisi de fois puis le laisse
// au fixe.
// pourrait être utilisé pour les boutons-interrupteur pour les tracé d'initinéraire au PRS
// clignotement "itinéraire enregistré" ; "fixe "itinéraire enclenché"


int LED1 = 4 ; // attribue le nom LED à la broche 4
int incremClin1 = 0 ; // variable d'incrémentation du clignotement
int inter1 = 2 ; // attribue le nom inter à la broche 2
int interrupteur1 = 0; // attribue le nom interrupteur à la lecture de la broche 2
int LEDcarreViolet = 5 ; // attrinue le nom LEDcarreViolet à la broche 5
int LEDblanc = 3; //,attribue le nom LEDblanc à la broche 3
unsigned long dateCourante = millis();
unsigned long dateEnclenchement;
unsigned long intervalle=dateCourante-dateEnclenchement;

void setup() {
pinMode (LED1,OUTPUT);
pinMode (inter1,INPUT);
pinMode (LEDcarreViolet, OUTPUT);
pinMode (LEDblanc,OUTPUT);
digitalWrite(LEDblanc,LOW);
dateCourante=0;
}

void loop() {
interrupteur1 = digitalRead(2); // lecture digitale de la broche 2




if (interrupteur1 == LOW)
{ // si interrupteur ouvert (pas d'itinéraire)
incremClin1=0; // incrémentation du clignotement1 remis à 0
digitalWrite (LED1,LOW); // LED éteinte
digitalWrite (LEDblanc,LOW);
digitalWrite (LEDcarreViolet,HIGH); // Cv allumé
}

else // sinon .... = interrupteur fermé (enclenchement d'itinéraire)
if (incremClin1<3) // séquence de clignotement (n=3)
{
digitalWrite (LEDcarreViolet,HIGH);
digitalWrite (LEDblanc,LOW);
digitalWrite (LED1,HIGH);
delay (600) ;
digitalWrite (LED1,LOW);
delay (600);
incremClin1=incremClin1+1;
dateEnclenchement=dateCourante;
}
else
{
digitalWrite (LED1,HIGH); // ... fixe après le clignotement
delay (50);
}


if (intervalle>7000) // intervalle date courante et date enclenchement
{
digitalWrite(LEDblanc,HIGH); // ... éteint Cv, allume le blanc si intervalle > 7000
digitalWrite (LEDcarreViolet,LOW);
}
else{
digitalWrite(LEDblanc,LOW);
digitalWrite(LEDcarreViolet,HIGH);
}

}

//////////////////////////////////////////////////////////////////////////////////////
FD

Avatar du membre
jlb
Fécond
Messages : 694
Enregistré le : jeu. 04 oct. 2012, 16:38
Echelle pratiquée : N
Prénom : Jean-Luc
Site Internet : http://modelleisenbahn.triskell.org

Re: Exercice : fonction millis() pour retarder allumage LED ?

Message par jlb » jeu. 16 mai 2019, 23:20

Bonsoir,

Alors. millis() est appelée une fois pour initialiser dateCourante au moment de sa déclaration. Je ne suis même pas sûr du sens de ceci. Lors de l'initialisation des variables globales, l'Arduino n'est pas initialisé et le temps de s'écoule pas. Supposons que ça soit 0.
dateCourante est mis à 0 dans setup ce qui écrase la valeur qui y a été mise au moment de la déclaration.
Ensuite dateCourante n'est plus jamais modifiée. Elle ne contient donc en aucun cas la date courante (il faudrait lui affecter millis() à intervalles régulier.
intervalle a été initialisé au moment de sa déclaration avec dateCourante-dateEnclenchement. Je ne sais pas ce qui est dans dateCourante à ce moment là (les variables sont-elle initialisées dans l'ordre de déclaration, pas sûr, c'est non spécifié dans le langage). dateEnclenchement est non intialisé. intervalle a donc une valeur inconnue mais je parierais sur 0. Ensuite intervalle n'est jamais modifié. Donc le test intervalle > 7000 est faux.

Votre programme ne correspond pas à votre organigramme

Il ne faut pas :
1 - initialiser une variable globale avec le résultat renvoyé par une fonction. C'est piégeux.
2 - initialiser une variable globale avec une autre variable globale. Rien ne spécifie que ceci sera fait dans l'ordre.

Ensuite si vous souhaitez organiser des choses au fil du temps, je vous suggère de jeter un œil à ScheduTable : http://www.locoduino.org/spip.php?article116 et si vous souhaitez manipuler des LED et les faire clignoter, regardez LightDimmer : https://github.com/Locoduino/LightDimmer

Ces deux bibliothèques sont disponibles via le gestionnaire de bibliothèques de l'IDE Arduino

Cordialement

Avatar du membre
François D
Intarissable !
Messages : 4301
Enregistré le : mer. 27 déc. 2006, 22:26
Echelle pratiquée : [0]
Localisation : JOUE
Âge : 58

Re: Exercice : fonction millis() pour retarder allumage LED ?

Message par François D » ven. 17 mai 2019, 06:49

Merci pour toutes ces indications.
Je m'y suis remis en en tenant compte .... et ça marche ! :D
FD

Avatar du membre
François D
Intarissable !
Messages : 4301
Enregistré le : mer. 27 déc. 2006, 22:26
Echelle pratiquée : [0]
Localisation : JOUE
Âge : 58

Re: Exercice : fonction millis() pour retarder allumage LED ?

Message par François D » ven. 17 mai 2019, 16:55

Nouveau logigramme après prise en compte de vos corrections.
Après écriture du code, ça fonctionne comme je le souhaite. Je vais pouvoir passer à l'étape suivante.
Merci à vous.

Arduino logigramme LR5.jpg
Arduino logigramme LR5.jpg (59.6 Kio) Vu 1052 fois
// fait clignoter un interrupteur fermé pendant un nombre choisi de fois puis le laisse
// au fixe.
// pourrait être utilisé pour les boutons-interrupteur pour les tracé d'initinéraire au PRS
// clignotement "itinéraire enregistré" ; "fixe "itinéraire enclenché"


int LED1 = 4 ; // attribue le nom LED à la broche 4
int incremClin1 = 0 ; // variable d'incrémentation du clignotement
int inter1 = 2 ; // attribue le nom inter à la broche 2
int interrupteur1 = 0; // attribue le nom interrupteur à la lecture de la broche 2
int LEDcarreViolet = 5 ; // attrinue le nom LEDcarreViolet à la broche 5
int LEDblanc = 3; //,attribue le nom LEDblanc à la broche 3
unsigned long dateCourante;
unsigned long dateEnclenchement;
unsigned long intervalle;

void setup() {
pinMode (LED1,OUTPUT);
pinMode (inter1,INPUT);
pinMode (LEDcarreViolet, OUTPUT);
pinMode (LEDblanc,OUTPUT);
digitalWrite(LEDblanc,LOW);
dateCourante=0;

}

void loop() {
interrupteur1 = digitalRead(2); // lecture digitale de la broche 2




if (interrupteur1 == LOW)
{ // si interrupteur ouvert (pas d'itinéraire)
dateCourante=millis();
dateEnclenchement=dateCourante; // remet à zéro " intervalle"
incremClin1=0; // remet à zéro l' incrémentation du clignotement1
digitalWrite (LED1,LOW); // LED éteinte
digitalWrite (LEDblanc,LOW);
digitalWrite (LEDcarreViolet,HIGH); // Cv allumé
}

else // sinon .... = interrupteur fermé (enclenchement d'itinéraire)
if (incremClin1<3) // séquence de clignotement (n=3)
{
incremClin1=incremClin1+1;
dateCourante=millis();
dateEnclenchement=dateCourante;
digitalWrite (LEDcarreViolet,HIGH);
digitalWrite (LEDblanc,LOW);
digitalWrite (LED1,HIGH);
delay (600) ;
digitalWrite (LED1,LOW);
delay (600);

}
else
{
digitalWrite (LED1,HIGH); // ... fixe après le clignotement
delay (50);
}

dateCourante=millis();
intervalle=dateCourante - dateEnclenchement;

if (intervalle>7000) // intervalle date courante et date enclenchement
{
digitalWrite(LEDblanc,HIGH); // ... éteint Cv, allume le blanc si intervalle > 7000
digitalWrite (LEDcarreViolet,LOW);
}
else{

digitalWrite(LEDblanc,LOW);
digitalWrite(LEDcarreViolet,HIGH);
}

}

//////////////////////////////////////////////////////////////////////////////////////
FD

Répondre