Intégrer multiplexer cd74hc4067

Bonjour,

C'est mon premier message pour demander de l'aide.
Je vous explique:

Actuellement j'ai un arduino mega avec 50 boutons et ca fonctionne très bien

mais je souhaiterais utiliser des multiplexer 74hc4067 pour pouvoir me servir d'un arduino nano
ca fais 2 semaine que je cherche et j'ai rien trouver, je n'y arrive pas

est ce que quelqu'un peut m'aider a intégrer dans mon code les multiplexer

Voici mon code
un grand merci a ceux qui pourrons m'aider


int Pot; 
int Pot2;
int timeLong = 1000;
int timeBreak = 1000;


const byte maxButton = 50;             // number of buttons
const byte pinPushButton[maxButton] = {2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51};  // the Arduino pins 


byte message[] = {0x82};
// ------------------------------------------------------------------------
// --- Setup
// --------------------------------------------------------------------------
void setup() {
  

    Serial.begin(38400); 
    

   
    
  // --- initialize push button pins as inputs with pull-ups
  for (byte i=0; i<maxButton; i++) {
    pinMode(pinPushButton[i], INPUT_PULLUP);
  }
}   


// --------------------------------------------------------------------------
// --- Main loop
// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
void loop() {

  static unsigned long previousTime = 0;  
  const byte timeInterval = 0;   // pick a short time interval, you don't have to 
                                 // check the button with 10kHz
  byte a[maxButton] = {};        // array to store the latest readings

  // - check all buttons
  if ((millis()-previousTime) > timeInterval) {
    previousTime = millis();
    for (byte i=0; i<maxButton; i++) {
      a[i] = checkButtons(i); 
      
      }

    if (a[0] == 1)  {
      Serial.print( "\x80\x2b\x01");
            }
    if (a[0] == 2)  {
      Serial.print( "\x90\x2b\x7F");
      
      }
    if (a[1] == 1)  {
      Serial.print( "\x80\x2c\x01");
      
    }
    if (a[1] == 2)  {
      Serial.print( "\x90\x2c\x7F");
      
    }
    if (a[2] == 1)  {
      Serial.print( "\x80\x2d\x01");
      
    }
    if (a[2] == 2)  {
      Serial.print( "\x90\x2d\x7F");
      
    }
    if (a[3] == 1)  {
      Serial.print( "\x80\x2e\x01");
      
    }
    if (a[3] == 2)  {
      Serial.print( "\x90\x2e\x7F");
      
    }
    if (a[4] == 1)  {
      Serial.print( "\x80\x2f\x01");
      
    }
    if (a[4] == 2)  {
      Serial.print( "\x90\x2f\x7F");
      
    }
    if (a[5] == 1)  {
      Serial.print( "\x80\x30\x01");
      
    }
    if (a[5] == 2)  {
      Serial.print( "\x90\x30\x7F");
      
    }
    if (a[6] == 1)  {
      Serial.print( "\x80\x31\x01");
      
    }
    if (a[6] == 2)  {
      Serial.print( "\x90\x31\x7F");
      
    }
    if (a[7] == 1)  {
      Serial.print( "\x80\x32\x01");
      
    }
    if (a[7] == 2)  {
      Serial.print( "\x90\x32\x7F");
      
    }
    if (a[8] == 1)  {
      Serial.print( "\x80\x33\x01");
      
    }
    if (a[8] == 2)  {
      Serial.print( "\x90\x33\x7F");
      
    }
    if (a[9] == 1)  {
      Serial.print( "\x80\x34\x01");
      
    }
    if (a[9] == 2)  {
      Serial.print( "\x90\x34\x7F");
      
    }
    if (a[10] == 1)  {
      Serial.print( "\x80\x35\x01");
      
    }
    if (a[10] == 2)  {
      Serial.print( "\x90\x35\x7F");
      
    }
    if (a[11] == 1)  {
      Serial.print( "\x80\x36\x01");
      
      
    }
    if (a[11] == 2)  {
      Serial.print( "\x90\x36\x7F");
      
    }
    if (a[12] == 1)  {
      Serial.print( "\x80\x37\x01");
      
    }
    if (a[12] == 2)  {
      Serial.print( "\x90\x37\x7F");
      
    }
    if (a[13] == 1)  {
      Serial.print( "\x80\x38\x01");
      
    }
    if (a[13] == 2)  {
      Serial.print( "\x90\x38\x7F");
      
    }
    if (a[14] == 1)  {
      Serial.print( "\x80\x39\x01");
      
    }
    if (a[14] == 2)  {
      Serial.print( "\x90\x39\x7F");
      
    }
    if (a[15] == 1)  {
      Serial.print( "\x80\x3a\x01");
      
    }
    if (a[15] == 2)  {
      Serial.print( "\x90\x3a\x7F");
      
    }
    if (a[16] == 1)  {
      Serial.print( "\x80\x3b\x01");
      
    }
    if (a[16] == 2)  {
      Serial.print( "\x90\x3b\x7F");
      
    }
    if (a[17] == 1)  {
      Serial.print( "\x80\x3c\x01");
      
    }
    if (a[17] == 2)  {
      Serial.print( "\x90\x3c\x7F");
      
    }
    if (a[18] == 1)  {
      Serial.print( "\x80\x3d\x01");
      
    }
    if (a[18] == 2)  {
      Serial.print( "\x90\x3d\x7F");
      
    }
    if (a[19] == 1)  {
      Serial.print( "\x80\x3e\x01");
      
    }
    if (a[19] == 2)  {
      Serial.print( "\x90\x3e\x7F");
      
    }
    if (a[20] == 1)  {
      Serial.print( "\x80\x3f\x01");
     
    }
    if (a[20] == 2)  {
      Serial.print( "\x90\x3f\x7F");
      
    }
    if (a[21] == 1)  {
      Serial.print( "\x80\x40\x01");
      
    }
    if (a[21] == 2)  {
      Serial.print( "\x90\x40\x7F");
      
    }
    if (a[22] == 1)  {
      Serial.print( "\x80\x41\x01");
      
    }
    if (a[22] == 2)  {
      Serial.print( "\x90\x41\x7F");
      
    }
    if (a[23] == 1)  {
      Serial.print( "\x80\x42\x7F");
      
    }
    if (a[23] == 2)  {
      Serial.print( "\x90\x42\x7F");
      
    }
    if (a[24] == 1)  {
      Serial.print( "\x80\x43\x7F");
      
    }
    if (a[24] == 2)  {
      Serial.print( "\x90\x43\x7F");
      
    }
    if (a[25] == 1)  {
      Serial.print( "\x80\x44\x7F");
      
    }
    if (a[25] == 2)  {
      Serial.print( "\x90\x44\x7F");
      
    }
    if (a[26] == 1)  {
      Serial.print( "\x80\x45\x7F");
      
    }
    if (a[26] == 2)  {
      Serial.print( "\x90\x45\x7F");
      
    }
    if (a[27] == 1)  {
      Serial.print( "\x80\x46\x7F");
      
    }
    if (a[27] == 2)  {
      Serial.print( "\x90\x46\x7F");
      
    }
    if (a[28] == 1)  {
      Serial.print( "\x80\x47\x7F");
      
    }
    if (a[28] == 2)  {
      Serial.print( "\x90\x47\x7F");
      
    }
    if (a[29] == 1)  {
      Serial.print( "\x80\x48\x7F");
      
    }
    if (a[29] == 2)  {
      Serial.print( "\x90\x48\x7F");
      
    }
    if (a[30] == 1)  {
      Serial.print( "\x80\x49\x7F");
      
    }
    if (a[30] == 2)  {
      Serial.print( "\x90\x49\x7F");
      
    }
    if (a[31] == 1)  {
      Serial.print( "\x80\x4a\x7F");
      
    }
    if (a[31] == 2)  {
      Serial.print( "\x90\x4a\x7F");
      
    }
    if (a[32] == 1)  {
      Serial.print( "\x80\x4b\x7F");
      
    }
    if (a[32] == 2)  {
      Serial.print( "\x90\x4b\x7F");
      
    }
    if (a[33] == 1)  {
      Serial.print( "\x80\x4c\x7F");
     
    }
    if (a[33] == 2)  {
      Serial.print( "\x90\x4c\x7F");
     
    }
    if (a[34] == 1)  {
      Serial.print( "\x80\x4d\x7F");
      
    }
    if (a[34] == 2)  {
      Serial.print( "\x90\x4d\x7F");
      
    }
    if (a[35] == 1)  {
      Serial.print( "\x80\x4e\x7F");
      
    }
    if (a[35] == 2)  {
      Serial.print( "\x90\x4e\x7F");
      
    }
    if (a[36] == 1)  {
      Serial.print( "\x80\x4f\x7F");
      
    }
    if (a[36] == 2)  {
      Serial.print( "\x90\x4f\x7F");
      
    }
    if (a[37] == 1)  {
      Serial.print( "\x80\x50\x7F");
      
    }
    if (a[37] == 2)  {
      Serial.print( "\x90\x50\x7F");
     
    }
    if (a[38] == 1)  {
      Serial.print( "\x80\x51\x7F");
      
    }
    if (a[38] == 2)  {
      Serial.print( "\x90\x51\x7F");
     
    }
    if (a[39] == 1)  {
      Serial.print( "\x80\x52\x7F");
      
    }
    if (a[39] == 2)  {
      Serial.print( "\x90\x52\x7F");
      
    }
    if (a[40] == 1)  {
      Serial.print( "\x80\x53\x7F");
      
    }
    if (a[40] == 2)  {
      Serial.print( "\x90\x53\x7F");
      
    }
    if (a[41] == 1)  {
      Serial.print( "\x80\x54\x7F");
      
    }
    if (a[41] == 2)  {
      Serial.print( "\x90\x54\x7F");
      
    }
    if (a[42] == 1)  {
      Serial.print( "\x80\x55\x7F");
      
    }
    if (a[42] == 2)  {
      Serial.print( "\x90\x55\x7F");
      
    }
    if (a[43] == 1)  {
      Serial.print( "\x80\x56\x7F");
      
    }
    if (a[43] == 2)  {
      Serial.print( "\x90\x56\x7F");
      
    }
    if (a[44] == 1)  {
      Serial.print( "\x80\x57\x7F");
      
    }
    if (a[44] == 2)  {
      Serial.print( "\x90\x57\x7F");
      
    }
    if (a[45] == 1)  {
      Serial.print( "\x80\x58\x7F");
      
    }
    if (a[45] == 2)  {
      Serial.print( "\x90\x58\x7F");
      
    }
    if (a[46] == 1)  {
      Serial.print( "\x80\x59\x7F");
      
    }
    if (a[46] == 2)  {
      Serial.print( "\x90\x59\x7F");
      
    }
    if (a[47] == 1)  {
      Serial.print( "\x80\x5a\x7F");
      
    }
    if (a[47] == 2)  {
      
      Serial.print( "\x90\x5a\x7F");
    }
    if (a[48] == 1)  {
      Serial.print( "\x80\x5b\x7F");
      
    }
    if (a[48] == 2)  {
      Serial.print( "\x90\x5b\x7F");
      
    }
    if (a[49] == 1)  {
      Serial.print( "\x80\x5c\x7F");
      Serial.print( "\xb8\x40\x01");
      
    }
    if (a[49] == 2)  {
      Serial.print( "\x90\x5c\x7F");
      Serial.print( "\xb8\x40\x7F");
      
      
    }
    
  }

} 


