Demux sn 74hc138, augmenter nombre de sortie de arduino nano

Bonsoir
J'aimerais augmenter le nombre de sortie de mon arduino nano, pour sa j'ai utilisé un démultiplexeur le Sn74hc138, c'est un démultiplexeur qui prend 3pin de mon arduino et qui me donne 8 en sortie du démultiplexeur , petit problème sa ne fonctionne pas! quand je televerse mon programme pour sélectionner la 1ere sortie par exemple pour allumer la 1ere led. Je vais televerser un ( 0 0 0) ou =>
digitalWrite(2,LOW)
digitalWrite(3,LOW)
digitalWrite(4,LOW)
Mais sa ne fonctionne pas . J'aimerais un petit coup de main.
Voila le code que j'ai utilisé et le shema sur isis pour illustré le branchement que jai réalisé réellement, merci

int Outputs[] = {9,10,11};
void setup()
{
pinMode (Outputs[0], OUTPUT);
pinMode (Outputs[1], OUTPUT);
pinMode (Outputs[2], OUTPUT);
}
void loop()
{
for (byte binary =0;binary<=7; binary++) { BinaryOut(binary); delay(500); } } void BinaryOut(byte number) { for (int i =0;i<3;i++) { if (bitRead(number, i)==1){ digitalWrite(Outputs[i], HIGH); }else{ digitalWrite(Outputs[i], LOW); } } }

20210315_230100.jpg

20210315_230100.jpg

Bonsoir

où est le programme complet ?
(ici on n’aime pas les bouts de code, le problème se situant bien souvent dans la partie non communiquée)
dans le cas présent on n’a pas l’assurance ques les 3 bornes aient été déclarées préalablement en sorties.

où est le schéma montrant le câblage du démultiplexeur et des DEL ?

(voir la Règle du Forum Francophone pour voir quelles infos fournir, comment publier le code.

c’est à lire ompérativement en arrivant sur ce forum)

Oui désolé ,Voila j'ai modifier le poste j'espère que vous avez tout maintenant

sur mon smartphone :

Schéma , bof… sur ce schéma Proteus pas très net on ne voit pas :
-le sens de câblage des Leds
-à quelle tension est relié le point commun des résistances en série avec les DEL

Code : mal formaté à partir de loop() tout est sur une seule ligne !!!

l’IDE Arduino possède une commande permettant de bien indenter le code avant publication.

Si vous avez un bon programme qui marche et un shema adéquat sa serai super

Je pense que tu t'est trompé de forum. Celui ci a pour but d'aider les personnes à réaliser leur rêve Arduino. Il doit exister des forums pour demander des réalisations toutes faites.

Pour rester sur ce forum, les règles ne sont pas établies pour enquiquiner le monde, mais parce que si le post ne respecte pas ces règles, bien souvent on ne peut pas répondre.

Dans ton post, il manque un schéma complet avec les alimentations, et un programme lisible
Dans le code, il y a une erreur sur la dernière ligne juste avant l'accolade.

Restons calme, il y a un peu trop de coup de lune en ce moment.

Déjà il nous semble de bon ton quand on arrive sur un forum, quel qu’il soit, d’en lire les règles.

Ensuite il faut bien que tu comprennes que l’aide à distance impose d’être rigoureux sinon cela part en eau de boudin. Malheureusement nous avons trop d’expérience “eau de boudin” , c’est pour cela que maintenant nous réagissons immédiatement.

Dans les messages que l’on demande de lire il y a le conseil d’utiliser le tuto d’Eskimon : il est parfait pour débuter car il traite de l’apprentissage de la programmation et plus rare dans les tutos de l’électronique des composants.
A quoi sert le meilleur programme si le coté électronique est foireux ?

