/* attiny charlieplexing 6leds tempo aleatoire
   changement de l'état des sorties et tempo aléatoires
   Charlieplexing 3 broches de commande, 6 LEDs
   24/11/2021
   Dominique Hudry
   liens: https://electroniqueamateur.blogspot.com/2019/06/controler-plusieurs-leds-avec-arduino.html
          https://wokwi.com/projects/383742543737815041
   test: ok   
  
    led A  B  C
     1  +  -  HZ
     2  -  +  HZ
     3  HZ +  -
     4  HZ -  +
     5  -  HZ +
     6  +  HZ -
      
             Brochage ATtiny85
             
                =|1  U  8|= VCC
                =|2     7|= 2<--> BrocheC
   random -->A2 =|3     6|= 1<--> BrocheB
            GND =|4     5|= 0<--> BrocheA
*/
const byte BrocheA = 0; // déclaration des broches de commande
const byte BrocheB = 1;
const byte BrocheC = 2;
const byte ButeeMini = 1;   // valeur mini de la temporisation aléatoire
const byte ButeeMaxi = 5;   // valeur maxi +1 de la temporisation aléatoire
const byte NombreDeLeds = 6;   // nombre de leds
bool etatLeds[] = {1, 1, 1, 1, 1, 1}; // état des 6 leds, au démarrage tout est allumé
unsigned long tempsActuel;
byte bitAleatoire;             // bit choisi aléatoirement entre bit0 et bit5
int tempo;                     // temporisation aléatoire entre deux états

void setup() {
  tempsActuel = millis();
  tempo = 10000; // au démarrage toutes les leds sont allumées durant 10s pour test
  randomSeed(analogRead(A2));
  efface_tout(); // les broches de commandes sont en HZ
} // fin setup

void loop() {
  for (byte i = 0; i < 6; i++) { // on cherche quelle led doit être allumée
    if (etatLeds[i] == 1) { 
      reglage_led(i + 1); // on régle les paramètres pour chaque led devant être allumée
    }// fin if
    else { // si être éteinte on passe les broches de commande en haute impédance
      efface_tout(); 
    } // fin else
  } // fin boucle for
  if (millis() > tempsActuel + tempo) {
    tempsActuel = millis();
    tempo = random(ButeeMini, ButeeMaxi); // génération de la temporisation aléatoire
    tempo = tempo * 1000;
    bitAleatoire = random(0, NombreDeLeds); // génère le numéro du bit qui changera l'état de la sortie liée
    etatLeds[bitAleatoire] = !etatLeds[bitAleatoire]; // inversion de l'état de la sortie correspondant au nombre aléatoire
  } // fin test if
} // fin loop

void efface_tout() { // on met les 3 broches de commande en haute impédance
  pinMode(BrocheA, INPUT); 
  pinMode(BrocheB, INPUT);
  pinMode(BrocheC, INPUT);
} // fin efface_tout

void reglage_led(int numeroLed) { // pour chaque led devant s'allumer on précise uniquement les broches impliquées
  switch (numeroLed)  {
    case 1: // led1
      reglage_broches(BrocheA, BrocheB); // A+ B-
      break;

    case 2: // led2
      reglage_broches(BrocheB, BrocheA); // B+ A-
      break;

    case 3: // led3
      reglage_broches(BrocheB, BrocheC); // B+ C-
      break;

    case 4: // led4
      reglage_broches(BrocheC, BrocheB); // C+ B-
      break;

    case 5: // led5
      reglage_broches(BrocheC, BrocheA); // C+ A-
      break;

    case 6: // led6
      reglage_broches(BrocheA, BrocheC); // A+ C-
      break;
      
    default:
      break;
  } // fin switch case
} // fin reglage_led

void reglage_broches(int anode, int cathode) { // on fixe le niveau des broches impliquées
  efface_tout();  // on éteint les leds, donc il restera systématiquement une broche en haute impédance
  pinMode(anode, OUTPUT); // la broche qui envoie du +5V
  digitalWrite(anode, HIGH);
  pinMode(cathode, OUTPUT);// la broche qui est à la masse
  digitalWrite(cathode, LOW);
} // fin reglage_broches
ATTINY8520PU