// -----------------------------------------------------------------
// ---------------------------------------------------------------------------------
// --- check one button for short or long push
// ---------------------------------------------------------------------------------
//     returns: 0-none  1-short  2-long
//




byte checkButtons(byte buttonNo) {


  
 
 // Pot = analogRead(A0); 
 // Pot2 = analogRead(A1);
  
 // timeBreak = map(Pot, 0, 450, 0, 55); 
  //timeLong = map(Pot2, 0, 450, 0, 55); 


const unsigned long timeDebounce = 0; // time to debounce 
    
                                       //  before ready for next press 
static byte state[maxButton] = {};     // this initializes all elements to zero
static unsigned long previousTime[maxButton] = {};
 
  byte r = 0;

  r = 0;      // 0:not  1:short  2:long

 
 
  if (state[buttonNo] == 0) {             // --- no button has been pressed - check if 
    if (digitalRead(pinPushButton[buttonNo]) == LOW) {
      previousTime[buttonNo] = millis();
      state[buttonNo] = 1;
    }
  } else if (state[buttonNo] == 1) {  // --- button was pressed - check for how long
    if ( (millis()-previousTime[buttonNo]) > timeDebounce) {
      if ( (millis()-previousTime[buttonNo]) < timeLong) {
        if ( digitalRead(pinPushButton[buttonNo]) == HIGH) { // released -> short press
          previousTime[buttonNo] = millis();
          state[buttonNo] = 2;
          
        }
      } else {                        // it was a long press
        state[buttonNo] = 2;
        r = 2;
      }
    }
  } else if (state[buttonNo] == 2) {  // --- wait for long button press to end
    if (digitalRead(pinPushButton[buttonNo]) == HIGH) {
      previousTime[buttonNo] = millis();
      state[buttonNo] = 3;
      
    }  
  } else if (state[buttonNo] == 3) {  // --- wait a little while after previous button press
    if ( (millis()-previousTime[buttonNo]) > timeBreak) {
      state[buttonNo] = 0;
      r = 1;
    }
          
    else if (digitalRead(pinPushButton[buttonNo]) == LOW) {
      previousTime[buttonNo] = millis();
      state[buttonNo] = 3;
    }
  }
  return r;

 
  }


  

  

