Bonjour,
pour un arduino uno
Le prof demande comme exercice de ne pas utiliser les broches A (donc pas d'I2C) ni de multiplexeur.
Les broches 2 à 4 sont utilisées, 5 et 6 aussi pour un TM1637
J'ai besoin de 10 broches OUT .
-----
Bonjour,
pour un arduino uno
Le prof demande comme exercice de ne pas utiliser les broches A (donc pas d'I2C) ni de multiplexeur.
Les broches 2 à 4 sont utilisées, 5 et 6 aussi pour un TM1637
J'ai besoin de 10 broches OUT .
bonjour,
Pas claire cette demande !
sur de la reference MSCP23017 ?
un petit schema ?
les 3 pins d'adresses( A0,A1,A2 ) I2C du MCP23017 ?les broches A ?
MCP23017 PORT d'Entrees/sorties programmable deporté sur bus I2C ...8E/8S ou 16S ou 16E
MCP23S17 PORT d'entrees /sorties programmable deporté sur bus SPI ...8E/8S ou 16S ou 16E
donc OK pour 10 out en SPI , si il ne faut pas utiliser l'I2C
Dernière modification par paulfjujo ; 20/05/2023 à 08h08.
oui j'ai mélangé les lettres c'est bien MCP23S17
J'étais parti sur le I2C
Merci
Comment remplacer par un SPI
Avec ce code :
Code:#include <Adafruit_MCP23X17.h> // pour le mcp23017 ci-dessous /* I2C A4 SDA (datas) A5 SCK (clock) */ /* MCP23017 VDD +5v VSS ground GPB0 1 28 GPA7 GPB1 2 27 GPA6 GPB2 3 26 GPA5 GPB3 4 25 GPA4 GPB4 5 24 GPA3 GPB5 6 23 GPA2 GPB6 7 22 GPA1 GPB7 8 21 GPA0 Vdd+ 9 20 INT4 Vss- 10 19 INTB NC 11 18 +RESET SCK 12 17 A2 SDA 13 16 A1 NC 14 15 A0 gestion adresse I2C de A0 à A2 (binaire de 000 - gnd à 111 +5v) à partir de 0x20 2^3 = 8 x 16 = 128 e/s possibles ... INTB +5 Volts RST +5 Volts Vdd +5 Volts Vss GND */ // on crée l'objet Adafruit_MCP23X17 mcp; ///////////////////////////////////////////////////////////////////////////////////////// #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 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, 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); } } 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; mcp.begin_I2C(32); // Utilise l'adresse 32 (base 10) de base a0 a1 et a2 000 for (int i = 0; i < 10; i++) { // 6 tricolores + 4 bicolores mcp.pinMode(i, OUTPUT); mcp.digitalWrite(i, HIGH); mcp.pinMode(i, OUTPUT); mcp.digitalWrite(i, HIGH); } 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; }
Oubliez-moi