Projet sur Arduino => allumer une LED en tapant 2 fois dans les mains
Résolu
frozice
-
-
-
Bonjour,
j'ai un projet qui consiste à allumer une LED en tapant 2 fois dans le mains sur ARDUINO.
En gros :
Après avoir taper 1 fois dans les mains, si pendant un petit temps donné on ne tape pas une deuxième fois dans les mains alors la LED ne s'allume pas. Pareillement pour l'éteindre.
Il faut donc taper 2 fois assez rapidement pour pouvoir l'allumer.
Mon problème c'est que je n'arrive pas à faire le programme.
J'ai déjà le montage.
Pour l'instant j'ai trouvé ça pour l'allumer en tapant une fois dans les mains :
J’espère avoir des retours.
Merci d'avance.
j'ai un projet qui consiste à allumer une LED en tapant 2 fois dans le mains sur ARDUINO.
En gros :
Après avoir taper 1 fois dans les mains, si pendant un petit temps donné on ne tape pas une deuxième fois dans les mains alors la LED ne s'allume pas. Pareillement pour l'éteindre.
Il faut donc taper 2 fois assez rapidement pour pouvoir l'allumer.
Mon problème c'est que je n'arrive pas à faire le programme.
J'ai déjà le montage.
Pour l'instant j'ai trouvé ça pour l'allumer en tapant une fois dans les mains :
void setup() { Serial.begin(9600); // using serial port to check analog value pinMode(2, OUTPUT); // LED on digital pin 2 } void loop() { int analog_val; // analog value read from A2 static bool led_state = false; // current state of LED analog_val = analogRead(A2); if (analog_val > 10) { // trigger threshold // toggle LED if (led_state) { led_state = false; // LED was on, now off digitalWrite(2, LOW); Serial.println(analog_val); // print analog value for debug purposes } else { led_state = true; digitalWrite(2, HIGH); // LED was off, now on Serial.println(analog_val); } delay(50); // wait for clap noise to subside } }
J’espère avoir des retours.
Merci d'avance.
Configuration: Windows / Firefox 76.0
A voir également:
- Lampe qui s'allume en frappant dans les mains
- Mon pc s'allume mais ne démarre pas windows 10 - Guide
- Mon pc s'allume mais lécran reste noir sans bip - Guide
- Pc qui s'allume et s'éteint en boucle - Forum Matériel & Système
- Installer lampe torche sur mon téléphone - Télécharger - Vie quotidienne
- Tele qui s'allume toute seule signification - Forum TV & Vidéo
8 réponses
Bonjour,
Qui dit projet dit recherche, essais, corrections, améliorations. C'est de mon point de vue la démarche qui permet la satisfaction d'avoir trouvé la solution.
Pour l'instant, je subodore que vous avez trouvé un code sur le net et n'avez même pas cherché à le modifier d'un iota.
Comme vous le dîtes, ce code permet de changer une fois l'état de la diode.
Si l'on veut que l'action se fasse après deux claps, il faut sans doute introduire une boucle de comptage avant la détection du clap, par exemple un while en ligne 11.
Une fois cela fait, il faudra sans doute ajuster le délai de 50 millisecondes pour régler l'écart entre les deux claps.
Je vous laisse faire le reste puisqu'ils 'agit manifestement d'un exercice.
Faîtes part de vos progressions ou blocages en repostant un code modifié et commenté par vous pour situer les blocages et joignez y les éventuels messages d'erreur.
Cordialement
Qui dit projet dit recherche, essais, corrections, améliorations. C'est de mon point de vue la démarche qui permet la satisfaction d'avoir trouvé la solution.
Pour l'instant, je subodore que vous avez trouvé un code sur le net et n'avez même pas cherché à le modifier d'un iota.
Comme vous le dîtes, ce code permet de changer une fois l'état de la diode.
Si l'on veut que l'action se fasse après deux claps, il faut sans doute introduire une boucle de comptage avant la détection du clap, par exemple un while en ligne 11.
Une fois cela fait, il faudra sans doute ajuster le délai de 50 millisecondes pour régler l'écart entre les deux claps.
Je vous laisse faire le reste puisqu'ils 'agit manifestement d'un exercice.
Faîtes part de vos progressions ou blocages en repostant un code modifié et commenté par vous pour situer les blocages et joignez y les éventuels messages d'erreur.
Cordialement
Salut frozice,
Sur Arduino, tu peux quantifier le temps qui passe avec la fonction millis()
https://www.arduino.cc/reference/en/language/functions/time/millis/
Dal
Sur Arduino, tu peux quantifier le temps qui passe avec la fonction millis()
https://www.arduino.cc/reference/en/language/functions/time/millis/
Dal
Bonsoir à tous deux,
@ [Dal],
Je n'ai pas une grande expertise en "langage" Arduino (je fais de la robotique en utilisant un "fork" de Scratch nommé Mblock.
Mais je peux affirmer en m'appuyant sur des lectures appropriées (notamment Srackoverflow.com) que la fonction loop() ne peut être employée qu'une fois.
Elle correspond à la fonction main() en C et englobe toutes les autres fonctions après les déclarations de variables et le paramétrage du GPIO. A la différence que le programme boucle indéfiniment à la fin du bloc loop(), ce qui permet notamment de checker en permanence les variables correspondant aux entrées-sorties de la carte.
A moins que j'aie mal interprété l'expression Tu mets toute ta logique dans une seule itération de la fonction loop() et tu voudras bien dans ce cas m'en excuser.
@ frozice,
Bravo si vous le permettez d'avoir persévéré et introduit vos modifs. Vous voyez que vous progressez en surmontant vos erreurs ou votre maîtrise du langage. Comme je le disais, c'est ainsi que je procède (je lis tout de même les tutoriels sur les différents langages).
J'ai mis pour la part des mois à comprendre comment fonctionnait millis() dans certains programmes. La principale différence entre delay() et millis() est que la première fonction interrompt la fonction en cours pour exécuter une ou plusieurs autres fonctions, puis retour à la fonction de départ.
Millis() permet d'exécuter parallèlement plusieurs fonctions:
Par exemple, je lance un mouvement du robot, puis je mesure une température sur un capteur pendant 3 secondes, je pourrais lancer un autre mouvement du robot pendant ces 3 secondes, ce que je ne peux pas faire avec delay(), qui, s'il dure 10 secondes, bloque toutes les autre fonctions qu'on pourrait souhaiter lancer pendant ces 3 ou 10 secondes.
Je ne suis pas persuadé par ailleurs que millis() soit indispensable pour ce double clap, mais s'il en complique l'exécution, tant que vous n'en aurez pas la maîtrise, je vous propose d'utiliser delay() dans un premier temps, à moins que la précision entre les deux claps soit essentielle.
Par ailleurs, vous utilisez trop de while, un seul devrait suffire (voire deux) comme indiqué dans mon premier post, while() placé dans le loop() et qui engloberait l'ensemble détection de clap/action consécutive.
La fonction compteur() est parfaitement superflue comme l'indique Dal, puisque vous disposez de delay() ou millis()
Je vous incite de rester sous la houlette bienveillante de Dal, qui est bien plus qualifié que moi en programmation (je le sais parce que je le suis depuis des années et ai beaucoup appris et continue de profiter indirectement de ses conseils).
Mais si vous le permettez et le jugez utile, je ferais des commentaires de ce type en toute humilité et dans un esprit d'change.
Je n'ai pas le temps en ce moment de vous proposer une version de ce code, mais le ferai par la suite si cela s'avère utile.
Cordialement
@ [Dal],
Je n'ai pas une grande expertise en "langage" Arduino (je fais de la robotique en utilisant un "fork" de Scratch nommé Mblock.
Mais je peux affirmer en m'appuyant sur des lectures appropriées (notamment Srackoverflow.com) que la fonction loop() ne peut être employée qu'une fois.
Elle correspond à la fonction main() en C et englobe toutes les autres fonctions après les déclarations de variables et le paramétrage du GPIO. A la différence que le programme boucle indéfiniment à la fin du bloc loop(), ce qui permet notamment de checker en permanence les variables correspondant aux entrées-sorties de la carte.
A moins que j'aie mal interprété l'expression Tu mets toute ta logique dans une seule itération de la fonction loop() et tu voudras bien dans ce cas m'en excuser.
@ frozice,
Bravo si vous le permettez d'avoir persévéré et introduit vos modifs. Vous voyez que vous progressez en surmontant vos erreurs ou votre maîtrise du langage. Comme je le disais, c'est ainsi que je procède (je lis tout de même les tutoriels sur les différents langages).
J'ai mis pour la part des mois à comprendre comment fonctionnait millis() dans certains programmes. La principale différence entre delay() et millis() est que la première fonction interrompt la fonction en cours pour exécuter une ou plusieurs autres fonctions, puis retour à la fonction de départ.
Millis() permet d'exécuter parallèlement plusieurs fonctions:
Par exemple, je lance un mouvement du robot, puis je mesure une température sur un capteur pendant 3 secondes, je pourrais lancer un autre mouvement du robot pendant ces 3 secondes, ce que je ne peux pas faire avec delay(), qui, s'il dure 10 secondes, bloque toutes les autre fonctions qu'on pourrait souhaiter lancer pendant ces 3 ou 10 secondes.
Je ne suis pas persuadé par ailleurs que millis() soit indispensable pour ce double clap, mais s'il en complique l'exécution, tant que vous n'en aurez pas la maîtrise, je vous propose d'utiliser delay() dans un premier temps, à moins que la précision entre les deux claps soit essentielle.
Par ailleurs, vous utilisez trop de while, un seul devrait suffire (voire deux) comme indiqué dans mon premier post, while() placé dans le loop() et qui engloberait l'ensemble détection de clap/action consécutive.
La fonction compteur() est parfaitement superflue comme l'indique Dal, puisque vous disposez de delay() ou millis()
Je vous incite de rester sous la houlette bienveillante de Dal, qui est bien plus qualifié que moi en programmation (je le sais parce que je le suis depuis des années et ai beaucoup appris et continue de profiter indirectement de ses conseils).
Mais si vous le permettez et le jugez utile, je ferais des commentaires de ce type en toute humilité et dans un esprit d'change.
Je n'ai pas le temps en ce moment de vous proposer une version de ce code, mais le ferai par la suite si cela s'avère utile.
Cordialement
Si au moins quelqu'un saurait comment faire un programme où on doit juste allumer quelque chose en sortie mais pour ça il faut 2 enclenchements sur un bouton par exemple et non pas 1.
Je dois avoué que je suis désespéré ...
Je dois avoué que je suis désespéré ...
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question
Bonjour,
Ça y est j'ai réussi à faire allumer la LED avec 2 clappements grâce à des boucles while.
Ce qui se passe avec le programme ci-après, c'est que quand je clap 1 fois cela ne fait rien et si après un délaie infini je clap une 2ème fois la LED s'allume.
Donc tant que je clap 2 fois dans les mains, qu'importe le temps d'attente, la
LED va s'allumer.
Le problème maintenant c'est que je n'arrive pas à mettre un temps limite entre les 2 clappements.
Pour le délaie limite, j'ai créé un compteur de temps hors du programme principale. Je n'ai pas réussi à placer la fonction millis() car elle compte au lancement du programme et non au 1er clappement rendent nécessaire l'utilisation de soustraction à plusieurs endroits du programme ce que je trouve plus compliqué.
Merci des futurs réponses.
void setup()
{
pinMode(2, OUTPUT); // LED sur la branche pin 2
}
void compteur ()
{
int compteur ;
for (compteur < 2000 ; compteur > 2000 ; compteur = compteur + 5)
{
delay (5);
}
}
void loop()
{
int analog_val; // valeur analogique lue sur A2
static bool led_state = false; // état actuel de la LED
int compteur = 2000;
analog_val = analogRead(A2);
while (analog_val <= 10) // 1er clap
{
analog_val = analogRead(A2);
}
compteur = 0;
delay (100); // delaie entre 1er clap et 2eme clap
analog_val = analogRead(A2);
while (compteur < 1000 )
{
while (analog_val <= 10) // 2eme clap
{
analog_val = analogRead(A2);
}
if (led_state) // si la LED est allumée
{
led_state = false; // LED était allumée, maintenant éteinte
digitalWrite(2, LOW);
}
else // si la LED est éteinte
{
led_state = true;
digitalWrite(2, HIGH); // LED était éteinte, maintenant allumée
}
delay(50); // attendre que le bruit des claquements disparaisse
}
}
Ça y est j'ai réussi à faire allumer la LED avec 2 clappements grâce à des boucles while.
Ce qui se passe avec le programme ci-après, c'est que quand je clap 1 fois cela ne fait rien et si après un délaie infini je clap une 2ème fois la LED s'allume.
Donc tant que je clap 2 fois dans les mains, qu'importe le temps d'attente, la
LED va s'allumer.
Le problème maintenant c'est que je n'arrive pas à mettre un temps limite entre les 2 clappements.
Pour le délaie limite, j'ai créé un compteur de temps hors du programme principale. Je n'ai pas réussi à placer la fonction millis() car elle compte au lancement du programme et non au 1er clappement rendent nécessaire l'utilisation de soustraction à plusieurs endroits du programme ce que je trouve plus compliqué.
Merci des futurs réponses.
void setup()
{
pinMode(2, OUTPUT); // LED sur la branche pin 2
}
void compteur ()
{
int compteur ;
for (compteur < 2000 ; compteur > 2000 ; compteur = compteur + 5)
{
delay (5);
}
}
void loop()
{
int analog_val; // valeur analogique lue sur A2
static bool led_state = false; // état actuel de la LED
int compteur = 2000;
analog_val = analogRead(A2);
while (analog_val <= 10) // 1er clap
{
analog_val = analogRead(A2);
}
compteur = 0;
delay (100); // delaie entre 1er clap et 2eme clap
analog_val = analogRead(A2);
while (compteur < 1000 )
{
while (analog_val <= 10) // 2eme clap
{
analog_val = analogRead(A2);
}
if (led_state) // si la LED est allumée
{
led_state = false; // LED était allumée, maintenant éteinte
digitalWrite(2, LOW);
}
else // si la LED est éteinte
{
led_state = true;
digitalWrite(2, HIGH); // LED était éteinte, maintenant allumée
}
delay(50); // attendre que le bruit des claquements disparaisse
}
}
Bonjour,
J'ai réussi a faire 2 clap pour que la led s'allume sur un temps donné. Mais le problème c'est qu'après l'avoir allumé la led ne veut plus s'éteindre.
Ci-après le programme que j'ai fais.
Je ne sais pas su tout pourquoi ça ne marche pas !
Si vous avez des réponses a ma question ...
void setup()
{
pinMode(2, OUTPUT); // LED sur la branche pin 2
}
void(* reset) (void) = 0; //declare reset function @ address 0
void loop()
{
long PREMIER_CLAP;
long DEUXIEME_CLAP;
long temps;
int analog_val; // valeur analogique lue sur A2
static bool led_state = false; // état actuel de la LED
analog_val = analogRead(A2);
while (analog_val <= 10) // 1er clap
{
analog_val = analogRead(A2);
}
PREMIER_CLAP = millis() + 200; // délaie minimum
DEUXIEME_CLAP = PREMIER_CLAP + 2000; // delaie entre 1er clap et 2eme clap
temps = millis();
while (temps < PREMIER_CLAP) // attente du délaie minimum
{
temps = millis();
}
analog_val = analogRead(A2);
while (temps < DEUXIEME_CLAP && analog_val < 10) // attente du 2eme clap ou du reset
{
analog_val = analogRead(A2);
temps = millis();
}
if (temps >= DEUXIEME_CLAP)
{
delay(50);
reset();
}
else
{
if (led_state) // si la LED est allumée
{ //
led_state = false; // LED était allumée, maintenant éteinte
digitalWrite(2, LOW); //
} //
//
else // si la LED est éteinte
{ //
led_state = true; //
digitalWrite(2, HIGH); // LED était éteinte, maintenant allumée
} //
}
delay(200); // attendre que le bruit des claquements disparaisse
reset();
}<code>
J'ai réussi a faire 2 clap pour que la led s'allume sur un temps donné. Mais le problème c'est qu'après l'avoir allumé la led ne veut plus s'éteindre.
Ci-après le programme que j'ai fais.
Je ne sais pas su tout pourquoi ça ne marche pas !
Si vous avez des réponses a ma question ...
void setup()
{
pinMode(2, OUTPUT); // LED sur la branche pin 2
}
void(* reset) (void) = 0; //declare reset function @ address 0
void loop()
{
long PREMIER_CLAP;
long DEUXIEME_CLAP;
long temps;
int analog_val; // valeur analogique lue sur A2
static bool led_state = false; // état actuel de la LED
analog_val = analogRead(A2);
while (analog_val <= 10) // 1er clap
{
analog_val = analogRead(A2);
}
PREMIER_CLAP = millis() + 200; // délaie minimum
DEUXIEME_CLAP = PREMIER_CLAP + 2000; // delaie entre 1er clap et 2eme clap
temps = millis();
while (temps < PREMIER_CLAP) // attente du délaie minimum
{
temps = millis();
}
analog_val = analogRead(A2);
while (temps < DEUXIEME_CLAP && analog_val < 10) // attente du 2eme clap ou du reset
{
analog_val = analogRead(A2);
temps = millis();
}
if (temps >= DEUXIEME_CLAP)
{
delay(50);
reset();
}
else
{
if (led_state) // si la LED est allumée
{ //
led_state = false; // LED était allumée, maintenant éteinte
digitalWrite(2, LOW); //
} //
//
else // si la LED est éteinte
{ //
led_state = true; //
digitalWrite(2, HIGH); // LED était éteinte, maintenant allumée
} //
}
delay(200); // attendre que le bruit des claquements disparaisse
reset();
}<code>
Bonjour,
Aujourd'hui est un grand jour car j'ai enfin réussi a faire un programme qui permet d'allumer une LED en tapant 2 fois dans les mains.
Je vous envoie si après le programme.
Je tiens a remercier georges97 et Dal, sans qui je n'aurais sans doute pas réussi avant aujourd'hui.
Aujourd'hui est un grand jour car j'ai enfin réussi a faire un programme qui permet d'allumer une LED en tapant 2 fois dans les mains.
Je vous envoie si après le programme.
Je tiens a remercier georges97 et Dal, sans qui je n'aurais sans doute pas réussi avant aujourd'hui.
void setup()
{
pinMode(2, OUTPUT); // LED sur la branche pin 2
}
void(* reset) (void) = 0; //declare reset function @ address 0
void loop()
{
long PREMIER_CLAP;
long DEUXIEME_CLAP;
long temps;
int delai = 2000;
int analog_val; // valeur analogique lue sur A2
static bool led_state = false; // état actuel de la LED
analog_val = analogRead(A2);
while (analog_val <= 10) // 1er clap
{
analog_val = analogRead(A2);
}
PREMIER_CLAP = millis() + 200; // délaie minimum
DEUXIEME_CLAP = PREMIER_CLAP + delai; // delaie entre 1er clap et 2eme clap
temps = millis();
while (temps < PREMIER_CLAP) // attente du délaie minimum
{
temps = millis();
}
analog_val = analogRead(A2);
while (temps < DEUXIEME_CLAP && analog_val < 10) // attente du 2eme clap ou du reset
{
analog_val = analogRead(A2);
temps = millis();
}
if (temps >= DEUXIEME_CLAP)
{
reset();
}
else
{
if (led_state) // si la LED est allumée
{ //
led_state = false; // LED était allumée, maintenant éteinte
digitalWrite(2, LOW); //
} //
//
else // si la LED est éteinte
{ //
led_state = true; //
digitalWrite(2, HIGH); // LED était éteinte, maintenant allumée
} //
delay(200); // attendre que le bruit des claquements disparaisse
}
}
Salut frozice,
J'ai eu un peu de temps pour illustrer sous forme de code quelques lignes d'une machine à états qui implémenterait le comportement souhaité de façon non bloquante.
Pour simplifier le code, j'ai déporté dans une fonction
Enjoy !
J'ai eu un peu de temps pour illustrer sous forme de code quelques lignes d'une machine à états qui implémenterait le comportement souhaité de façon non bloquante.
Pour simplifier le code, j'ai déporté dans une fonction
do_switch_lamp()à implémenter le changement d'état de la lampe et son extinction / allumage alternés.
Enjoy !
enum etat_clap { AUCUN_CLAP, PREMIER_CLAP, DEUXIEME_CLAP }; enum etat_lampe { LAMPE_ETEINTE, LAMPE_ALLUMEE }; void do_switch_lamp(enum etat_lampe * lampe); void loop() { static enum etat_clap clap = AUCUN_CLAP; static enum etat_lampe lampe = LAMPE_ETEINTE; static unsigned long temps_clap_precedent = 0; unsigned long temps_actuel = millis(); int analog_val = analogRead(A2); /* si on a un clap */ if (analog_val > 10) { switch (clap) { case AUCUN_CLAP: /* Premier CLAP */ temps_clap_precedent = temps_actuel; clap = PREMIER_CLAP; break; case PREMIER_CLAP: if (temps_actuel < temps_clap_precedent + 2000) { /* Deuxième CLAP */ clap = DEUXIEME_CLAP; } else { /* Deuxième clap trop tardif, ce clap compte comme Premier CLAP */ clap = PREMIER_CLAP; temps_clap_precedent = temps_actuel; } break; default: /* TODO: Erreur, état imprévu */ break; } if (clap == DEUXIEME_CLAP) { do_switch_lamp(&lampe); clap = AUCUN_CLAP; } /* attendre que le bruit du clap disparaisse */ delay(200); } }
Merci de m'avoir répondu.
Sans vouloir vous vexer, certes j'ai pris ce programme sur internet, mais cela fait déjà une semaine que je travaille déçu affin de trouver le bon programme, hélas en vain.
J'avais déjà eu l'idée de cette boucle de comptage mais cela a conclue par un échec.
Je vais donc retravailler ceci encore et encore comme vous l'avez dit.
Merci encore, cordialement.
Par ailleurs, quand ça coince, n'essayez pas de réussir à faire tout le code en une fois. Décomposez, en l'occurrence, fîtes un programme plus court portant sur la boucle while, pour effectuer les deux "tours", sans inclure la partie capteur de son par exemple.
Vous l'intégrerez en suite au programme complet. En tous cas, c'est ainsi que je fais et cela m'a plutôt réussi.
L'échec dont vous parlez est soit une faute de syntaxe, soit un défaut en sortie de boucle qui fait que le reste du programme n'a pas intégré le résultat. En tous cas, c'est ainsi que je fais et cela m'a plutôt réussi.a boucle .
Ceci dit, je ne suis pas un cador en programmation, mais il y en a sur CCM et il vous viendront sans aucun doute en aide, dès qu'ils verront vos premières modifs.
A vous lire.
Bonne soirée