A cela nous ajoutons souvent qu’il faut utiliser la liaison série comme une aide à la mise au point.
Si tu places des serial.print à quelques endroit clés tu peux t’assurer que le programme se déroule bien comme tu le voulais.
A ce sujet évite le serial.begin(9600) qui dans certains cas peut ralentir ton programme et utilise au minimum serial.begin(115200). 9600 bauds c’était dans le temps jadis et pour parcourir des centaines de mètres. Dans le cas présent la liaison série fait la distance entre le microcontrôleur atmega328p et le ch340 c’est dire 1 ou 2 cm.

Quant au schéma électrique il est vrai que nous préférons un vrai schéma même dessiné à la main (avec une règle quand même). Au bout de 40 ans d’électronique professionnelle je faisais toujours mes pré-schémas à la main car cela permet de mieux “sentir” ce que l’on fait.
Cliquer déposer va trop vite et ne permet pas d’être multi-taches, c’est à dire réfléchir tout en dessinant.

Le 74138 n'est pas fait pour réaliser des sorties logiques permanentes. C'est un circuit purement combinatoire qui est employé en général pour générer des "chip select" sur des boitiers périphériques à un micro. Donc pour avoir 8 sorties sur un arduino avec trois lignes "OUTPUT" il vaut mieux prendre autre chose, genre série de 8 bascules D avec entrée série.

Cela dit, pour allumer des LED, avec le schéma proposé, c'est possible, y compris pour afficher une combinaison visuelle de plusieurs LED, en jouant sur le multiplexage et la persistance rétinienne. Mais, pour aller plus loin dans ce sens, il faudrait nous montrer un schéma avec le sens de montage de la diode (au lieu d'un point noir) et le raccordement du commun (en haut à droite), car sur le schéma on ne voit même pas si c'est raccordé au Vcc ou au Gnd.

Après, une fois le schéma correct, il faudra faire un programme qui boucle sur les 8 sorties, avec une fréquence de raffraichissement d'ensemble de l'ordre de 200 Hz, et ce n'est pas quelque chose de simpliste pour débutant.

Si la commande de DEL est dans le contexte de l'autre fil initié par @samiz14, (éclairage d'une es marches d'un escalier) l'idée du démultiplexeur (1 parmi n) est défendable....... une solution parmi d'autres.

(Si les deux fils sont liés mieux vaudrait éviter le saucissonnage et les fusionner pour ne pas faire perdre de temps aux uns et aux autres)

al1fch:
Si la commande de DEL est dans le contexte de l'autre fil initié par @samiz14, (éclairage d'une es marches d'un escalier) l'idée du démultiplexeur (1 parmi n) est défendable....... une solution parmi d'autres.

Oui si une seule LED parmi 8 doit être allumée. Si on veut en allumer deux ou plusieurs en même temps, on reporte sur le logiciel la complexité. D'ailleurs dans cette dernière hypothèse il faudrait rajouter aux trois bits de sélection un bit de validation des sorties, non câblé sur le schéma.

Tiens, just for fun, en supposant que l’alimentation des LED est au Vcc et qu’on rajoute une sortie à l’arduino pour commander (à 0) la sélection du boitier.

// Programme d'affichage d'un octet sur 8 leds à travers un 74HC138

// three address lines on 74138
#define ADDR0 9
#define ADDR1 10
#define ADDR2 11
#define SELECT 8 // chip select 74138 : to light on a LED

volatile unsigned char etatLeds ; // etat des Leds en binaire
unsigned char compteur8 ;

void setup(){
  
  //set pins as outputs
  pinMode(ADDR0, OUTPUT);   
  pinMode(ADDR1, OUTPUT);   
  pinMode(ADDR2, OUTPUT);
  pinMode(SELECT, OUTPUT);
  cli();//stop interrupts
//set timer0 interrupt at 1000 Hz
  TCCR0A = 0;// set entire TCCR2A register to 0
  TCCR0B = 0;// same for TCCR2B
  TCNT0  = 0;//initialize counter value to 0
  // set compare match register for 1000 hz increments
  OCR0A = 250 ; // = (16*10^6) / (1000*64) - 1 (must be <256)
  // turn on CTC mode
  TCCR0A |= (1 << WGM01);
  TCCR0B = 0x04 ; // prescaler = 64
  // enable timer compare interrupt
  TIMSK0 |= (1 << OCIE0A);
  etatLeds = 0 ;
  compteur8 = 0 ;
  sei();//allow interrupts
}

