Difficulté avec shiftOut(ds_Pin, shcp_Pin, LSBFIRST, xxx) sur 74HC595

Bonjour à tous.
Comme évoqué dans dans ma présentation, je travaille sur une horloge à eau type Bernard Gitton.
Je souhaite allumer une (ou plusieurs) LED correspondant à chaque heure, dizaine de minutes et unités de minutes, soit une LED indiquant l'heure (et il y en a 12 possibles ) une indiquant la dizaine de minute (6 possibles) et une indiquant la minute paire (soient 6 possibles). Donc 12+6+6 = 24 LED à allumer potentiellement
Je compte utiliser trois 74HC595 en cascade.
J'utilise à ce stade une carte équivalent Uno chinoise, UN (pour travailler par étape) chips 74HC595, une breadbord avec les cables, leds et resitences qui vont bien. Ce montage est fonctionnel, j'arrive à reproduire les exemples simples trouvés par ci et par la sur ce forum.
Mon probléme, c'est que quand , dans mon code, j'utilise " shiftOut(ds_Pin, shcp_Pin, LSBFIRST, xxx)" les LEDs s'allument pas du tout comme escompté !!!
Voici le code utilisé :`
Mon raisonnement est de lire l'heure sur un module RTC3231 et de la traduire en une chaine de 0 ou 1 correspondants aux leds à allumer , idem pour la dizaine de minute puis les unités de minutes.
Je concaténe ensuite ces trois chaines de 0 et 1 pour l'envoyer dans le(s) registre à décalage.
(pour mon apprentissage j'utilise une heure fixe ( 1 heure) et une unité de minute fixe ( 6 minutes) mais pas de dizaine de minutes) fixées par variables)


```cpp

int stcp_Pin = 4;
int shcp_Pin = 5;
int ds_Pin = 6;
int Heure = 1;          // designe les heures relevees sur RTC
int DizaineMinute = 0;  // designe les dizaines de minutes relevees sur RTC
int Minute = 6;         // designe les minutes relevees sur RTC

String AllumeLedHeure;          // designe la partie de message concernant les heures
String AllumeLedDizaineMinute;  // designe la partie de message concernant les dizaines de minute
String AllumeLedMinute;         // designe la partie de message concernant les unites minutes
String AllumeLED;               // designe le message transmis au 74HC595 qui est la concatenation des 3 parties de message

void setup() {
  Serial.begin(9600);  //Démarre le port communication
  pinMode(stcp_Pin, OUTPUT);
  pinMode(shcp_Pin, OUTPUT);
  pinMode(ds_Pin, OUTPUT);
}