Salut.
En premier lieu il va falloir concevoir le matériel et comme le 74hc4067 n'a que 16 E/S soit vous en utilisez trois et vous vous contentez de 48 boutons soit vous en utilisez 4 et vous pouvez placer 64 un schéma avec 4 74hc4067, (j'ai non représenté l'alimentation de la puce qui va sur le 5V de l'arduino et le choix des pins est aléatoire, ce serait le suivant :


L'opération est simple en écrivant dans D2, D3, D4, et D5 le nombre binaire de l'entrée correspondante, (0-16) on aura la valeur de ladite entrée disponible sur la broche D10. Évidemment, nous devrons également sélectionner en même temps la puce qui donne cette entrée, nous le faisons en réglant l'entrée EN à partir de laquelle nous voulons lire sur LOW, D6 pour U1, D7 pour U2, D8 pour U3 et D9 pour U4 .

Code : vous devrez changer peu, actuellement vous lisez les 50 boutons d'un coup, avec ce circuit vous devrez les lire 4 fois de 16 lectures chacune en prenant soin de sauvegarder la valeur dans la bonne position de "checkButtons" pour que tous les if sont valables.

À titre d'exemple, sur cette PAGE, vous avez quelques codes de lecture/écriture pour 74hc4067 que vous pouvez adapter à votre code pour le nouveau matériel.
Salutations

