Petite fonction de bitmask pour usage multiple.

Salut les Arduino,
Je vous présente ici un tout petit bout de code dont vous pourrez vous servir afin d'utiliser toutes les sorties digitales afin par exemple de faire flasher des LED dans toutes les combinaisons comme le présente le code exemple ou afficher la valeur d'un octet grâce a des LED ou ce quoi bon vous semble.
Le code construit un tableau de N port ayant pow(N,2) possibilités de sortie|entrés digitales, indexer de manière a ce que le premier bitmask représente le nombre zéro et le dernier pow(N,2)... pour par exemple afficher la valeur d'un octet.
Voici le code:

#define DIG_PIN_1 2
#define DIG_PIN_2 3
#define DIG_PIN_3 4
#define DIG_PIN_4 5

#define DIG_PINS_NUMBER 4

int dig_pin_table[DIG_PINS_NUMBER]={DIG_PIN_1,DIG_PIN_2,DIG_PIN_3,DIG_PIN_4} ;

void setup() {
  int c ;
  for (c=0 ; c < DIG_PINS_NUMBER ; c++) {
    pinMode(dig_pin_table[c],OUTPUT) ;
  }
  Serial.begin(9600) ;
}

void loop() {
  if (Serial.available() > 0 ) {
    int serial_value=Serial.read() ;
    if ( serial_value == '0' ) {
      LED_switch_all(DIG_PINS_NUMBER) ; 
      init_LED(DIG_PINS_NUMBER) ;
    }
    
  }
  
  
}

void LED_switch_all(int number_of_LED) {
  
  /*******************************************************/
  /* A little function to switch a number of LED on|off  */
  /* with all possibilities.                             */     
  /*******************************************************/
  
  int total_possibilities = pow(number_of_LED,2) ;
  
  int table[total_possibilities][number_of_LED] ;

  int c ;
  for (c=0 ; c < total_possibilities ; c++) {
    int cc ;
    int value_to_bin=c ;
    for (cc=0 ; cc < number_of_LED ; cc++) {
      table[c][cc]=value_to_bin % 2 ;
      value_to_bin /= 2 ;
    }
  }
  /* example code */
  /*    begin     */
  for (c=0 ; c < total_possibilities ; c++) {
    int cc ;
    for(cc=0 ; cc < DIG_PINS_NUMBER ; cc++ ) {
      
      if ( table[c][cc] == 1 ) {
        switch_LED_on(dig_pin_table[cc]) ;
      }
      
    }
    delay(750) ;
    init_LED(DIG_PINS_NUMBER) ;
  }
 /* example code */ 
 /*      end     */ 
}

void switch_LED_on(int pin_number) {
  digitalWrite(pin_number,HIGH) ;
}

void switch_LED_off(int pin_number) {
  digitalWrite(pin_number,LOW) ;
}

void init_LED(int number_of_LED) {
  int c ;
  for (c=0 ; c < number_of_LED; c++) {
    switch_LED_off(dig_pin_table[c]) ;
  }
}

La fonction a réutiliser est la fonction: LED_switch_all() le reste n'est qu'un exemple d'utilisation.
Mais celle-ci mérite quelque explications:
-La fonction prend en entrée le nombre de PIN puis calcule a partir de ce le chiffre exacte du nombre de possibilités de combinaisons de 0 (Pour mettre a LOW) et de 1 (pour mettre a HIGH) grace a la puissance du nombre de pin par 2 ( pow(N,2) ) puis construit un tableau ,de longueurs pow(N,2), de tableaux de taille du nombre de PIN. Puis remplis celui-ci de toutes les combinaisons de 0 et de 1 par un calcule de base 10 en base binaire. Résultat vous avez un tableau de tableau composer de 0 et de 1, ce qui peut être utile.

A vous de jouer.

Bon apparemment comme ça n'interresse personne j'ai amélioré le truc:
Dans la nouvelle version:
Le jeu de fonctions est capable:
-De traiter jusqu'à 7 ports.
-De les allumer et les éteindre dans toutes les possibilités:
-> Dans l'ordre de calcul du des bitmasks.
-> Dans l'ordre inverse du calcul du calcule des bitmasks.
-> Grâce a une fonction de mixage, de mixer le tableau contenant les bitmasks, et d'obtenir un ordre pseudo-aléatoire.

Vous pouvez retrouver le jeu de fonction sur mon site: http://www.cyber-sanktuary.fr/Programmation/Codes/Astuce/py_code_00000.py

J'ai du mal à comprendre l'utilité de ton code.

Si tu veux faire toutes les combinaisons possibles de 8 LEDs, il faut juste mettre les 8 LEDS sur le même port puis assigner une valeur entre 0 et 255 à ce port.

Ou alors je n'ai vraiment rien compris mais j'ai une excuse je suis très fatigué :slight_smile:

L'utilité ne se limite pas aux LEDs mais au port digitals,
par exemple pour 2 ports,
on a:

table[pow(2,2)][2]={ {0,0}, {0,1}, {1,0},{1,1} } // comme bitmask possible.

Il suffit d'itérer sur le tableau table puis sur le tableau d'indice actuel et en fonction que la valeur soit un 1 ou un 0 allumer ou éteindre un port digital.
par exemple:

for (byte c=0 ; c < 2 ; c++) {
  if (table[1][c] == 1) {
    digitalWrite(port,HIGH) ;
  }
}
// Puis éteindre tout et continuer a itérer.

Hello,

Pourquoi jouer avec pow alors qu'en base 2, les opérateurs binaires (<<, >>, &&, ||) sont beaucoup plus efficaces ?

j'ai vraiment à piger où tu veux en venir et de ce que je comprend, au point où tu en es autant manipuler directement les ports Arduino Reference - Arduino Reference
Beaucoup plus simple et amplement plus rapide.

Tu confonds pin et port. Un port c'est un groupe de pins, quand tu utilise digitalWrite, en fait tu change simplement un bit de la valeur du port associé.

Par exemple les pins 22 à 29 de l'Arduino Mega sont sur le port A.
Regarde ce tableau: https://spreadsheets.google.com/pub?key=rtHw_R6eVL140KS9_G8GPkA&gid=0

Je ne comprend pas pourquoi tu parle de bitmask. Tu ne fais aucun bitmask, tu remplis juste un tableau avec toutes les valeurs possibles, ce qui est un gros gaspillage de précieuse mémoire: ton exemple utilise 8 bytes, alors que tu n'as finalement besoin que de 2 bits (32x moins de mémoire).

Je veux pas te décourager, si tu es débutant c'est toujours utile de tester et faire ce genre de truc :wink: