faire clignoter une led quand on lui demande et pendant un temps donné

bonjour a tous,

j'essaie de réaliser un jeu de buzzer avec des leds rvb.
pour l'instant j'ai réussi tant bien que mal à :

quand j'appuie sur le bouton start : les leds passent au bleu et la led flag est allumée
quand j'appuie sur le bouton reset : les leds sont blanches et led flag est éteinte
quand j'appuie sur un des bouton joueurs : la led du joueur qui a appuyé passe au vert, les trois autres au rouge, la led flag s'éteint (donc on ne peut pas buzzer tant que je n'ai pas appuyé sur le bouton start.)

je cherche désormais a vouloir faire clignoter le led verte du joueur qui vient de buzzer pendant 2 secondes ...
mais je bloque grave
j'ai essayé de retourner le problème dans tout les sens avec la fonction millis, essayé de créer un compteur " à part pour remplacer la fonction millis
du genre :

for ( long Temps=0; Temps<3000; Temps++);
if(currentTemps - previousTemps >= interval) {
    
    previousTemps = currentTemps;   

    if (ledState == LOW)
      ledState = HIGH;
    else
      ledState = LOW;


    digitalWrite(ledPin, ledState);

tout ca a différents endroit de mon code mais rien n'y fait...
(j'écarte la fonction delay, car ceci n'est qu'une premiere étape, et je souhaiterai déclencher des sons par la suite. si j'utilise la fonction delay, tout va se mettre en pause si j'ai bien compris)

voici mon code :

const char boutonstart = 48;     // declaration des variables boutons
const char boutonreset = 49;  
const char bouton1 = 50;
const char bouton2 = 51;
const char bouton3 = 52;
const char bouton4 = 53;

const char ledflag = 13;         // declaration de la led interne en guise de flag


unsigned char etatboutonstart;          // declaration des etats des boutons (si necessaire)
unsigned char etatboutonreset;
unsigned char etatbouton1;
unsigned char etatbouton2;
unsigned char etatbouton3;
unsigned char etatbouton4;

unsigned char etatledflag;                //declaration de l'etat de la led flag

unsigned char etatpinsled_V[] = {
  3, 6, 9, 12 };






int pinsled_R[] = {             // declaration des bornes de led rouge
  1, 4, 7, 10 };      
int pinCount_R = 4;     

int pinsled_B[] = {             // declaration des bornes de led bleu
  2, 5, 8, 11 };      
int pinCount_B = 4;           
         
int pinsled_V[] = {             // declaration des bornes de led verte
  3, 6, 9, 12 };      
int pinCount_V = 4;
       


int ledpins[] = {               // declaration des bornes de toutes les leds
  1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 };       
int allpinCount = 12;


boolean ledstate[6][12] = {                  // les diffrentes configs que peuvent avoir les leds
  {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
  {0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0 },
  {0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0 },
  {1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0 },
  {1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0 },
  {1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1 }
};





void setup() {
  
  for (int thisPin = 0; thisPin < allpinCount; thisPin++)    // declaration des pins led en tant que sortie
  {
    pinMode(ledpins[thisPin], OUTPUT);      
  }
  
pinMode(ledflag, OUTPUT);                //declaration de la pin 13 en tant que sortie


pinMode(bouton1, INPUT_PULLUP);         // declaration des pins boutons en tant qu'entrees avec pullup interne
pinMode(bouton2, INPUT_PULLUP);
pinMode(bouton3, INPUT_PULLUP);
pinMode(bouton4, INPUT_PULLUP);
pinMode(boutonstart, INPUT_PULLUP);
pinMode(boutonreset, INPUT_PULLUP);




  for (int i = 0; i < allpinCount; i++)                   // les leds demarrent en config 1 et flag eteint  
  {
    digitalWrite (ledpins[i], ledstate[0][i]);
    digitalWrite (ledflag, 0);
    }
    

}



void loop() {

etatbouton1 = digitalRead(bouton1);
etatbouton2 = digitalRead(bouton2);
etatbouton3 = digitalRead(bouton3);
etatbouton4 = digitalRead(bouton4);
etatboutonstart = digitalRead(boutonstart);
etatboutonreset = digitalRead(boutonreset);
etatledflag = digitalRead(ledflag);


for( int j = 0; j< pinCount_V; j++)
etatpinsled_V[j] = digitalRead(pinsled_V[j]);







if(etatboutonreset == LOW)                                  // si on appuie sur bouton reset, on est en config 1 et flag eteint
  {
    for (int i = 0; i < allpinCount; i++)
    digitalWrite (ledpins[i], ledstate[0][i]);
    digitalWrite (ledflag, 0);
  }

if(etatboutonstart == LOW)                              //si on appuie sur bouton start ,config 2 et flag s'allume
  {
    for (int i = 0; i < allpinCount; i++)
    digitalWrite (ledpins[i], ledstate[1][i]);
    digitalWrite(ledflag, 1 );   
  }




if(etatbouton1 == LOW  && etatledflag == 1)    //si on appuie sur bouton 1 ,config 3 et flag s'eteint     
  { 
    for (int i = 0; i < allpinCount; i++)
    digitalWrite (ledpins[i], ledstate[2][i]);
    digitalWrite(ledflag, 0);
  }
 
if(etatbouton2 == LOW && etatledflag == 1)                //si on appuie sur bouton 2 ,config 4 et flag s'eteint
  {
    for (int i = 0; i < allpinCount; i++)
    digitalWrite (ledpins[i], ledstate[3][i]);
    digitalWrite(ledflag, 0) ;
  }
  
if(etatbouton3 == LOW && etatledflag == 1 )                //si on appuie sur bouton 3 ,config 5 et flag s'eteint
  {
    for (int i = 0; i < allpinCount; i++)
    digitalWrite (ledpins[i], ledstate[4][i]);
    digitalWrite(ledflag, 0) ;
  }
  
if(etatbouton4 == LOW && etatledflag == 1)                //si on appuie sur bouton 4 ,config 6 et flag s'eteint
  {
    for (int i = 0; i < allpinCount; i++)
    digitalWrite (ledpins[i], ledstate[5][i]);
    digitalWrite(ledflag, 0) ;
  }
}

comment et ou attaqueriez vous le problème????

merci
Francois

Salut,

Si j'ai bien pigé :

unsigned long start=millis();

digitalWrite(ledJoueur,HIGH);

while(digitalread(start)==HIGH && millis()<start+2000) {

digitalWrite(ledJoueur,((millis()-start)/200) & 1);

}

digitalWrite(ledJoueur,LOW);

un peu d'explication :

millis() - start donne le temps écoulé en ms. Je divise par 200 pour clignoter toute les 200 ms. Ca donne donc

à 200 ms écoulé => 1
à 400 ms => 2
à 600 ms => 3
à 800 ms => 4
....

soit en binaire 001, 010, 011, 100 ... Le bit de poids faible (celui le plus à droite) alterne alors entre 0 et 1. J'utilise alors un masque pour récupérer ce bit :

001 & 001 = 1
010 & 001 = 0
011 & 001 = 1
100 & 001 = 0

...

Je boucle le tout temps qu'on appuie par sur le bouton start ou que deux secondes se sont écoulées

c'est bien ca en effet...

un grand merci, j'aurai jamais trouvé tout seul, ou alors pas de cette manière la...

je pense avoir compris le principe de ton code.

toujours est-il que ca fonctionne comme je le souhaite.

cependant

Je boucle le tout temps qu'on appuie par sur le bouton start ou que deux secondes se sont écoulées

cceci ne fonctionne pas... si un joueur buzze et que j'appuie sur le bouton start dans le délai de clignotement que j'ai fixé... le bouton start ne reprend pas la main .
en revanche au bout du délai de clignotement, la oui, le bouton start peut reprendre la main

ce n'est pas bien grave. pendant le clignotement je n'ai pas besoin de cette fonction.

voici comment je l'ai intégré :

if(etatbouton1 == LOW  && etatledflag == 1) //si on appuie sur bouton 1 ,config 3 et flag s'eteint     
 
   { 
    for (int i = 0; i < allpinCount; i++)
    digitalWrite (ledpins[i], ledstate[2][i]);
    digitalWrite(ledflag, 0);
    Serial.println("etatbouton1");              // le serialprint, c'est parce que en meme temps j'essaie  
    Serial.println(etatbouton1);                // d'apprendre a m'en servir
    delay(1);
    
    while(etatboutonstart==HIGH && millis()<start+800) 
    {

digitalWrite(pinsled_V[0],((millis()-start)/50) & 1);
}

digitalWrite(pinsled_V[0],HIGH);

Je fais donc clignoter pendant 0,8 secondes, et le changement d'état se fait tout les 50ms. je met HIgh a la derniers ligne car je veux que ma led verte reste allumée une fois le clignotement terminé...

le

unsigned long start=millis()

:
je l'ai mis au début de ma fonction loop() car en variable globale ca ne fonctionne pas car ca voudrait dire que la fonction millis() débute dès le lancement du programme.... c'est bien ca?????

ce n'est pas pour autant que j'ai compris quand démarre cette fonction, ou quand elle repart a 0 dans ma boucle....

millis()<start+2000

:
ceci est un grand mystère pour moi dans l'état des choses...
dans ma logique :
étant donné qu'on a dit plus haut que start = millis()

pour moi "millis()" sera toujours plus petit que" start+2000"
et vu que cette ligne est prise dans une boucle WHILE, je comprends pas comment on arrive a en sortir...

re merci en tout cas!

Outch pas mal de questions ... Pour la dernière :

start = millis() avant la boucle, c'est le point de départ. millis() sera donc ensuite forcement supérieur à start.

donc start+2000 c'est la valeur qu'aura millis() deux secondes plus tard

D'une manière générale je crois que tu n'as pas bien saisi ni millis() ni les variables en générale.

Si tu mets unsigned long start=millis() en en-tête normal que ça ne fonctionne jamais.

Si tu utilises while(etatboutonstart==HIGH && millis()<start+800) comme ça sans jamais mettre à jour etatboutonstart c'est normal que le bouton ne marche pas ... C'est bien pour ça que j'utilisais digitalRead() dans la condition de boucle sinon comment veux que etatboutonstart change quand on appuie sur le bouton ?

D'une manière générale je crois que tu n'as pas bien saisi ni millis() ni les variables en générale.

c'est vrai ca se voit tant que ca???? mince....
j'y travaille, j'y travaille.

Si tu mets unsigned long start=millis() en en-tête normal que ça ne fonctionne jamais.

m'en suis rendu compte... mais ca rejoins ta premiere remarque ci dessus.
j'y travaille toujours...

Si tu utilises while(etatboutonstart==HIGH && millis()<start+800) comme ça sans jamais mettre à jour etatboutonstart c'est normal que le bouton ne marche pas ... C'est bien pour ça que j'utilisais digitalRead() dans la condition de boucle sinon comment veux que etatboutonstart change quand on appuie sur le bouton ?

alors la pour ma défense :smiling_imp: :
me suis dit, en voyant ton code, et vu que j'avais deja déclaré plus haut
etatboutonstart = digitalRead(boutonstart) :

"ben pourquoi écrire digitalRead(boutonstart) alors que je l'ai "renommé" plus haut????"

effectivement si je remplace while(etatboutonstart==HIGH && millis()<start+800)
par while(digitalRead(boutonstart)==HIGH && millis()<start+800)
cela fonctionne

encore une histoire de non maitrise de déclaration de variables je présume... :smiling_imp:

pas taper, pas taper....
ca ne fait qu'une semaine, et en partant de 0... :wink:

la suite au prochain épisode.
mais je pense qu'avec ce que tu m'a fourni la, je vais pouvoir me débrouiller... j'espère.

cdlt,

Pour approfondir ce sujet précis : [Tutorial] Les interruptions temporelles avec Arduino | B@ttoMicro - Microcontrôleurs et compagnie !

merci