Edition : Voir les modifications importantes dans le message # 11

Bonsoir music59

Pourquoi ne pas s'orienter du côté du MCP23017 qui a 16 E/S on peut en chaîner 8 et ça utilise 2 fils (SDA/SCL respectivement A4 et A5) du Nano c'est le bus i2C?

Cordialement
jpbbricole

Deux remarques :

  1. La secondaire :
    La référence CD74HCxxxx est plus que bizarre, bien que je l'ai trouvé dans une doc Texas.
    Les technologies CDxxxx et 74HCxxxc étant différentes.
  • La 74HC ne fonctionne que sous 5 V.
  • La CD4xxx fonctionne dans une large gamme de tension d'alimentation. Le CD4067 fonctionne de 2V à 7V, d'autres références fonctionnent à des tensions supérieures à 12 V.
  1. La principale :
    Le CI CD4067 ou 74HC4067 est un multiplexeur analogique, le MCP23017 est numérique.

Tu parles de boutons donc il me semble que le traitement pourrait être uniquement numérique.
Même si l'analogique qui est "transparent" au signal permet d'avoir une programmation plus simple.
Un MCP23017 (16 bits) qui peut se configurer aussi bien en entrée qu'en sortie pourrait convenir.
Un PCF 8574 (8 bits) pourrait aussi convenir (plus délicat à utiliser).
Ces deux circuits (I2C donc 2 GPIOs utilisés au total) étant dotés d'une fonction pouvant générer une interruption quand une entrée change d'état (appui sur un bouton).