void loop() {
  /////////////////////////////////////TRAITEMENT DES HEURES
  switch (Heure) {
    case 0:
    case 12:
      AllumeLedHeure = "0000";
      Serial.print("AllumeLedHeure ");
      Serial.print("\t");
      Serial.print(AllumeLedHeure);
      Serial.print("\t");
      break;
    case 1:
    case 13:
      AllumeLedHeure = "1111";
      Serial.print("AllumeLedHeure ");
      Serial.print("\t");
      Serial.print(AllumeLedHeure);
      Serial.print("\t");
      break;
    case 2:
    case 14:
      AllumeLedHeure = "0010";
      Serial.print("AllumeLedHeure ");
      Serial.print("\t");
      Serial.print(AllumeLedHeure);
      Serial.print("\t");
      break;
    case 3:
    case 15:
      AllumeLedHeure = "0001";
      Serial.print("AllumeLedHeure ");
      Serial.print("\t");
      Serial.print(AllumeLedHeure);
      Serial.print("\t");
      break;
    case 4:
    case 16:
      AllumeLedHeure = "0001";
      Serial.print("AllumeLedHeure ");
      Serial.print("\t");
      Serial.print(AllumeLedHeure);
      Serial.print("\t");
      break;
    case 5:
    case 17:
      AllumeLedHeure = "0001";
      Serial.print("AllumeLedHeure ");
      Serial.print("\t");
      Serial.print(AllumeLedHeure);
      Serial.print("\t");
      break;
    case 6:
    case 18:
      AllumeLedHeure = "0001";
      Serial.print("AllumeLedHeure ");
      Serial.print("\t");
      Serial.print(AllumeLedHeure);
      Serial.print("\t");
      break;
    case 7:
    case 19:
      AllumeLedHeure = "0001";
      Serial.print("AllumeLedHeure ");
      Serial.print("\t");
      Serial.print(AllumeLedHeure);
      Serial.print("\t");
      break;
    case 8:
    case 20:
      AllumeLedHeure = "0001";
      Serial.print("AllumeLedHeure ");
      Serial.print("\t");
      Serial.print(AllumeLedHeure);
      Serial.print("\t");
      break;
    case 9:
    case 21:
      AllumeLedHeure = "0001";
      Serial.print("AllumeLedHeure ");
      Serial.print("\t");
      Serial.print(AllumeLedHeure);
      Serial.print("\t");
      break;
    case 10:
    case 22:
      AllumeLedHeure = "0001";
      Serial.print("AllumeLedHeure ");
      Serial.print("\t");
      Serial.print(AllumeLedHeure);
      Serial.print("\t");
      break;
    case 11:
    case 23:
      AllumeLedHeure = "0001";
      Serial.print("AllumeLedHeure ");
      Serial.print("\t");
      Serial.print(AllumeLedHeure);
      Serial.print("\t");
      break;
    default:
      Serial.print("PROBLEME HEURE ");
  }
  /////////////////////////////////////TRAITEMENT DES DIZAINES DE MINUTES
  switch (DizaineMinute) {
    case 0:
      AllumeLedDizaineMinute = "0000";
      Serial.print("AllumeLedDizaineMinute ");
      Serial.print("\t");
      Serial.print(AllumeLedDizaineMinute);
      Serial.print("\t");
      break;
    case 1:
      AllumeLedDizaineMinute = "0100";
      Serial.print("AllumeLedDizaineMinute ");
      Serial.print("\t");
      Serial.print(AllumeLedDizaineMinute);
      Serial.print("\t");
      break;
    case 2:
      AllumeLedDizaineMinute = "0010";
      Serial.print("AllumeLedDizaineMinute ");
      Serial.print("\t");
      Serial.print(AllumeLedDizaineMinute);
      Serial.print("\t");
      break;
    case 3:
      AllumeLedDizaineMinute = "0001";
      Serial.print("AllumeLedDizaineMinute ");
      Serial.print("\t");
      Serial.print(AllumeLedDizaineMinute);
      Serial.print("\t");
      break;
    case 4:
      AllumeLedDizaineMinute = "0000";
      Serial.print("AllumeLedDizaineMinute ");
      Serial.print("\t");
      Serial.print(AllumeLedDizaineMinute);
      Serial.print("\t");
      break;
    case 5:
      AllumeLedDizaineMinute = "0000";
      Serial.print("AllumeLedDizaineMinute ");
      Serial.print("\t");
      Serial.print(AllumeLedDizaineMinute);
      Serial.print("\t");
      break;
    default:
      Serial.print("PROBLEME dizaine Minute ");
  }

  /////////////////////////////////////TRAITEMENT DES UNITES DE MINUTES
  switch (Minute) {
    case 0:
    case 1:
      AllumeLedMinute = "0000";
      Serial.print("AllumeLedMinute ");
      Serial.print("\t");
      Serial.print(AllumeLedMinute);
      Serial.print("\t");
      break;
    case 2:
    case 3:
      AllumeLedMinute = "0100";
      Serial.print("AllumeLedMinute ");
      Serial.print("\t");
      Serial.print(AllumeLedMinute);
      Serial.print("\t");
      break;
    case 4:
    case 5:
      AllumeLedMinute = "0010";
      Serial.print("AllumeLedMinute ");
      Serial.print("\t");
      Serial.print(AllumeLedMinute);
      Serial.print("\t");
      break;
    case 6:
    case 7:
      AllumeLedMinute = "0101";
      Serial.print("AllumeLedMinute ");
      Serial.print("\t");
      Serial.print(AllumeLedMinute);
      Serial.print("\t");
      break;
    case 8:
    case 9:
      AllumeLedMinute = "0000";
      Serial.print("AllumeLedMinute ");
      Serial.print("\t");
      Serial.print(AllumeLedMinute);
      Serial.print("\t");
      break;
    default:
      Serial.print("PROBLEME Minute ");
  }

  //AllumeLED = "0B" + AllumeLedHeure + AllumeLedDizaineMinute + AllumeLedMinute; //Youpi ca marche !!!
  AllumeLED = "0B" + AllumeLedHeure + AllumeLedMinute;  //"0B" +
  digitalWrite(stcp_Pin, LOW);
  shiftOut(ds_Pin, shcp_Pin, LSBFIRST, "AllumeLED");
  //shiftOut(ds_Pin, shcp_Pin, LSBFIRST, 0B11111111 );
  digitalWrite(stcp_Pin, HIGH);
  Serial.print("AllumeLED ");
  Serial.print("\t");
  Serial.println(AllumeLED);
  delay(2000);
}

Cette variable "AllumeLed", bien que correspondant à ce que je veux, comme l'indique la lecture du port série, n'est probablement pas lue comme moi par le langage c++ ce qui provoque le bazar dans l'affichage des LEDs.
Pouvez vous SVP m'aider à comprendre et donc résoudre cette difficulté.
Merci d'avance.
Denis

Bonjour,
La valeur à envoyer dans shiftout n'est pas une chaine de caractère mais du binaire.
Quand tu fais "0B" + AllumeLedHeure + AllumeLedMinute, ça ne transforme pas du tout la chaîne en binaire.

La notation 0bxxxxxxx n'est valable que dans le source.

Bonjour arduinoded

Pour aller dans le même sens que @kamill, voici ce que attend shiftout:


val attend une variable de 8 bits (uint8_t ou byte) pas une chaine de caractères.

Je n'ai pas le matériel pour essayer, mais fais ces essais:
Au lieu de faire:
shiftOut(ds_Pin, shcp_Pin, LSBFIRST, "AllumeLED");
essaies une de ces 3 options
shiftOut(ds_Pin, shcp_Pin, LSBFIRST, Heure);
ou
shiftOut(ds_Pin, shcp_Pin, LSBFIRST, DizaineMinute);
ou
shiftOut(ds_Pin, shcp_Pin, LSBFIRST, Minute);

A+
Cordialement
jpbbricole

Bonjour et merci pour vos réponses.
J'ai compris qu'il ne faut pas confondre chaine de caractéres et chaine binaire.
J'ai cherché dans ce forum et ailleurs comment convertir une chaine de caractéres en binaire mais n'ai rien trouvé.
Cela est il possible ?
J'ai remarqué que le 4 eme argument de shiftout peut etre de format DECIMAL : si je mets 255 qui équivaut à 11111111 en binaire toutes les led s'allument, de meme 170 (10101010 en binaire) allume une led sur deux. Ya t'il un moyen (une fonction ou autre) de convertir ma chaine de caractères (0 et 1) concaténés en un nombre décimal ?
Merci de votre aide


