Tirage au sort sur 25 ou 30 led Possible?

Bonjour à tous

J'ai déjà réalisé de petits montages à base d'arduino Uno dont un qui se trouve sur ce forum.

Il faudrait que je réalise un système de tirage au sort ayant 25 à 30 possibilités de choix.

La sortie serait simplement une des 25 (ou +) led (5mm rouge) qui s'allumerait sur une fonction RANDOM. (Chaque led en face d'un nom)

Hélas pas assez de sortie pour 25 led, il faut multiplexer ?
Là je bloque un peu. Chaque sortie étant en ov ou 5v, va-t-il falloir encoder TOUTES les possibilités?

ex si je pars sur une matrice 5x5
(5 premières sorties) (5 sorties suivantes)
LED 1 10000 01111
Led 2 01000 01111
Led 3 00100 01111 etc?

Merci pour votre aide

WOW génial merci

Je vais sûrement câbler en 30 led (c'est pour ma classe, afin de répartir les tâches quotidiennes les élèves sans mon intervention)

Il me reste à comprendre le code :smiley:

La boucle FOR passe les 6 broches en INPUT correct? Ça évite de taper 12 lignes de code pour les 6 broches?

Ensuite, je peux générer un RANDOM entre 1 et 6 pour les valeurs [a] et
avec un IF (b==a) b = random (1,6) pour ne pas passer une broche en HIGH et en LOW en même temps
avec un bouton poussoir en entrée, je peux créer une boucle qui se termine à l'ouverture du bouton, non?
ça créera un joli effet de mélange d'allumage et d'extinction de led au hasard.
la dernière led restera allumée pour le tirage au sort en relâchant le bouton.
Pour les led je vais rester sur du 5mm soit bleues ou rouges/bleues flash ça tourne dans les 3v 20ma
(Je débute soyez indulgents)

Un random n'est pas réellement aléatoire?

Je vais commencer par bricoler ma série de led.
Il faut que je trouve comment les disposer avec la liste en face...
J'ai retrouvé une vingtaine de led 5mm vertes et des boutons de borne d'arcade. Il me reste un arduino Uno.
Il me manque une alimentation, je vais fouiller !

non, la fonction random renvoi un nombre pseudo-aléatoire, en fait un nombre pris dans une séquence qui se répète, à chaque allumage de l'arduino la séquence sera la même

sinon il faut initialiser la fonction random avec un nombre différent à chaque fois, comme expliqué dans la doc de random():

https://www.arduino.cc/en/Reference/Random

Bonjour.
J'ai un peu de temps libre et je travaille sur le code grâce à l'aide apportée sur ce post (encore merci à eux)
J'ai évité les boucles car j'ai des messages d'erreurs et j'ai pas envie de me compliquer la vie ;D

void setup() {
  // put your setup code here, to run once:
const byte pinsLeds[] = {2, 3, 4, 5, 6, 7};
Serial.begin(9600);
}
void loop(){
    pinMode(1, INPUT);
    digitalWrite(1, LOW);
    pinMode(1, INPUT);
    digitalWrite(2, LOW);
    pinMode(2, INPUT);
    digitalWrite(3, LOW);
    pinMode(3, INPUT);
    digitalWrite(4, LOW);
    pinMode(4, INPUT);
    digitalWrite(4, LOW);
    pinMode(5, INPUT);
    digitalWrite(5, LOW);
    pinMode(6, INPUT);
    digitalWrite(6, LOW);   

 int nbAlea;
  
  randomSeed(analogRead(0));
  nbAlea=random(1, 31); 
  Serial.println(nbAlea);
  delay(1000);


if (nbAlea == 1)
{
  pinMode(1, OUTPUT);
  digitalWrite(1, HIGH);
  pinMode(6, OUTPUT);
  digitalWrite(6, LOW);
  }
  if (nbAlea == 2)
{
  pinMode(5, OUTPUT);
  digitalWrite(5, HIGH);
  pinMode(1, OUTPUT);
  digitalWrite(1, LOW);
  }
  if (nbAlea == 3)
{
  pinMode(1, OUTPUT);
  digitalWrite(1, HIGH);
  pinMode(5, OUTPUT);
  digitalWrite(5, LOW);
  }
}
  // etc

Qu'en pensez-vous? Il me manque encore la fonction du bouton

j'ai branché les led et ajouté un delay... test

:frowning:
J'ai un bug...

Première led branchée en 1 (+) et 5 (-)
Quand le random génère ce chiffre, elle s'allume et reste allumée le temps du DELAY
MAIS si je branche en cette led en inverse 1 (-) et 5 (+) elle flashe juste 1/10e de seconde et s'éteint
Même en changeant la séquence ...
Par contre avec les bornes 2-6 ou 6-2 ça marche???

pepe:
La broche 1 produit le signal TX de l'interface série destiné à l'interface USB.

On ne doit pas l'utiliser, sauf à prendre certaines précautions.

Oki je déplace alors des sorties 2 à 7
MERCI !!!!!!!!!!!!!
Ca fonctionne nickel

void setup() {
  // put your setup code here, to run once:
const byte pinsLeds[] = {2, 3, 4, 5, 6, 7};
Serial.begin(9600);
}
void loop(){
    pinMode(2, INPUT);
    digitalWrite(2, LOW);
    pinMode(3, INPUT);
    digitalWrite(3, LOW);
    pinMode(4, INPUT);
    digitalWrite(4, LOW);
    pinMode(5, INPUT);
    digitalWrite(5, LOW);
    pinMode(6, INPUT);
    digitalWrite(6, LOW);
    pinMode(7, INPUT);
    digitalWrite(7, LOW);   

 int nbAlea;
  
  randomSeed(analogRead(0));
  nbAlea=random(1, 5); 
  Serial.println(nbAlea);
 if (nbAlea == 1)  // j'ai mis les adressages led au pif pour 4 LEDS
{
  pinMode(2, OUTPUT);
  digitalWrite(2, HIGH);
  pinMode(6, OUTPUT);
  digitalWrite(6, LOW);
  }
if (nbAlea == 2)
{
  pinMode(5, OUTPUT);
  digitalWrite(5, HIGH);
  pinMode(3, OUTPUT);
  digitalWrite(3, LOW);
  }
if (nbAlea == 3)
{
  pinMode(3, OUTPUT);
  digitalWrite(3, HIGH);
  pinMode(5, OUTPUT);
  digitalWrite(5, LOW);
  }
if (nbAlea == 4)
{
  pinMode(6, OUTPUT);
  digitalWrite(6, HIGH);
  pinMode(2, OUTPUT);
  digitalWrite(2, LOW);
  }
delay(100);

// etc
  }

:smiley:
Comme j'hésitais sur l'utilité de cette ligne, je l'ai laissée !
Je viens de commander 100leds rgb flash 5mm et un petit buzzer
Il me reste à câbler un bouton et trouver une commande pour l'arrêt.

Question de débutant : un bouton doit-il toujours être câblé en 3 fils avec une résistance ou un simple +vcc sur l'entrée est suffisant?

EDIT trouvé : INPUT_PULLUP

Bonsoir

En attendant mes leds, j'ai tenté de compléter le code pour que la led choisie reste allumée jusqu'au prochain contact du bouton poussoir...
Je dois encore faire une boucle IF ? ou un WHILE ?

(...)

Il se fait tard et le mal de crâne me guette. Je vais attendre mes leds avant de modifier le code. Je tourne en rond. Allez bonne nuit !

Les leds sont là ! RGB fast flash. Jolies !
Je fonce terminer mes trous.

Pour le code, l'allumage se fait bien mais je bloque pour le bouton

Je pense insérer une commande WAIT activée par ce bouton. Après cette temporisation, l'allumage aléatoire reprendra. Il faudra juste couper l'alimentation...
Un peu barbare mais j'ai pas mieux
:smiley:

tu veux faire quoi exactement avec le bouton ?

En me relisant, je trouve aussi ne pas avoir été clair :grin:

J'alimente l'arduino, les led clignotent aléatoirement pour donner un effet de mélange, le random fonctionne et allume 4-5 led par seconde en boucle sans arrêt. Cela permet de voir que, à un moment ou à un autre, chaque led peut s'allumer.

Je voudrais qu'en poussant sur ce bouton, le RANDOM se termine et laisse la dernière led allumée.

Je pense que je vais rester sur un IF (bouton enfoncé) WAIT (10-15 sec) comme ça la boucle repart après avoir affiché le tirage au sort.

pinMode(10,INPUT)
if (digitalread 10 == High) wait 10000

ce serait bon?

peux-tu poster ton code actuel complet ?

Voici mon code
Soyez indulgents sur l'organisation, je ne maîtrise pas encore toutes les ficelles...

void setup() {
  // put your setup code here, to run once:
const byte pinsLeds[] = {2, 3, 4, 5, 6, 7};
Serial.begin(9600);
  pinMode(10,INPUT_PULLUP); // pour l'interrupteur
  
}

void loop(){
    pinMode(2, INPUT);
    digitalWrite(2, LOW);
    pinMode(3, INPUT);
    digitalWrite(3, LOW);
    pinMode(4, INPUT);
    digitalWrite(4, LOW);
    pinMode(5, INPUT);
    digitalWrite(5, LOW);
    pinMode(6, INPUT);
    digitalWrite(6, LOW);
    pinMode(7, INPUT);
    digitalWrite(7, LOW);  
     
  

;int nbAlea;
  randomSeed(analogRead(0));
  nbAlea=random(1, 5); 
  Serial.println(nbAlea);
 if (nbAlea == 1)  // j'ai mis les adressages led au pif pour 4 LEDS
{
  pinMode(2, OUTPUT);
  digitalWrite(2, HIGH);
  pinMode(6, OUTPUT);
  digitalWrite(6, LOW);
  }
if (nbAlea == 2)
{
  pinMode(5, OUTPUT);
  digitalWrite(5, HIGH);
  pinMode(3, OUTPUT);
  digitalWrite(3, LOW);
  }
if (nbAlea == 3)
{
  pinMode(3, OUTPUT);
  digitalWrite(3, HIGH);
  pinMode(5, OUTPUT);
  digitalWrite(5, LOW);
  }
if (nbAlea == 4)
{
  pinMode(6, OUTPUT);
  digitalWrite(6, HIGH);
  pinMode(2, OUTPUT);
  digitalWrite(2, LOW);
  }
  // etc etc 

delay(100); // juste assez de temps pour que l'allumage soit visible

  int etat = digitalRead(10); // a sera HIGH ou LOW selon bouton
  
  if(etat == LOW)
{
  delay(10000);  // une pause avec dernière LED allumée
}
  }

EDIT j'ai des résistances 120ohms ça semble nickel : la led est lumineuse et cycle sur ses couleurs

essayes avec ceci, normalement le fonctionnement devrait être : allumage, les leds clignotent, appui = ça fige, nouvel appui = ça repart

n'ayant pas ton matériel je ne l'ai pas testé, mais à priori ça doit aller

void setup() 
{
  // put your setup code here, to run once:
  const byte pinsLeds[] = {2, 3, 4, 5, 6, 7};
  Serial.begin(9600);
  pinMode(10, INPUT_PULLUP); // pour l'interrupteur

}

void loop() 
{
  pinMode(2, INPUT);
  digitalWrite(2, LOW);
  pinMode(3, INPUT);
  digitalWrite(3, LOW);
  pinMode(4, INPUT);
  digitalWrite(4, LOW);
  pinMode(5, INPUT);
  digitalWrite(5, LOW);
  pinMode(6, INPUT);
  digitalWrite(6, LOW);
  pinMode(7, INPUT);
  digitalWrite(7, LOW);



  int nbAlea;
  randomSeed(analogRead(0));
  nbAlea = random(1, 5);
  Serial.println(nbAlea);
  if (nbAlea == 1)  // j'ai mis les adressages led au pif pour 4 LEDS
  {
    pinMode(2, OUTPUT);
    digitalWrite(2, HIGH);
    pinMode(6, OUTPUT);
    digitalWrite(6, LOW);
  }
  if (nbAlea == 2)
  {
    pinMode(5, OUTPUT);
    digitalWrite(5, HIGH);
    pinMode(3, OUTPUT);
    digitalWrite(3, LOW);
  }
  if (nbAlea == 3)
  {
    pinMode(3, OUTPUT);
    digitalWrite(3, HIGH);
    pinMode(5, OUTPUT);
    digitalWrite(5, LOW);
  }
  if (nbAlea == 4)
  {
    pinMode(6, OUTPUT);
    digitalWrite(6, HIGH);
    pinMode(2, OUTPUT);
    digitalWrite(2, LOW);
  }
  // etc etc

  delay(100); // juste assez de temps pour que l'allumage soit visible

  if(digitalRead(10) == LOW); // LOW si bouton appuyé
  {
    delay(10); //un délai pour éviter de prendre en compte les rebonds du contact
    
    while(digitalRead(10) == LOW)//on attends tant que le bouton n'a pas été relaché
    { }//on ne ne fait rien, on attends

    //ici le bouton a été relaché
    
    while(digitalRead(10) == HIGH)//maintenant le bouton à été relaché, on va attendre tant qu'il reste relaché
    { }//on ne ne fait rien, on attends

    //ici il a été à nouveau appuyé
    
    while(digitalRead(10) == LOW)//on attends tant que le bouton n'a pas été relaché
    { }//on ne ne fait rien, on attends
    
    delay(10); //un délai pour éviter de prendre en compte les rebonds du contact lors de l'appel suivant de loop()
  }
    

}

Merci mais ça va pas...

J'allume et il me sort 1 allumage aléatoire et s'arrête.
A chaque appui et relâchement du bouton il me ressort 1 seul allumage, il ne boucle pas, il attend un appui/relâchement pour changer d'allumage.
Il ne change qu'au relâchement -> HIGH

J'ai même testé avec une résistance de pull-up , même résultat 1 appui/relâchement = 1 changement

Étrange...

Dans la boucle WHILE il faudrait pas relire la valeur de digitalRead(10) ?

Bonjour,

Tu as un défini tableau de leds pinsLeds[]. Il faut utiliser ce tableau.
Ca donne un programme comme ça.

const byte pinsLeds[] = {2, 3, 4, 5, 6, 7};
const int NBLEDS=sizeof pinsLeds;
const byte pinButton=10;

void setup()
{
 Serial.begin(9600);
 // put your setup code here, to run once:
 pinMode(pinButton, INPUT_PULLUP); // pour l'interrupteur
}

void loop()
{
 static int nled=0;
 static bool etatButtonPrec=false;
 
 bool etatButton=digitalRead(pinButton)==LOW;
 
 if (etatButton)
 {
   digitalWrite(pinsLeds[nled],LOW);
   nled++;
   if (nled>=NBLEDS)
     nled=0;
   digitalWrite(pinsLeds[nled],HIGH);
   delay(100);
 }
 
 if (etatButton!=etatButtonPrec && !etatButton)
 {
   // on vient de relacher le bouton
   int nrand=(micros()/4)%NBLEDS+1; // on utilise le nombre de micros au moment ou on relache comme nombre aléatoire
   for (int i=0; i<nrand; i++)
   {
     digitalWrite(pinsLeds[nled],LOW);
     nled++;
     if (nled>=NBLEDS)
       nled=0;
     digitalWrite(pinsLeds[nled],HIGH);
     delay(200);
   }
 }
 etatButtonPrec=etatButton;
}

:o Impressionnant ! Kamill, c'est du code de pro là !
Mais j'ai rien compris ! (int nrand=(micros()/4)%NBLE... etc) :fearful: :fearful:
Merci pour ta participation. Mais, un peu d'indulgence, je débute :-[ Je suis LOIN de ton niveau.
Je l'ai chargé pour tester et rien ne démarre, aucune trace sur le moniteur série. :sob:

Mon code fonctionnait bien jusque là.
Malfoutu, mal organisé, avec plein de trucs inutiles ou trop lourds (je sais) mais c'était ma petite création.
Il ne me manque que ce :-X de bouton pour le finaliser. Si j'y arrive pas ce sera avec le DELAY activé par bouton et hop bon pour le service.

L'effet bouton arrêt / redémarrage m'aurait bien plu pourtant.

Edit solution à la Mac Gyver : un bouton avec un delay énoooorme et un second bouton RESET. Je sais je suis un barbare... :grinning:

Leeleen:
Merci mais ça va pas...

J'allume et il me sort 1 allumage aléatoire et s'arrête.
A chaque appui et relâchement du bouton il me ressort 1 seul allumage, il ne boucle pas, il attend un appui/relâchement pour changer d'allumage.
Il ne change qu'au relâchement -> HIGH

J'ai même testé avec une résistance de pull-up , même résultat 1 appui/relâchement = 1 changement

Étrange...

Dans la boucle WHILE il faudrait pas relire la valeur de digitalRead(10) ?

justement, l'intéret de while c'est que ça relis constamment l'entrée : il lit la valeur et tant que la condition est vraie, il execute ce qui est entre les { }, soit ici rien, mais comme ça on a une attente tant que la condition est vraie.

j'ai considéré que ton bouton mettait à la masse la pin d'entrée lorsqu'il est appuyé. est-ce vraiment le cas ?

si au contraire il est entre la pin et le 5V, alors il faut inverser les HIGH et LOW dans le code.

sinon essayes avec le code suivant (juste quelques modifs dans la partie du bouton, pour rajouter des délais et éviter de sauter d'une condition à l'autre avec les rebonds du contact. Si ça ne marche toujours pas tu peux essayer en augmentant les délais entre les étapes, passer de 10 à 50 ou 100) :

  if(digitalRead(10) == LOW); // LOW si bouton appuyé
  {
    delay(10); //un délai pour éviter de prendre en compte les rebonds du contact
    
    while(digitalRead(10) == LOW)//on attends tant que le bouton n'a pas été relaché
    { }//on ne ne fait rien, on attends

    delay(10); //un délai pour éviter de prendre en compte les rebonds du contact

    //ici le bouton a été relaché
    
    while(digitalRead(10) == HIGH)//maintenant le bouton à été relaché, on va attendre tant qu'il reste relaché
    { }//on ne ne fait rien, on attends

    //ici il a été à nouveau appuyé
    
    delay(10); //un délai pour éviter de prendre en compte les rebonds du contact
    
    while(digitalRead(10) == LOW)//on attends tant que le bouton n'a pas été relaché
    { }//on ne ne fait rien, on attends
    
    delay(100); //un délai pour éviter de prendre en compte les rebonds du contact lors de l'appel suivant de loop()
  }

et sinon la version simplifiée, c'est juste appui sur le bouton = fige l'affichage, relacher = ça repart

dans ce cas tu utilises juste

    while(digitalRead(10) == LOW)//si bouton activé on rentre dans la boucle
    { delay(10); }//on ne ne fait rien, on attends

Avec possibilité d'allonger le delay si tu veux que ça fasse une pause même en lâchant le bouton

toujours en partant du principe que bouton activé == LOW bien entendu si le bouton est entre la pin et le 5V il faut utiliser HIGH

:grin: Merciiiiiiiiiiiiiiiiii
La version simplifiée est nickel !
J'y avais pas pensé

J'appuie et ça mélange, je lâche et hop ça s'arrête. Je peux ainsi conserver le dernier résultat indéfiniment !

Youpeeeeeeeeeeeeeeeeeeeeeee

Je n'ai plus qu'à fixer tout ça !

MERCI !!!!!!!!!!! Et longue vie à ce forum et à ses passionnés !

La vidéo suivra quand tout sera fini