Le même carrefour qu vu précédemment, mais remplacement du MCP23107 par un 74154.
Je pensais que cela allait aller tout seul... mais non, toutes les LED restent allumées
Code:///////////////////////////////////////////////////////////////////////////////////////// // Pour le 74154 const int A_PIN = 7; const int B_PIN = 8; const int C_PIN = 9; const int D_PIN = 10; const int E1_PIN = 11; const int E2_PIN = 12; ///////////////////////////////////////////////////////////////////////////////////////// #include <TM1637Display.h> // gestion de 4 digits 7 segments // Module connection pins (Digital Pins) #define CLK 5 #define DIO 6 TM1637Display display(CLK, DIO); const int UT = 2; // Durée de l'unité de temps en secondes (ou plutôt en nbre de compteurs) int t1, t2; const byte interruptPin_A = 2; const byte interruptPin_B = 3; const byte pinMaintenace = 4; bool fBP; // mémorise si les boutons pbA ou pbB ont été enclenchés int compteur = 0; // Le nombre d'unités de temps (secondes) écoulés unsigned long long next_seconde = 0; bool bSens = true; // si true A = Vert, sinon B = Vert //char cSens[2]; // contiendra 'A' et 'B' char message[50]; // Attention : pas trop peu, sinon plantage sans erreur // pour la maintenance bool bEtatOrange = false; bool bInitMaintenance = false; //pour le 1er passage unsigned long long nextOrange = 0 ; // gestion des temps /* valeurs et tableaux pour mieux comprendre les messages À terme, ils pourront disparaitrent */ enum {RED, ORANGE, GREEN}; //0, 1 et 2 const char* tColors[] = { "Rouge", "Orange", "Vert" }; const char* tState[] = { "LOW", // pour 0 (on pourrait aussi mettre "Off" "HIGH" // pour 1 (on pourrait aussi mettre "On" }; char cSens[2]; // sera rempli dans le setup struct ST_FEU { int sens; // 0/1 false/true int couleur; // 0 1 2 RED ORANGE GREEN | voir emum ci-dessus int broche; // broche mcp int etat; // 0/1 LOW/HIGH }; /* Les 10 feux avec leurs broches (mcp) respectives. Seule le dèrnière dimension (etat) changera : LOW / HIGH */ ST_FEU feuxVoitures[6] = { {1, 0, 0, 0}, // Feu voiture A - rouge - broche - LOW {1, 1, 1, 0}, // Feu voiture A - orange - broche - LOW {1, 2, 2, 0}, // Feu voiture A - vert - broche - LOW {0, 0, 3, 0}, // Feu voiture B - rouge - broche - LOW {0, 1, 4, 0}, // Feu voiture B - orange - broche - LOW {0, 2, 5, 0} // Feu voiture B - vert - broche - LOW }; ST_FEU feuxPietons[4] = { {1, 0, 6, 0}, // Feu piéton A - rouge - broche - LOW {1, 2, 7, 0}, // Feu piéton A - vert - broche - LOW {0, 0, 8, 0}, // Feu piéton B - rouge - broche - LOW {0, 2, 9, 0} // Feu piéton B - vert - broche - LOW }; void gere(int nombre) { // Éteignez toutes les broches digitalWrite(A_PIN, LOW); digitalWrite(B_PIN, LOW); digitalWrite(C_PIN, LOW); digitalWrite(D_PIN, LOW); // Vérifiez si le nombre est dans la plage valide (1-16) if (nombre >= 1 && nombre <= 16) { // Convertissez le nombre décimal en binaire int binaire[4]; for (int i = 0; i < 4; i++) { binaire[i] = nombre % 2; nombre /= 2; } // Configurez les broches A_PIN à D_PIN en fonction du nombre binaire digitalWrite(A_PIN, binaire[0]); digitalWrite(B_PIN, binaire[1]); digitalWrite(C_PIN, binaire[2]); digitalWrite(D_PIN, binaire[3]); } } void majVoitures(bool way, int color, int state) { Serial.println(); sprintf(message, "feux voiture voie %c couleur %s etat %s", cSens[way], tColors[color], tState[state]); Serial.print(message); Serial.print(" "); for (int i = 0; i <= 5; i += 1) { if (feuxVoitures[i].sens == way) { // tous les feux de sens à LOW feuxVoitures[i].etat = LOW; if (feuxVoitures[i].couleur == color) { // traitement de ce feu particulier (LOW ou HIGH) feuxVoitures[i].etat = state; } } //mcp.digitalWrite(feuxVoitures[i].broche, feuxPietons[i].etat); gere(feuxVoitures[i].broche); //, feuxVoitures[i].etat); } } void majPietons(bool way, int color, int state) { Serial.println(); sprintf(message, "feux pietons voie %c couleur %s etat %s", cSens[way], tColors[color], tState[state]); Serial.print(message); Serial.print(" "); for (int i = 0; i <= 3; i += 1) { if (feuxPietons[i].sens == way ) { // tous les feux de sens à LOW feuxPietons[i].etat = LOW; if (feuxPietons[i].couleur == color) { // traitement de ce feu particulier (LOW ou HIGH) feuxPietons[i].etat = state; } } //mcp.digitalWrite(feuxPietons[i].broche, feuxPietons[i].etat); gere(feuxPietons[i].broche); } } void init_timer() { // initialise t1 et t2 selon UT t2 = 2 * UT; t1 = 6 * t2; } void event_bp_A() { if (bSens && digitalRead(pinMaintenace) == HIGH) { //sens VERT hors maintenance pour A (on accepte l'appui) fBP = true; Serial.print("* "); } } void event_bp_B() { if (!bSens && digitalRead(pinMaintenace) == HIGH) { //sens VERT hors maintenance pour B (on accepte l'appui) fBP = true; Serial.print("* "); } } int Affichage() { /* le temps restant est t1+t2 - compteur le sens est connu avec bSens */ int digit = bSens * 2; display.showNumberDec(t1 + t2 - compteur, false, 2, digit); digit = !bSens * 2; display.showNumberDec(0, false, 2, digit); return compteur; } // fin affichage void setup() { Serial.begin(9600); Serial.println(); Serial.println(__FILE__); Serial.println(); cSens[0] = 'B'; // si false cSens[1] = 'A'; // si true compteur = 0; init_timer(); // t1 et t2 pinMode(interruptPin_A, INPUT_PULLUP); pinMode(interruptPin_B, INPUT_PULLUP); pinMode(pinMaintenace, INPUT_PULLUP); attachInterrupt(digitalPinToInterrupt(interruptPin_A), event_bp_A, LOW ); attachInterrupt(digitalPinToInterrupt(interruptPin_B), event_bp_B, LOW ); fBP = false; pinMode(A_PIN, OUTPUT); pinMode(B_PIN, OUTPUT); pinMode(C_PIN, OUTPUT); pinMode(D_PIN, OUTPUT); pinMode(E1_PIN, OUTPUT); pinMode(E2_PIN, OUTPUT); digitalWrite(E1_PIN, LOW); // Activer les sorties du décodeur digitalWrite(E2_PIN, LOW); // Activer les sorties du décodeur display.setBrightness(5); // de 0 à 8 display.clear(); } void loop() { Serial.print(Affichage()); Serial.print(" "); if (compteur >= (t1 + t2)) { // Changement de sens de circulation à la fin du cycle t1+t2. compteur à 0 Serial.println("T1+T2 "); bSens = !bSens; compteur = 0; // urgence maintenance while (digitalRead(pinMaintenace) == LOW) { // tant que le bouton Maintenance est actionné if (!bInitMaintenance) { // 1er passage /* Éteindre les feux piétons ========================= if suffit d'un mettre 1 à LOW dans les 2 sens pour qu'ils soient tous à LOW */ majPietons(bSens, GREEN, LOW); majPietons(!bSens, GREEN, LOW); /* Définir les temps ================= HIGH 750 millisecondes LOW 250 millis */ bEtatOrange = false; // je les décare éteins pour les allumer juste après bInitMaintenance = true; // fin du 1er passage, on y repassera plus } // fin 1er passage (nextOrange = 0) if (nextOrange < superMillis()) { //temps écoulé, échange true/false donc HIGH/LOW bEtatOrange = !bEtatOrange; majVoitures(bSens, ORANGE, bEtatOrange); majVoitures(!bSens, ORANGE, bEtatOrange); if (bEtatOrange) { // Orange allumé pendant ... nextOrange = superMillis() + 750; } else { // temps éteind pendant ... nextOrange = superMillis() + 250; } } // fin du test/bascule clignotemant } // fin de l'urgenece bInitMaintenance = false; } // fin compteur >= (t1 + t2) if (compteur == 0) { // début init_timer(); // s'il a été modifié ou pas, recalcul t1 majVoitures(bSens, GREEN, HIGH); majVoitures(!bSens, RED, HIGH); majPietons(bSens, RED, HIGH); majPietons(!bSens, GREEN, HIGH); } // fin compteur == 0 if (compteur == t1) { // Préparation du changement de sens : orange pour le sens en cours, rouge pour le reste Serial.print("_T1_ "); majVoitures(bSens, ORANGE, HIGH); majVoitures(!bSens, RED, HIGH); majPietons(bSens, RED, HIGH); majPietons(!bSens, RED, HIGH); } // fin compteur == t1 /* le reste du temps, attend 1 seconde on n'utilise pas delay pour que les interruptions fonctionnent */ while (superMillis() <= next_seconde) { /* si un Bouton Piéton a été appuyé (même avant t1/2 et que l'on est dans la tranche horaire (compteur) entre t1/2 et T1 on raccourci t1 au compteur actuel (+ 1 seconde) */ if (fBP && compteur >= (t1 / 2) && compteur < t1) { t1 = compteur + 1; fBP = false; } } next_seconde = 500 + superMillis(); // dans la version définitive, remplacer par 1000 compteur += 1; } unsigned long long superMillis() { //https://www.carnetdumaker.net/snippets/8/ /** Retourne le nombre de millisecondes depuis le démarrage du programme sous la forme d'un nombre entier sur 64 bits (unsigned long long). anti bug de l'overflow des 32 bits qui repasse à zéro tous les moins de 50 jours Là, ce sera l'overflow toutes les 584.542.046 années */ static unsigned long nbRollover = 0; static unsigned long previousMillis = 0; unsigned long currentMillis = millis(); if (currentMillis < previousMillis) { nbRollover++; } previousMillis = currentMillis; unsigned long long finalMillis = nbRollover; finalMillis <<= 32; finalMillis += currentMillis; return finalMillis; }
-----