Voir aussi :

Pour t'aider à trouver la meilleure solution, il faut que tu expliques exactement ce que tu veux faire.
Si c'est demandé dans le message épinglé en tête de forum, ce n'est pas par hasard.

Bonsoir 68tjs

Si j'ai proposé le MCP23017, c'est parce que toutes les données sont dans le post #1, il suffit de le lire, ainsi que le programme?
Que te faut-il de plus?

Cordialement
jpbbricole

Pourquoi le choix d'un multiplexeur analogique ?
--> choix volontaire et argumenté ?
--> choix parce que visionnage d'une vidéo "Youtube"?

A quoi servent les boutons ?

Le programme doit-il réagir à un changement d'état d'un bouton ou se contente-t-il de lire leur état quand il en a besoin ?

C'est le cahier des charges et s'il n'y a pas de cahier des charges, on va voir les nouvelles demandes être précisées au fur et à mesure des échanges comme cela arrive souvent.
Avec une possible remise en cause des solutions proposées qui se révèlent être incompatible avec les demandes complémentaires.

Salut
seraient pas à l'envers, tes diodes ?

"Pourquoi ne pas s'orienter du côté du MCP23017"
Salut
et pourquoi pas du tlc5947 ?

c'est comme ça chez texas

de 2 à 6v

Le tic5947 n'a rien à voire avec le MCP23017, c'est un PWM LED driver?

Cordialement
jpbbricole

Ils ne sont pas bien orientés et servent à isoler la sortie d'un multiplexeur de celle des trois autres.
Maintenant que je revois le schéma proposé, je vois qu'il manque une résistance pullup ou pulldown pour un fonctionnement correct dans toutes les E/S des 4 intégrées.
Maintenant, je préfère mettre des résistances de pulldown 5K de la broche e/s à GND et l'autre borne de tous les boutons-poussoirs au lieu d'aller à GND, comme ils sont dans le schéma, connectez-les à 5V et dans le code au lieu de lire un LOW lire un HIGH.
Les salutations.

Oui, et un seul suffirait :


Sur cette image il y a une matrice de 16 boutons. En utilisant les 16 lignes du MCP23017 il est possible de monter à 64.
Il existe une librairie :
https://github.com/joeyoung/arduino_keypads/tree/master/Keypad_MC17
Exemple avec 64 touches :
https://github.com/joeyoung/arduino_keypads/blob/master/Keypad_MC17/examples/HelloKpd64_MC17/HelloKpd64_MC17.ino

Ensuite, il existe une solution bien plus intéressante que câbler 50 boutons :

ou :

ça je savais
ce que tu ne savais pas, c'est que j'ai un pupitre avec 80 leds et 50 boutons commandés par des tlc5947, et que ça marche très bien depuis des années ...

Bonsoir trimarco232

Donc tu lis tes 50 boutons aussi avec des tlc5947?

Cordialement
jpbbricole

de la manière suivante :

  • chaque bouton (ou inter) est relié à une sortie d'un tlc5947
  • les 2èmes bornes de chaque bouton sont reliées ensembles, et a une résistance de pullup, et à une entrée de l'arduino
  • on "allume" les boutons à tour de rôle, cycliquement, rapidement, en mettant une sortie d'un tlc5947 , geyscale à fond, ce qui revient à mettre cette sortie à LOW ; si le bouton correspondant à cette sortie est appuyé, l'entrée de l'arduino est low

on aurait pu faire pareil avec un 74hc595, mais il aurait fallu mettre des diodes, pour éviter des cc si 2 boutons sont appuyés simultanément ; l'avantage du tlc5947, c'est que ses sorties sont en source de courant, ce qui ressemble ici à de l'open drain : pas besoin de diode
l'inconvénient c'est qu'il faut pour chaque bouton envoyer 12bits sur le spi, et aussi un sentiment d'être + pervers que génial ...

Salut à tous et merci pour vos conseille.

J'ai réussi a intègre les multiplexer dans mon projet.

Je vous remercie tous.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.