ISR(TIMER0_COMPA_vect){//timer0 interrupt 1000 Hz 
  digitalWrite (SELECT, HIGH) ; // déselection sorties 74HC138, toutes LED éteintes
  // Positionnement des adresses adr0-adr3
  switch (compteur8) {
    case 0 : 
      digitalWrite(ADDR2, LOW) ; digitalWrite(ADDR1, LOW) ; digitalWrite(ADDR0, LOW) ; 
      break ;
    case 1 : case 3 : case 5 : case 7 :
      digitalWrite(ADDR0, HIGH) ; 
      break ;
    case 2 : case 6 : 
      digitalWrite(ADDR1, HIGH) ; digitalWrite(ADDR0, LOW) ; 
      break ;
    case 4 : 
      digitalWrite(ADDR2, HIGH) ; digitalWrite(ADDR1, LOW) ; digitalWrite(ADDR0, LOW) ; 
      break ;
    default :
      while (true) ; // Harakiri
  }
  if (etatLeds & (0x01 << compteur8)) digitalWrite (SELECT, LOW) ; // Allumage une LED pendant 1 ms
  compteur8 += 1 ; if (compteur8 > 7) compteur8 = 0 ;
  // Le cycle se reproduit à une fréquence de 125 Hz, suffisant pour la persistance rétinienne
}

void loop(){
  // fait prendre les 256 états possibles aux 8 LED
  cli () ; etatLeds += 1 ; sei () ;
  delay (100) ;
}

Je ne l’ai pas testé mais je pense que ça doit le faire.

pfff, même pas de fading :grin:

trimarco232:
pfff, même pas de fading :grin:

Sur la condition de selection du boitier, donc allumage de la LED, rajouter :
if (random (0, 100) <= fading
Et régler la variable fading entre 1 et 100. Pour des valeurs faibles cela doit donner un effet de déco de Noël sympa.

Si on revenait au début ?
Augmenter le nombre de sorties ?

Compléments indispensables :

  1. Il ne faut que des sorties ? Il n’y aura jamais besoin qu’une “sortie” se retrouve positionnée en “entrée” ?
    Techniquement on parle d’accès unidirectionnel ou bidirectionnel.

  2. Si on ajoute N sorties, il y aura-t-il qu’une seule sortie active à la fois, ou plusieurs sorties actives simultanément ?

  3. Courant max demandé aux sorties. Oui cela à son importance certains CI ne pouvant pas délivrer plus que 2 ou 5 mA.

Tant que @samiz14 ne répond pas à ces questions on discute dans le vide.

Solutions possibles

  • démultiplexeur 1 vers N en général 3 fils de commande → unidirectionnel → une seule sortie active à la fois
  • registre à décalage : 2 fils strictement nécessaires plus 1 souhaitable (latch) → unidirectionnel → plusieurs sorties actives à la fois
  • expenseur I2C ( deux fils) ou SPI (2 fil+ 1 fil par esclave) —> il existe des modèles bidirectionnel ou unidirectionnel → plusieurs sorties actives à la fois.

Samiz14 à toi de dire ce que tu veux faire.

Désolé pour les informations manquantes, mon projet ce porte sur un allumage d'escaliers successive ( il ya pas mal d'exemple sur YouTube) et je voudrai le faire en commandant ces lumières (une vingtaine sa peut etre des spots ou ruban led en (12V) ) avec 2 boutton poussoir situer en bas et en haut des escaliers , pour allumer et éteindre en meme temps , et 2 detecteur de passage pour que si on passe sur l'un des deux détecteur (du haut ou du bas)sa s'allume , et après un passage devant le deuxième détecteur sa s'éteint (avec une priorité pour le bouton poussoir qui allume et éteint ) .
j'ai utiliser un atmega328p qui est limité en nombre de sortie , pour régler le problème des nombres de sortie manquantes jai pensé a utiliser un demux mais ils n'est pas adapté a mon cas d'escalier lumineux et a mon programme, si il ya une autres alternative a me conseiller je suis preneur, mon second problème c'est que j'aimerais faire un système pour la configuration du nombre de marche ( par exemple je pourrais brancher 1,2 ,3 ...15 etc lumières avec ce circuit sans qu'il y'est de retard car si je déclare 20 sortie (marche) et que je branche 10 sortie en laissant les 10 autres sorties en cercuit ouvert on vas constater une perte de temps lors de l'allumage de l'escalier ce qui est normale vu que j'ai déclarer 20 sortie (marche) , j'aimerais remidier a ce problème )@al1fch ma conseiller de mettre un dipswtitches pour introduire un nombre de sortie dans le programme , j'aimerai savoir si c'est la meilleure solution dans mon cas et dans ce que je cherche a faire, j'espère avoir été clair dans mes propos.
je mets aussi le code qui n'est pas finit et qui est configurer pour 10 sortie (marche), le programme a été tester il fonctionne bien mais il n'est ni finis ni optimiser en terme de nombre de lignes , j'aurais pu déclarer une variable qui change en fonction du nombre de marche voulu mais ce n'est que des testes j'attends d'avoir la finalité du programme pour l'optimiser... si vous avez d'autres astuces a me donner pour optimiser le programme ou l'ensemble de ce projet je suis preneur.
Merci d'avance.

boolean etat = false;


void setup(){
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(7, OUTPUT);
  pinMode(8, OUTPUT);
  pinMode(9, OUTPUT); 
  pinMode(10, OUTPUT);
  pinMode(11, OUTPUT);

  pinMode(A1, INPUT);
  digitalWrite(A1, HIGH);   
  pinMode(A2, INPUT_PULLUP);
  digitalWrite(A2, HIGH); 
  pinMode(A3, INPUT);
  digitalWrite(A3, HIGH);   
  pinMode(A4, INPUT_PULLUP);
  digitalWrite(A4, HIGH);     
}

void loop(){
if (digitalRead(A1) == HIGH){
  
while(  digitalRead(A1) == HIGH)
{digitalWrite(2, etat ? HIGH : LOW);}
{digitalWrite(3, etat ? HIGH : LOW);}
{digitalWrite(4, etat ? HIGH : LOW);}
{digitalWrite(5, etat ? HIGH : LOW);}
{digitalWrite(6, etat ? HIGH : LOW);}
{digitalWrite(7, etat ? HIGH : LOW);}
{digitalWrite(8, etat ? HIGH : LOW);}
{digitalWrite(9, etat ? HIGH : LOW);}
{digitalWrite(10, etat ? HIGH : LOW);}
{digitalWrite(11, etat ? HIGH : LOW);}

etat = !etat;  
             
{digitalWrite(2, etat ? HIGH : LOW);}
delay(300);
{digitalWrite(3, etat ? HIGH : LOW);}
delay(300);
{digitalWrite(4, etat ? HIGH : LOW);}
delay(300);
{digitalWrite(5, etat ? HIGH : LOW);}
delay(300);
{digitalWrite(6, etat ? HIGH : LOW);}
delay(300);
{digitalWrite(7, etat ? HIGH : LOW);}
delay(300);
{digitalWrite(8, etat ? HIGH : LOW);}
delay(300);
{digitalWrite(9, etat ? HIGH : LOW);}
delay(300);
{digitalWrite(10, etat ? HIGH : LOW);}
delay(300);
{digitalWrite(11, etat ? HIGH : LOW);}

  }
  else if (digitalRead(A2) == HIGH){
  
while(  digitalRead(A2) == HIGH)
{digitalWrite(2, etat ? HIGH : LOW);}
{digitalWrite(3, etat ? HIGH : LOW);}
{digitalWrite(4, etat ? HIGH : LOW);}
{digitalWrite(5, etat ? HIGH : LOW);}
{digitalWrite(6, etat ? HIGH : LOW);}
{digitalWrite(7, etat ? HIGH : LOW);}
{digitalWrite(8, etat ? HIGH : LOW);}
{digitalWrite(9, etat ? HIGH : LOW);}
{digitalWrite(10, etat ? HIGH : LOW);}
{digitalWrite(11, etat ? HIGH : LOW);}

    etat = !etat;    
               
{digitalWrite(2, etat ? HIGH : LOW);}
delay(300);
{digitalWrite(3, etat ? HIGH : LOW);}
delay(300);
{digitalWrite(4, etat ? HIGH : LOW);}
delay(300);
{digitalWrite(5, etat ? HIGH : LOW);}
delay(300);
{digitalWrite(6, etat ? HIGH : LOW);}
delay(300);
{digitalWrite(7, etat ? HIGH : LOW);}
delay(300);
{digitalWrite(8, etat ? HIGH : LOW);}
delay(300);
{digitalWrite(9, etat ? HIGH : LOW);}
delay(300);
{digitalWrite(10, etat ? HIGH : LOW);}
delay(300);
{digitalWrite(11, etat ? HIGH : LOW);}


  }
 else if (digitalRead(A3) == LOW){
  
while(  digitalRead(A3) == LOW)
{digitalWrite(2, etat ? HIGH : LOW);}
{digitalWrite(3, etat ? HIGH : LOW);}
{digitalWrite(4, etat ? HIGH : LOW);}
{digitalWrite(5, etat ? HIGH : LOW);}
{digitalWrite(6, etat ? HIGH : LOW);}
{digitalWrite(7, etat ? HIGH : LOW);}
{digitalWrite(8, etat ? HIGH : LOW);}
{digitalWrite(9, etat ? HIGH : LOW);}
{digitalWrite(10, etat ? HIGH : LOW);}
{digitalWrite(11, etat ? HIGH : LOW);}

    etat = !etat;      
             
{digitalWrite(2, etat ? HIGH : LOW);}
delay(300);
{digitalWrite(3, etat ? HIGH : LOW);}
delay(300);
{digitalWrite(4, etat ? HIGH : LOW);}
delay(300);
{digitalWrite(5, etat ? HIGH : LOW);}
delay(300);
{digitalWrite(6, etat ? HIGH : LOW);}
delay(300);
{digitalWrite(7, etat ? HIGH : LOW);}
delay(300);
{digitalWrite(8, etat ? HIGH : LOW);}
delay(300);
{digitalWrite(9, etat ? HIGH : LOW);}
delay(300);
{digitalWrite(10, etat ? HIGH : LOW);}
delay(300);
{digitalWrite(11, etat ? HIGH : LOW);}


  }
 else if (digitalRead(A4) == LOW){
  
while(  digitalRead(A4) == LOW)
{digitalWrite(2, etat ? HIGH : LOW);}
{digitalWrite(3, etat ? HIGH : LOW);}
{digitalWrite(4, etat ? HIGH : LOW);}
{digitalWrite(5, etat ? HIGH : LOW);}
{digitalWrite(6, etat ? HIGH : LOW);}
{digitalWrite(7, etat ? HIGH : LOW);}
{digitalWrite(8, etat ? HIGH : LOW);}
{digitalWrite(9, etat ? HIGH : LOW);}
{digitalWrite(10, etat ? HIGH : LOW);}
{digitalWrite(11, etat ? HIGH : LOW);}

    etat = !etat;         
          
{digitalWrite(2, etat ? HIGH : LOW);}
delay(300);
{digitalWrite(3, etat ? HIGH : LOW);}
delay(300);
{digitalWrite(4, etat ? HIGH : LOW);}
delay(300);
{digitalWrite(5, etat ? HIGH : LOW);}
delay(300);
{digitalWrite(6, etat ? HIGH : LOW);}
delay(300);
{digitalWrite(7, etat ? HIGH : LOW);}
delay(300);
{digitalWrite(8, etat ? HIGH : LOW);}
delay(300);
{digitalWrite(9, etat ? HIGH : LOW);}
delay(300);
{digitalWrite(10, etat ? HIGH : LOW);}
delay(300);
{digitalWrite(11, etat ? HIGH : LOW);}


  }
  
 }

Apparemment il a abandonné l'idée du 74HC138. C'eut été cool qu'il nous en informât.

système pour la configuration du nombre de marche

Il y a souvent une solution hard, une soft et une usine à gaz.

Pour la solution hard, les dipswitch, est ce que je pense de mieux, mais cela utilise des entrées.
Pour l’usine à gaz, il y a un ordinateur plus performant, une deuxième carte avec un dialogue série…
Pour la solution soft, je te propose cette méthode

Si on met une broche non connectée en sortie et que l’on impose un niveau (on ne peut d’ailleurs pas faire autrement), en passant la broche en entrée, l’état va être conservé pendant un certain temps (3 secondes chez moi). C’est le principe des mémoires dynamiques, celles des gros ordis.

Si au contraire un Mosfet qui commande une marche est présent sur la sortie, avec une résistance Grille Source pas trop élevée (100ko par exemple), en mettant un état haut puis en passant la pin en entrée, on lira très rapidement un état bas.

Il est donc possible de lire la présence d’un Fet donc d’une marche, ou son absence. Les marches sont testées une fois dans le setup, on mémorise le nombre de marches pour la suite.

Soit le programme qui fait un test sur la pin n°2:

const byte pin = 2;

void setup()
{
  Serial.begin(115200);
}

void loop()
{
  // Mettre la broche à l'état haut en sortie
  Serial.println("Etat haut");
  pinMode(pin,OUTPUT);
  digitalWrite(pin,HIGH);
  // Mettre la pin en entrée
  pinMode(pin,INPUT);
  // Lire la valeur pendant 10s
  for (int i=0; i<10; i++) 
  {
    delay(1000);
    Serial.println(digitalRead(pin));
  }

  
  // Mettre la broche à l'état bas en sortie
  Serial.println("Etat bas");
  pinMode(pin,OUTPUT);
  digitalWrite(pin,LOW);
  // Mettre la pin en entrée
  pinMode(pin,INPUT);
  // Lire la valeur pendant 10s
  for (int i=0; i<10; i++)
  {
    delay(1000);
    Serial.println(digitalRead(pin));
  }
}

