Bonjour à tous, je débute dans l'Arduino et je rencontre un petit problème lorsque j'essaie de développer mon petit projet. Donc sur une platine d'essai est branché une LED ainsi qu'un capteur de contact magnétique. Mon but serais alors que lorsque que le contact magnétique n'est plus établi au bout de 4 minutes alors la LED s'allume. Pour le moment j'arrive bien à faire marcher le programme mais sans le petit "timer" de 4 minutes, je ne sais pas comment m'y prendre. Merci d'avance.
Code :
const int L1 = 5;
const int capteur = 4;
int etat;
void setup()
{
pinMode(capteur, INPUT_PULLUP);
pinMode(3, OUTPUT);
}
void loop()
{
etat = digitalRead(capteur);
if (etat == HIGH)
analogWrite(L1, 50);
else
analogWrite(L1, 0);
delay(200);
}
c'est typiquement une définition de programme qui se prête bien à la programmation par machine à états (cf mon tuto éventuellement)
on utilisera effectivement millis() pour déclencher un évènement de transition au bout des 4 minutes : au moment de la détection du capteur on mémorise la valeur de millis() dans une variable globale T0 et on passe en état ALERTE. dans cet état on teste d'abord si on est revenu aux conditions initiales sinon on teste si le temps est écoulé if (millis() - T0 >= 240000ul) { ... // plus de 4 minutes
il faut ensuite pouvoir sortir du mode LED allumée pour retourner à l'état initial, sans doute sur désactivation du capteur ?
Voici le résultat, j'ai testé, ça fonctionne plutôt bien, mais j'aimerais avoir votre avis pour savoir si j'ai pu quand même faire des erreurs dans le code, merci.
const int L1 = 5;
const int capteur = 4;
int etat;
int tempo = 0;
unsigned long T0 = 0;
void setup()
{
pinMode(capteur, INPUT_PULLUP);
pinMode(5, OUTPUT);
}
void loop()
{
etat = digitalRead(capteur);
if (etat == LOW) {
tempo = 1;
T0 = millis();
}
if (tempo) {
if ((millis()- T0) >= 5000) {
analogWrite(L1, 50);
tempo = 0;
}
else {
analogWrite(L1, 0);
delay(200);
}
}
}
vous n'avez pas du bien lire le tuto sur les machines à états - je ne vois pas les 3 états de mon diagramme
votre souci c'est que si le capteur est LOW vous remettez constamment à jour T0. Il ne faut plus le faire une fois qu'il est déclenché ➜ c'est le passage dans mon état 'ALERTE' du dessin
faut pas s'excuser, pas de souci. Vous débutez. Essayez de faire comme dans le tuto, un enum pour les 3 états et une seule variable d'état avec un switch()
Pour moi, utiliser une machine à état ici est un peu superflu.
On peut utiliser un petit timer de 4 minutes:
~ quand il arrive à échéance, on allume la led
~ si le contact est établi, on remet le timer à zéro et on éteint la led (que cette dernière soit allumée ou éteinte)
En reprenant le code au plus près:
void loop()
{
etat = digitalRead(capteur);
if (etat == HIGH) // Le capteur n'est pas activé
{
if (millis() - T0 > 5L*60*1000)
analogWrite(L1, 50);
}
else // Le capteur est activé
{
T0 = millis(); // Réinitialiser le timer
analogWrite(L1, 0); // Eteindre la led
}
}
Pour la led:
~ soit on allume la led en tout ou rien, alors pinMode(3, OUTPUT); est obligatoire, mais pour l'allumer il faut digitalWrite(L1);
~soit on l'allume pas à fond, et c'est bien analogWrite(L1, 50); qui l'allume, mais le pinMode(3, OUTPUT); ne sert plus à rien:
Page Reference > Language > Functions > Analog io > Analogwrite il est dit:
You do not need to call pinMode() to set the pin as an output before calling analogWrite().
Attention aussi que ce n'est pas pour détecter un arrêt mécanique genre arbre en rotation, car si l'arrêt se fait lorsque le contact est établi, le timer serait constamment remis à 0 et la led ne s'allumerait pas. Il faut dans ce cas non pas remettre à 0 le timer "quand le contact est établi" mais "quand le contact vient d'être établi". Autrement dit non pas quand il est HIGH, mais quand il vient de passer à HIGH (il est HIGH et juste avant il était LOW).
Cela fait 5000 millisecondes soit 5s. C'est bien pour les essais, mais on est loin des 5 minutes. Attention 5000 * 60 sur une Uno ne fait pas 5 minutes car le calcul est fait avec des entiers. Il faut alors écrire 5000L * 60
Vous avez raison, dans les cas simple on peut faire simple, mais c'est juste une bonne façon d'apprendre et de rendre le code assez évolutif si ensuite on veut rajouter d'autres conditions / transitions / états