```cpp

int stcp_Pin = 4;
int shcp_Pin = 5;
int ds_Pin = 6;
int Heure = 1;          // designe les heures relevees sur RTC
int DizaineMinute = 0;  // designe les dizaines de minutes relevees sur RTC
int Minute = 6;         // designe les minutes relevees sur RTC

int AllumeLedHeure;          // designe la partie de message concernant les heures
int AllumeLedDizaineMinute;  // designe la partie de message concernant les dizaines de minute
int AllumeLedMinute;         // designe la partie de message concernant les unites minutes
int AllumeLED;
int AllumeLEDDecimal;               // designe le message transmis au 74HC595 qui est la concatenation des 3 parties de message
//String toto;
//int Compteur;

void setup() {
  Serial.begin(9600);  //Démarre le port communication
  pinMode(stcp_Pin, OUTPUT);
  pinMode(shcp_Pin, OUTPUT);
  pinMode(ds_Pin, OUTPUT);
}

void loop() {
  /////////////////////////////////////TRAITEMENT DES HEURES
  switch (Heure) {
    
    case 1:
    case 13:
       AllumeLedHeure = 170;
      Serial.print("AllumeLedHeure ");
      Serial.print("\t");
      Serial.print(AllumeLedHeure);
      Serial.print("\t");
      break;
    
    default:
      Serial.print("PROBLEME HEURE ");
  }
  /////////////////////////////////////TRAITEMENT DES DIZAINES DE MINUTES
  
  /////////////////////////////////////TRAITEMENT DES UNITES DE MINUTES
  switch (Minute) {
    
    case 6:
    AllumeLedMinute = 0B0101;
      Serial.print("AllumeLedMinute ");
      Serial.print("\t");
      Serial.print(AllumeLedMinute);
      Serial.print("\t");
      break;
    default:
      Serial.print("PROBLEME Minute ");
  }

 

  digitalWrite(stcp_Pin, LOW);
  //shiftOut(ds_Pin, shcp_Pin, LSBFIRST,  129);
  shiftOut(ds_Pin, shcp_Pin, LSBFIRST, AllumeLedHeure );
  digitalWrite(stcp_Pin, HIGH);
  Serial.print("AllumeLED ");
  Serial.print("\t");
  Serial.print(AllumeLED);
  Serial.print("\t");
  //Serial.print("(AllumeLedHeure<<4 + AllumeLedMinute) ");
  Serial.println("\t");
  //Serial.println((AllumeLedHeure<<4 + AllumeLedMinute));
  delay(2000);
}

La question serait plutôt pourquoi passes-tu par une chaîne de caractères, cela ne présente aucun intérêt?
Ta RTC DS3231 va te fournir heures et minutes sous forme de nombres pas sous forme de chaînes de caractères.

Bonsoir arduinoded

Oui, c'est juste as tu essayé ce que je t'ai proposé au post#3, tu verra que comme le dit @fdufnews, il n'y a pas besoin de passer par une chaine de caractères.

Cordialement
jpbbricole

Merci pour la réponse.
J'ai 12 led qui correspondent aux heures, 6 led qui correspondent aux dizaines de minute et 6 led qui indiquent les unités de minute (que je compte de deux en deux).
Si la RTC me donne par exemple 6 heures, 3 dizaines de minutes et 4 unités de minutes.
Comment je fais pour allumer la 6 eme led de la colonne des heures, la 3 eme de la colonne des dizaines de minute et la 4 eme led de la colonne des unités de minutes ?
J'ai prévu de le faire avec 3 74HC595 en cascade, en envoyant la valeur binaire 000001000000001000000100, parce que c'est ce que j'ai compris de mes lectures de débutant. Mais s'il y a des meilleures solutions, je suis preneur !

Donc tu envoies une valeur binaire cela n'a donc rien à voir avec une chaîne de caractères.
Pour déplacer un 1 d'un certain nombre de pas tu fais un décalage
Si heure = 6, pour placer un 1 dans le bit 6 d'une variable que l'on appellera colHeure tu fais
colHeure = 1 << (heure - 1)
en toute rigueur il faudrait faire

if (heure == 0){
     colHeure = 0;
} else {
    colHeure = 1 << (heure - 1);
}

Bonjour !
Un grand merci pour cette info sur la manipulation des bits !!!
J'avais vu cette fonction de décalage lors de mes recherches, mais n'avait pas compris son fonctionnement (à mon age, les neurones ont parfois du mal à se connecter ...), mais avec l'exemple que tu donnes, c'est clair !!!.
J'en ai profité pour regarder d'autres fonctions comme bitWrite() que j'ai utilisée quand je devais modifier 2 bits dans un même octet.
Je mets donc le code obtenu, auquel je dois ajouter maintenant la gestion de la RTC.
Encore merci à tous et notamment à fdufnews qui m'a mis sur les rails.


int stcp_Pin = 4;       //L CLOK  
int shcp_Pin = 5;       //CLOCK
int ds_Pin = 6;         //SER IN
int Heure = 4;          // designe les heures relevees sur RTC
int DizaineMinute = 5;  // designe les dizaines de minutes relevees sur RTC
int Minute = 9;         // designe les minutes relevees sur RTC
 
int Message3 ;  // designe le message transmis au 74HC595 quiconcerne les dizaines de minutes 4 a 5 et les unites de minute
int Message2 ;  // designe le message transmis au 74HC595 quiconcerne les heures 8 a 11 et les dizaines de minutes 0 a 3
int Message1 ;  // designe le message transmis au 74HC595 quiconcerne les heures 0 a 7

void setup() {
Serial.begin(9600);  //Démarre le port communication
pinMode(stcp_Pin, OUTPUT);
pinMode(shcp_Pin, OUTPUT);
pinMode(ds_Pin, OUTPUT);
}

void loop() {
  if (Heure <8 ){
      if (Heure == 0){
        Message3 = 0b00000001;} 
       else Message3 =1 << (Heure);}  //viens changer l'octet concerné en fonction de l'heure pour le message 3
switch (Heure){
 case 8 : 
    Message3 == 0b00000000;           // si l'heure est supérieure ou égale à 8 met le message3 à 0
    Message2 = 0b00000000;            // si l'heure est supérieure ou égale à 8, crée le message 2 initialisé à 0
    bitWrite(Message2,0, 1);          //viens changer l'octet concerné en fonction de l'heure pour le message 2
    break;
    case 9 : 
    Message3 == 0b00000000;
    Message2 = 0b00000000;            //viens changer l'octet concerné en fonction de l'heure pour le message 2
    bitWrite(Message2,1, 1);          //viens changer l'octet concerné en fonction de l'heure pour le message 2
    break;
    case 10 : 
    Message3 == 0b00000000;
    Message2 = 0b00000000;
    bitWrite(Message2,2, 1);          //viens changer l'octet concerné en fonction de l'heure pour le message 2
    break;
    case 11 : 
    Message3 == 0b00000000;
    Message2 = 0b00000000;
    bitWrite(Message2,3, 1);          //viens changer l'octet concerné en fonction de l'heure pour le message 2
    break;
    }
switch(DizaineMinute){
case 0 : 
    bitWrite(Message2,4, 1);          //viens changer l'octet concerné en fonction de la dizaine de minutes pour le message 2
    break;
    case 1 : 
    bitWrite(Message2,5, 1);          //viens changer l'octet concerné en fonction de la dizaine de minutes pour le message 2
    break;
    case 2 : 
    bitWrite(Message2,6, 1);          //viens changer l'octet concerné en fonction de la dizaine de minutes pour le message 2
    break;
    case 3 : 
    bitWrite(Message2,7, 1);          //viens changer l'octet concerné en fonction de la dizaine de minutes pour le message 2
    break;
    case 4 : 
    bitWrite(Message1,0, 1);          //viens changer l'octet concerné en fonction de la dizaine de minutes pour le message 1
    break;
    case 5 : 
    bitWrite(Message1,1, 1);          //viens changer l'octet concerné en fonction de la dizaine de minutes pour le message 1
    break;
}
 switch (Minute){
//Message1 = 0b00000000;
Serial.print(Message1, BIN);          //viens changer l'octet concerné en fonction de la minute pour le message 1
  case 0 :
  case 1 :
  bitWrite(Message1,2, 1);          //viens changer l'octet concerné en fonction de la minute pour le message 1
  break;
  case 2 :
  case 3 :
  bitWrite(Message1, 3, 1);         //viens changer l'octet concerné en fonction de la minute pour le message 1
  break;
  case 4 :
  case 5 :
  bitWrite(Message1, 4, 1);         //viens changer l'octet concerné en fonction de la minute pour le message 1
  break;
  case 6 :
  case 7 :
  bitWrite(Message1, 5, 1);         //viens changer l'octet concerné en fonction de la minute pour le message 1
  break;
  case 8 :
  case 9 :
  bitWrite(Message1, 6, 1);         //viens changer l'octet concerné en fonction de la minute pour le message 1
  break;
}
Serial.print("Message1 ");
  Serial.print(Message1, BIN);
   Serial.print("\t");
      Serial.print("Message2 BIN ");
      Serial.print(Message2, BIN);
      Serial.print("\t");
      Serial.print("Message3 BIN ");
      Serial.print(Message3, BIN);
  Serial.print("\t");
  Serial.println("\t");
  digitalWrite(stcp_Pin, LOW);
  shiftOut(ds_Pin, shcp_Pin, LSBFIRST, Message3); //Envoie le message 3 dans la cascade de 74HC595
  digitalWrite(stcp_Pin, HIGH);
  delay(0000);
  digitalWrite(stcp_Pin, LOW);
  shiftOut(ds_Pin, shcp_Pin, LSBFIRST,Message2); //Envoie le message 2 dans la cascade de 74HC595
  digitalWrite(stcp_Pin, HIGH);
  delay(0000);
  digitalWrite(stcp_Pin, LOW);
  shiftOut(ds_Pin, shcp_Pin, LSBFIRST,Message1 );//Envoie le message 1 dans la cascade de 74HC595
  delay(0000);
  digitalWrite(stcp_Pin, HIGH);
  delay(2000);
  
}

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