Il teste combien de secondes la sortie ne change pas. Il faut ajuster le temps en fonction de la résistance extérieure

Ceci ne fonctionne que si la carte pilote les transistors, pas si on utilise un demultiplexeur.

n'est pas adapté a mon cas d'escalier lumineux et a mon programme, si il ya une autres alternative a me conseiller je suis preneur

un-eclairage-descalier-leds
Le SX1509 gère le PWM tout seul, l'allumage peut donc être progressif.
OK jusqu'à 16 marches, ce qui correspond au nombre de marches d'un escalier standard. Au delà il n'est pas interdit d'en utiliser deux, ou de brancher 2 marches par sortie en haut et en bas.

vileroi:
Il y a souvent une solution hard, une soft et une usine à gaz.

Pour la solution hard, les dipswitch, est ce que je pense de mieux, mais cela utilise des entrées.

Merci pour ton explication je pense que je vais opté pour le commutateur dip sa ma l'air plus possible et moin complex avec mon niveau (deja que je sais pas encore comment l'intégrer et le faire marcher ) je vais chercher la dessus alors

hbachetti:
un-eclairage-descalier-leds
Le SX1509 gère le PWM tout seul, l'allumage peut donc être progressif.

Mais pour ce que je voudrai faire c'est pas un allumage progressif de la lumière mais augmenter le nombre de Outputs de mon atmega328 pour qu'avec tous les composant que je vais reliés avoir 20 Outputs pour relier mes leds pour les allumer successivement avec un delay entre eux