Cuve de Led 3x3x3

Bonjour,

J'ai réalisé un cube de led 3x3x3, tout fonctionne parfaitement, mais je me pose des questions sur la meilleur façon de coder les animations.

Je souhaite comme effet, allumer toute les led et les éteindre aléatoirement une par une.

Pour allumer tout le cube

void toutAllumer(){
  for (int i=0; i<9; i++){
    digitalWrite(colonne[i], HIGH);
  }
  for (int i=0; i<3; i++){
    digitalWrite(etages[i], HIGH);
  }
}

Mais évidemment impossible après d'en éteindre seulement une.
J'utilise donc la persistance rétinien. Je les allumes individuellement.

for (int i=0; i<200; i++){
  allumerLed1();
  delay(1);
  allumerLed2();
  delay(1);
...
  allumerLed27();
  delay(1);
}

Mais je vois pas comment les éteindre de manière aléatoire, auriez vous des idées ?
De plus ca me fait un code super long, n'y aurait il pas un code plus malin.

Merci

vous avez 27 leds. vous voulez bâtir un code qui va toucher chaque LED une fois dans un ordre aléatoire.

une idée simple est de tirer au hasard un nombre entre 0 et 26 et de regarder s'il est déjà sorti. si oui, vous allez chercher le suivant qui n'est pas sorti, sinon vous le retenez.

Pour cela il faut mémoriser ce qui est déjà sorti, vous pouvez soit avoir un tableau de 27 éléments qui mémorise si oui (1) ou non (0) l'élément à la position est déjà sorti ou plus optimisé utiliser chacun des bits d'un unsigned long (32 bits donc 32 LEDs max) pour mémoriser l'info. par exemple si le bit n est à 0 alors la LED n est déjà sortie, s'il est à 1 alors elle n'a pas encore été touchée. --> 4 octets au lieu de 27)

Voilà à quoi ça pourrait ressembler

#define NBLEDS 27

void setup() {
  Serial.begin(115200);
  Serial.println();
  randomSeed(analogRead(0)); // génération d'un peu d'aléatoire

  // ---------------------------------
  // VERSION avec un tableau. prend de la mémoire
  // ---------------------------------
  uint8_t leds[NBLEDS];

  memset(leds, 1, NBLEDS); // on met des 1 dans chaque case du tableau (fonctionne parce que ce sont des octets), aucune LED pour le moment choisie
  for (int i = 0; i < NBLEDS; i++) {
    byte randomLedIndex = random(0, NBLEDS);
    if (leds[randomLedIndex]) {
      // on ne l'a pas encore touchée, on la prend
      leds[randomLedIndex] = 0;
      Serial.print(randomLedIndex); Serial.print(" ");
    } else {
      // elle est déjà éteinte, on va à celle suivante non éteinte
      do {
        if (++randomLedIndex >= NBLEDS) randomLedIndex = 0;
      } while (!leds[randomLedIndex]);
      leds[randomLedIndex] = 0;
      Serial.print(randomLedIndex); Serial.print(" ");
    }
  }
  Serial.println();

  // ---------------------------------
  // VERSION avec les bits - fonctionne si moins de 32 LEDs
  // ---------------------------------
  uint32_t ledBits; // 32 bits. chaque bit représente une LED

  randomSeed(analogRead(0)); // génération d'un peu d'aléatoire
  ledBits = 0xFFFFFFFF; // 1 partout, aucune LED pour le moment choisie

  for (int i = 0; i < NBLEDS; i++) {
    byte randomLedIndex = random(0, NBLEDS);
    if (bitRead(ledBits, randomLedIndex)) {
      // on ne l'a pas encore touchée, on la prend
      bitClear(ledBits, randomLedIndex);
      Serial.print(randomLedIndex); Serial.print(" ");
    } else {
      // elle est déjà éteinte, on va à celle suivante non éteinte
      do {
        if (++randomLedIndex >= NBLEDS) randomLedIndex = 0;
      } while (!bitRead(ledBits, randomLedIndex));
      bitClear(ledBits, randomLedIndex);
      Serial.print(randomLedIndex); Serial.print(" ");
    }
  }
  Serial.println();
}

void loop() {}

il y a les 2 versions, une avec un tableau et une avec les bits. si vous exécutez cela plusieurs fois vous verrez qu'il vous sort les nombres entre 0 et 26 à chaque fois dans un ordre différent

ça aide?

sinon c'est quoi votre code de allumerLed1();

Salut,

Merci pour ta réponse, mais c'est pas exactement ça !
Pour le fonctionnement du cube de led, je commande les 9 colonnes et les 3 étages.

Pour allumer une led, je met en HIGH une colonnes ( donc trois led ) et je met un étage au GND ( voir image )
Si on regarde qu'une face (donc 9 led), si je veux allumer la led a gauche du premier etage et la led du milieu du deuxieme étage.
-Si je met en HIGH la colonne de gauche et milieu et au GND le premier et deuxième étage, alors j'allume quatre led,..., pas le deux que je voulais.

Je sais pas si je suis claire :wink:

Donc pour faire ca, j'utilise la persistance rétinienne :

for (int i=0; i<200; i++){
digitalWrite(colonne2, LOW);
digitalWrite(etage2, LOW);
digitalWrite(colonne1, HIGH);
digitalWrite(etage1, HIGH);
delay(5);
digitalWrite(colonne1, LOW);
digitalWrite(etage1, LOW);
digitalWrite(colonne2, HIGH);
digitalWrite(etage2, HIGH);
delay(5);
}

Bonsoir,

Sujet très intéressant. Pourrais-je avoir des informations sur le fonctionnement de la partie pratique ?
Comment marchent les transistors ? Comment les monter ? Quels transistors utiliser ?

Comment doit fonctionner le code ?

Je te partage ce lien

J ai réussi assez facilement.
N hésité pas si tu as des questions

pas clair - je ne vois pas bien exactement où sont les connexions vers le grounds

vous pouvez mettre une vue schématique fritzing - où on peut voir vraiment qui est connecté où?

EDIT = plus clair avec le pdf

Il faut modeliser le cube a led en matrice, c'est a dire avec des tableaux a deux dimensions pour chaque étage.

Pour le gnd des étages, il est relié à un transistor qui sert de Switch en le saturant grâce à une sortie digital.

Je essayé de modéliser le cube en matrice, mais le problème est que agir sur une colonne impacte les trois étages.

J aurais pas réussi à le dire aussi bien :slight_smile:
Mais question est : je souhaite faire comme effet, allumer toute les led et les éteindre une par une aléatoirement.

J utilisé la persistance rétinienne, j allume les led une par une très très vite et petit à petit j en allume moins

For ( int i=0; i<value; i++){
EteindreLed27();
AllumerLed1();
Delay(2);
EteindreLed1();
AllumerLed2();
Delay(2);
...
EteindreLed26();
AllumerLed27();
}

Puis pour les éteindres je génère un nombre aléatoire et des conditions pour exclure l allumage des led une par une.

Je trouve ce code super lourd, si vous avez des idées pour le simplifier je suis preneur.

Merci

Pour allumer les led pas de probleme :

int colonnes[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
int etages[] = {12, 11, 10};

void setup(){
  for (int i=0; i<9; i++){
    pinMode(colonnes[i], OUTPUT); 
  }
  for (int i=0; i<3; i++){
    pinMode(etages[i], OUTPUT); 
  }
}

void loop(){
  for (int i=0; i<3; i++){
    digitalWrite(etages[i], HIGH);
  }
  for (int i=0; i<8; i++){
    digitalWrite(colonnes[i], HIGH);
  }
}

Si je comprend bien ce que tu me propose, c'est plutôt d'utiliser cette forme :

int colonnes[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
int etages[] = {12, 11, 10};

boolean choixLed[3][9]={
  1,1,1,1,1,1,1,1,1,
  1,1,1,1,1,1,1,1,1,
  1,1,1,1,1,1,1,1,1};

void setup(){
  for (int i=0; i<9; i++){
    pinMode(colonnes[i], OUTPUT); 
  }
  for (int i=0; i<3; i++){
    pinMode(etages[i], OUTPUT); 
  }
}
void loop(){

  for (int i=0; i<3; i++){
    digitalWrite(etages[i], HIGH);

    for (int a=0; a<9; a++){
      boolean etat=choixLed[i][a];
      digitalWrite(colonnes[a], etat);
      delay(2);
      digitalWrite(colonnes[a], LOW);
      delay(2);
    }
    digitalWrite(etages[i], LOW);
  }
}

Il me reste plus a implémenter une variable aléatoire qui changera l’état du choixLed[3][9].

Il me reste plus a implémenter une variable aléatoire qui changera l'état du choixLed[3][9].

==> cf mon code au début qui peut ordonnancer aléatoirement les 27 LEDs - le numéro N qui sort est entre 0 et 26 est correspond par exemple à choixLed[etage][colonne] avec etage=N/9; colonne=N%9;

reste plus qu'à rajouter un random(0,2) pour décider allumée ou éteinte si vous voulez faire clignoter aléatoirement, ou LOW si vous voulez éteindre aléatoirement, ou HIGH pour alluler - et mettre cela dans un test de tempo if (millis()-momentSuivant > periode) { ....  ; momentSuivant+=periode; }

Je commence à conprendre, merci à tous pour votre aide.
Vous êtes au top !