Go Down

Topic: 74HC595 newbie perdu (Read 3714 times) previous topic - next topic

Moilion

May 29, 2013, 05:02 pm Last Edit: May 30, 2013, 08:58 pm by Moilion Reason: 1
Bonjour, bonsoir,

Pour faire clair et ne pas offenser les personnes qui pourrait se dire encore un assisté en plus...
Je n'y connais rien et en plus le niveau d'anglais est très très bas, ça aide pas pour les tutos du net.
Ce sont mes premiers pas, en électronique, voilà comme ça vous aurez compris le niveau.

Bon, j'explique enfin mon problème d'incompréhension:

- Branchement du ShiftRegister (74HC595): ok
- Tentative de comprendre le fonctionnement depuis plus d'une semaine: BOFBOF

Après avoir trouvé le code suivant:

Quote
Code: [Select]


int SER_Pin = 8;   //pin 14 on the 75HC595
int RCLK_Pin = 9;  //pin 12 on the 75HC595
int SRCLK_Pin = 10; //pin 11 on the 75HC595

//How many of the shift registers - change this
#define number_of_74hc595s 1

//do not touch
#define numOfRegisterPins number_of_74hc595s * 8

boolean registers[numOfRegisterPins];

void setup(){
 pinMode(SER_Pin, OUTPUT);
 pinMode(RCLK_Pin, OUTPUT);
 pinMode(SRCLK_Pin, OUTPUT);

 //reset all register pins
 clearRegisters();
 writeRegisters();
}              

//set all register pins to LOW
void clearRegisters(){
 for(int i = numOfRegisterPins - 1; i >=  0; i--){
    registers[i] = LOW;
 }
}

//Set and display registers
//Only call AFTER all values are set how you would like (slow otherwise)
void writeRegisters(){

 digitalWrite(RCLK_Pin, LOW);

 for(int i = numOfRegisterPins - 1; i >=  0; i--){
   digitalWrite(SRCLK_Pin, LOW);

   int val = registers[i];

   digitalWrite(SER_Pin, val);
   digitalWrite(SRCLK_Pin, HIGH);

 }
 digitalWrite(RCLK_Pin, HIGH);

}

//set an individual pin HIGH or LOW
void setRegisterPin(int index, int value){
 registers[index] = value;
 

 
}

void loop(){
  setRegisterPin(0,HIGH);
 setRegisterPin(1,HIGH);
 setRegisterPin(2, LOW);
 setRegisterPin(3, LOW);
 setRegisterPin(4, HIGH);
 setRegisterPin(5, HIGH);
 setRegisterPin(6 ,HIGH);
 setRegisterPin(7, HIGH);
 
 
 writeRegisters();  //MUST BE CALLED TO DISPLAY CHANGES
 //Only call once after the values are set how you need.
 

} (


Ce que j'aimerais comprendre et faire, c'est de nommer les sorties du ShiftRegister afin de m'en servir comme d'une sortie digitale normale.

Comme pour allumer une led dans l'exemple blink:

exemple:

Code: [Select]
/*
 Blink
 Turns on an LED on for one second, then off for one second, repeatedly.

 This example code is in the public domain.
*/

// Pin 13 has an LED connected on most Arduino boards.
// give it a name:
int led = 13;

// the setup routine runs once when you press reset:
void setup() {                
 // initialize the digital pin as an output.
 pinMode(led, OUTPUT);    
}

// the loop routine runs over and over again forever:
void loop() {
 digitalWrite(led, HIGH);   // turn the LED on (HIGH is the voltage level)
 delay(1000);               // wait for a second
 digitalWrite(led, LOW);    // turn the LED off by making the voltage LOW
 delay(1000);               // wait for a second
}


Je ne comprends pas comment "appeler" ma sortie pour en faire ce que je veux, dès que j'appelle par exemple le setRegisterPin(3) pour le mettre en LOW, puis en HIGH ça ne fonctionne pas...



Je me rends compte de la longueur du message et m'excuse, mais pour être concret, je voudrais remplacer les sorties LEDS de ce petits code par ceux du shift register et je ne comprends pas comment.

Code: [Select]
[quote]#include "DHT.h"

#define DHTPIN 11     // sortie digitale du capteur


#define DHTTYPE DHT11   // DHT 11

int ledverte = 6; //défini le pin 6 comme étant la led verte
int ledrouge = 7; //défini le pin 7 comme étant la led rouge
int ledvertetemperature = 4;
int ledrougetemperature=3;
int ledrougemalfonction=5;
DHT dht(DHTPIN, DHTTYPE);

void setup() {
 Serial.begin(9600);
 Serial.println("DHTxx test!");

 dht.begin();
 pinMode(ledverte, OUTPUT); //défini led verte comme étant une sortie
 pinMode(ledrouge,OUTPUT);
 pinMode (ledvertetemperature,OUTPUT);
 pinMode (ledrougetemperature,OUTPUT);
 pinMode (ledrougemalfonction,OUTPUT);
}

void loop() {
 // Reading temperature or humidity takes about 250 milliseconds!
 // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
 float h = dht.readHumidity();
 float t = dht.readTemperature();

 // check if returns are valid, if they are NaN (not a number) then something went wrong!
 if (isnan(t) || isnan(h)) {
   Serial.println("Failed to read from DHT");
    digitalWrite (ledrougemalfonction,HIGH);
 delay(100);
 digitalWrite (ledrougemalfonction,LOW);
 delay(100);
 digitalWrite (ledrouge,HIGH);
 delay(100);
 digitalWrite (ledrouge,LOW);
 delay(100);
 digitalWrite (ledverte,HIGH);
 delay (100);
 digitalWrite (ledverte,LOW);
 delay(100);
 digitalWrite(ledvertetemperature,HIGH);
 delay(100);
 digitalWrite(ledvertetemperature,LOW);
 delay(100);
 digitalWrite(ledrougetemperature,HIGH);
 delay(100);
 digitalWrite(ledrougetemperature,LOW);
 delay(100);

 
 } else {
   Serial.print("Humidity: ");
   Serial.print(h);
   Serial.print(" %\t");
   Serial.print("Temperature: ");
   Serial.print(t);
   Serial.println(" *C");
   
 }
 
 //changer les valeurs de h pour le résultat a obtenir
 


 
 
 
 if (h>=50){
 digitalWrite(ledverte, HIGH);
 digitalWrite(ledrouge,LOW);
 
 }else{
   digitalWrite (ledverte, LOW);
   digitalWrite (ledrouge, HIGH);
   delay(700);
   digitalWrite (ledrouge,LOW);
   delay(700);
}
if (t>=28) {
  digitalWrite(ledvertetemperature,LOW);
  digitalWrite(ledrougetemperature,HIGH);
  delay(700);
  digitalWrite(ledrougetemperature,LOW);
  delay(700);
}

else {
  digitalWrite(ledvertetemperature,HIGH);
  digitalWrite(ledrougetemperature,LOW);}
 
}


 
[/quote]


Si une âme charitable pouvait m'aider, je lui serais réellement reconnaissant.
Merci d'avance et encore désolé du pavé.






haifger

Salut,

Ton code « trouvé » (où ?) n'est pas vraiment optimisé, mais il n'y a pas de raison pour que ça ne fonctionne pas... as-tu bien pensé à appeler writeRegisters(); après ton  setRegisterPin(3, LOW); pour « enregistrer » les changements dans le registre ? Sinon c'est un peu normal que ça ne fonctionne pas.

Ensuite, pour allez plus loin, il te faudra lire ceci http://skyduino.wordpress.com/2013/04/05/tuto-le-bitwise-pour-les-nuls/ (ou autre tuto sur le même sujet), ça d'évitera d'utiliser 8 octets pour stocker des données qui tiennent dans 1 seul... :)

Moilion

Le code est une compilation de plein de bouts de codes trouvés sur le net, il fonctionne, à force d'essais erreurs :smiley-red:

Merci, je m'attelle à la lecture de ton lien dès que je suis de retour à la maison.
dès que j'appelle le writeRegisters();si je me rappelle bien, j'ai pas le programme près de moi, il me dit qu'il y a trop de définition pour lui, enfin c'est ce que je comprends avec le peu d'anglais que je maîtrise.


haifger

Ah oui d'accord... alors là il va nous falloir le message d'erreur exact, on ne risque pas d'être très efficaces autrement :)

Moilion

dès que je suis à la maison je note le message...
je devrais avoir un arduino de poche  XD

68tjs

Quote
Tentative de comprendre le fonctionnement depuis plus d'une semaine: BOFBOF

http://blog.matael.org/writing/arduino-et-registres/

Moilion

#6
May 29, 2013, 09:10 pm Last Edit: May 30, 2013, 09:03 pm by Moilion Reason: 1

Quote
Tentative de comprendre le fonctionnement depuis plus d'une semaine: BOFBOF

http://blog.matael.org/writing/arduino-et-registres/


Je pense avoir saisi cet affaire de bits, enfin, je dis bien je pense, si je pars de l'exemple de ce lien,j'arrive donc à quelque chose comme cela:

Code: [Select]
[quote]#define SHIFT 8
#define LATCH 9
#define DATA 10
int const ON=HIGH;
int const OFF=LOW;

// Table des trucs à afficher (1 = led allumée)
const byte SortieLed[8] = {
   B00000001,
   B00000010,
   B00000100,
   B00001000,
   B00010000,
   B00100000,
   B01000000,
   B10000000};

int time_delay = 500; // Delay de base

void setup()
{
   // On déclare les pins vers le 74HC595 en sortie
   pinMode(SHIFT, OUTPUT);
   pinMode(LATCH, OUTPUT);
   pinMode(DATA, OUTPUT);
}

[/quote]  

pour le setup ce doit_être bon, puisque j'ai uniquement changé qu'un mot du code original, maintenant pour le void loop cela se corse...

Je recopie cette partie qui je pense dis au shift register de "bloquer les sorties"

[quote]void loop()
{
   int i;
   // On boucle sur le tableau char
   for (i = 0; i < 8; i++) {
       digitalWrite(LATCH, LOW);  // bloque la recopie
       // On balance la donnée dans le premier étage
       shiftOut(DATA, SHIFT, MSBFIRST, SortieLed[i]);
       digitalWrite(LATCH, HIGH);// recopie
   
   }
}[/quote]



Mais comment dois-je changer l'état de la sortie, quelle commande entrer pour mon exemple de température du code ci dessus (ou la led verte s'allume si la température est bonne?


J'aurais donc avec mon shift register quelque chose comme:

Code: [Select]
[code][quote]#include "DHT.h"

#define DHTPIN 11     // sortie digitale du capteur
#define DHTTYPE DHT11   // DHT 11


#define SHIFT 8
#define LATCH 9
#define DATA 10
int const ON=HIGH;
int const OFF=LOW;

// Table des trucs à afficher (1 = led allumée)
const byte SortieLed[8] = {
   B00000001,
   B00000010,
   B00000100,
   B00001000,
   B00010000,
   B00100000,
   B01000000,
   B10000000};
   
int const ledverte = B00000001;
int const ledrouge = B00000010;
int const ledvertetemperature = B00000100;
int const ledrougetemperature = B00001000;
int const ledrougemalfonction = B00010000;

DHT dht(DHTPIN, DHTTYPE);  
 


void setup()
{
   // On déclare les pins vers le 74HC595 en sortie
   pinMode(SHIFT, OUTPUT);
   pinMode(LATCH, OUTPUT);
   pinMode(DATA, OUTPUT);
   
   
   
 Serial.begin(9600);
 Serial.println("DHTxx test!");

 dht.begin();
 pinMode(ledverte, OUTPUT); //défini led verte comme étant une sortie
 pinMode(ledrouge,OUTPUT);
 pinMode (ledvertetemperature,OUTPUT);
 pinMode (ledrougetemperature,OUTPUT);
 pinMode (ledrougemalfonction,OUTPUT);
}


void loop()
{
 
 
   int i;
   // On boucle sur le tableau char
   for (i = 0; i < 8; i++) {
       digitalWrite(LATCH, LOW);  // bloque la recopie
       // On balance la donnée dans le premier étage
       shiftOut(DATA, SHIFT, MSBFIRST, SortieLed[i]);
       digitalWrite(LATCH, HIGH);// recopie
       // On contrôle le potar pour déterminer le delay
     
   
 // Reading temperature or humidity takes about 250 milliseconds!
 // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
 float h = dht.readHumidity();
 float t = dht.readTemperature();

 // check if returns are valid, if they are NaN (not a number) then something went wrong!
 if (isnan(t) || isnan(h)) {
   Serial.println("Failed to read from DHT");
    digitalWrite (ledrougemalfonction,HIGH);
 delay(100);
 digitalWrite (ledrougemalfonction,LOW);
 delay(100);
 digitalWrite (ledrouge,HIGH);
 delay(100);
 digitalWrite (ledrouge,LOW);
 delay(100);
 digitalWrite (ledverte,HIGH);
 delay (100);
 digitalWrite (ledverte,LOW);
 delay(100);
 digitalWrite(ledvertetemperature,HIGH);
 delay(100);
 digitalWrite(ledvertetemperature,LOW);
 delay(100);
 digitalWrite(ledrougetemperature,HIGH);
 delay(100);
 digitalWrite(ledrougetemperature,LOW);
 delay(100);

 
 } else {
   Serial.print("Humidity: ");
   Serial.print(h);
   Serial.print(" %\t");
   Serial.print("Temperature: ");
   Serial.print(t);
   Serial.println(" *C");
   
 }
 
 //changer les valeurs de h pour le résultat a obtenir
 


 
 
 
 if (h>=50){
 digitalWrite(ledverte, HIGH);
 digitalWrite(ledrouge,LOW);
 
 }else{
   digitalWrite (ledverte, LOW);
   digitalWrite (ledrouge, HIGH);
   delay(700);
   digitalWrite (ledrouge,LOW);
   delay(700);
}
if (t>=28) {
  digitalWrite(ledvertetemperature,LOW);
  digitalWrite(ledrougetemperature,HIGH);
  delay(700);
  digitalWrite(ledrougetemperature,LOW);
  delay(700);
}

else {
  digitalWrite(ledvertetemperature,HIGH);
  digitalWrite(ledrougetemperature,LOW);}
 
}

   }

[/quote]
[/code]
Ce qui ne fonctionne évidemment pas ...

68tjs

J'ai toujours dit que je ne rentrerai pas dans le code n'étant pas assez compétant pour cela.
Néanmoins un rapide survol m'a montré que tu n'as pas prévu d'afficher des information de débogage donc tu ne peut pas vérifier ce que fait ton programme.

Place aux endroits stratégiques des Serial.print("Message qui va bien") cela devrait te permettre de trouver par toi même un certain nombre d'erreurs.

Moilion

#8
May 30, 2013, 11:45 am Last Edit: May 30, 2013, 09:05 pm by Moilion Reason: 1
Je pense avoir trouvé, effectivement je n'appelais pas les fonctions pour écrire et supprimer l'état de la led.

En repartant de la première version ça donne ça, et la led clignote:

Code: [Select]
[quote]int SER_Pin = 8;   //pin 14 on the 75HC595
int RCLK_Pin = 9;  //pin 12 on the 75HC595
int SRCLK_Pin = 10; //pin 11 on the 75HC595

//How many of the shift registers - change this
#define number_of_74hc595s 1

//do not touch
#define numOfRegisterPins number_of_74hc595s * 8

boolean registers[numOfRegisterPins];

void setup(){
 pinMode(SER_Pin, OUTPUT);
 pinMode(RCLK_Pin, OUTPUT);
 pinMode(SRCLK_Pin, OUTPUT);

 //reset all register pins
 clearRegisters();
 writeRegisters();
}              

//set all register pins to LOW
void clearRegisters(){
 for(int i = numOfRegisterPins - 1; i >=  0; i--){
    registers[i] = LOW;
 }
}

//Set and display registers
//Only call AFTER all values are set how you would like (slow otherwise)
void writeRegisters(){

 digitalWrite(RCLK_Pin, LOW);

 for(int i = numOfRegisterPins - 1; i >=  0; i--){
   digitalWrite(SRCLK_Pin, LOW);

   int val = registers[i];

   digitalWrite(SER_Pin, val);
   digitalWrite(SRCLK_Pin, HIGH);

 }
 digitalWrite(RCLK_Pin, HIGH);

}

//set an individual pin HIGH or LOW
void setRegisterPin(int index, int value){
 registers[index] = value;
 

 
}

void loop(){
 writeRegisters();
  setRegisterPin(0,LOW);
  delay (100);
     clearRegisters;
     writeRegisters();
  setRegisterPin(0,HIGH);
  delay (100);
  clearRegisters;
 setRegisterPin(1,LOW);
 setRegisterPin(2, LOW);
 setRegisterPin(3, LOW);
 setRegisterPin(4, LOW);
 setRegisterPin(5, LOW);
 setRegisterPin(6 ,LOW);
 setRegisterPin(7, LOW);
 
 
 writeRegisters();  //MUST BE CALLED TO DISPLAY CHANGES
 //Only call once after the values are set how you need.
 
 
  clearRegisters;
 
}

[/quote]

A présent, vu les remarques, je vais tenter de passer les sorties en (b00000001,b00000010,...)

Moilion

#9
May 30, 2013, 08:52 pm Last Edit: May 30, 2013, 09:07 pm by Moilion Reason: 1
Dans ma tentative d'utiliser les bits (sans jeu de mots  :0), je tombe sur un os (toujours pas de jeu de mots ( :0):


Code: [Select]
[quote]
//installation des broches allant du 75HC595 à l'arduino
int SER_Pin = 8;   //pin 14 on the 75HC595
int RCLK_Pin = 9;  //pin 12 on the 75HC595
int SRCLK_Pin = 10; //pin 11 on the 75HC595


//Nombre de Registre - change this
#define number_of_74hc595s 1


// Table des trucs à afficher (1 = led allumée)
const byte SortieLed[8] = {
 B00000001,
 B00000010,
 B00000100,
 B00001000,
 B00010000,
 B00100000,
 B01000000,
 B10000000};

int time_delay = 500; // Delay de base


void setup(){
 pinMode(SER_Pin, OUTPUT);
 pinMode(RCLK_Pin, OUTPUT);
 pinMode(SRCLK_Pin, OUTPUT);
 
 
//reset des sortiesLed
clearSortieLed();
writeSortieLed();
}

//Mise des sorties à l'état OFF
void clearSortieLed(){
 for(int i = SortieLed - 1; i >=  0; i--){
    SortieLed = LOW;
 }[/quote]


J'ai le message d'erreur suivant:

invalid conversion from 'constant byte*' to'int'
Donc, si je comprends bien, il me dit que j'essaye de changer une valeur constante, et que c'est là mon erreur, mais je ne comprends pas comment alors "éteindre ma sortie"...

J'ai bien lu quelques trucs sur le net ou on parle de mask mais je n'y comprends rien de rien...

fdufnews

Code: [Select]
void clearSortieLed(){
  for(int i = SortieLed - 1; i >=  0; i--){
     SortieLed = LOW;
  }

Je ne comprends pas très bien où tu veux en venir mais en tout cas ce code ne peut pas fonctionner.
SortieLed est un tableau. Tu ne peux donc pas l'utiliser comme tu le fais.
Soit tu utilises le pointeur SortieLed et à ce moment là tu accèdes aux éléments du tableau avec *
Code: [Select]
  maValeur = *SortieLed;
tu peux même faire une boucle
Code: [Select]
ptr= SortieLed;
i=0
{
    maValeur = *ptr;
    ptr++;
    ........
}while(++i<8)

Soit tu utilises un index
Code: [Select]
for (i=0; i<8;i++){
   maValeurSortieLed[i];
   .......
}

Moilion

aie aie aie.....

Difficile de comprendre, donc, SortieLed est bien un tableau comprenant la valeur des bytes (ici allumé), si j'appelle la SortieLed1 par exemple, ma lampe située en b00000010 sur mon shift register va s'allumer.

Ce que j'ai essayé de faire, c'est une fonction clearSortieLed qui éteint ma led, et une fonction writeSortieLed qui me permette d'allumer une led que je choisis dans le tableau.

Mon niveau est plus bas que les pâquerettes...

Je remercie la patience des gens qui me donnent des coups de pouces ;) 

fdufnews

Quelque chose comme ça devrait faire l'affaire
setOuput indique quelle sortie on change
writeRegisters assure le transfert dans le registre
Dans setup il faut appeler writeRegisters pour mettre les sorties à 0

Code: [Select]
byte etatReg=0;   // <--- variable globale

const byte LedVerte=0; // définition d'une sortie du registre à décalage
const byte LedOrange=1;
const byte LedRouge=2;

/*
Si on doit changer plusieurs sorties en même temps
on peut appeler setOuput plusieurs fois de suite
on ne lance qu'une fois writeRegisters
*/

/* setOutput(byte pin, byte state)
       Positionne la sortie n° pin du registre à la valeur state
   state = 0 on éteind
   state <> 0 on allume
*/
void setOutput(byte pin, byte state){
byte mask;

mask=1 << pin; // décale le bit à la position occupée par la sorie à changer
if (state){ // si state est différent de zéro on allume
etatReg |= mask;
}else{ // si state==0 on éteind
etatReg &= ~mask;
}
writeRegisters(etatReg)
}

// writeRegisters(byte valeur)
Transfère valeur dans un registre à décalage
Note: on suppose qu'il n'y a qu'un registre à décalage
donc la boucle va de 0 à 7
*/
void writeRegisters(byte valeur){
byte tampon;

  tampon = valeur;
  digitalWrite(RCLK_Pin, LOW);

  for(int i = 7; i >=  0; i--){
    digitalWrite(SRCLK_Pin, LOW);

    digitalWrite(SER_Pin, tampon);
    digitalWrite(SRCLK_Pin, HIGH);
tampon >>= 1;

  }
  digitalWrite(RCLK_Pin, HIGH);

}

Code non testé mais l'idée est là

Moilion

#13
May 31, 2013, 01:44 pm Last Edit: May 31, 2013, 06:03 pm by Moilion Reason: 1
Merci beaucoup.

J'ai un problème (et oui encore)  :smiley-red:

donc voici le code pas d'erreur signalée par le soft:



//installation des broches allant du 75HC595 à l'arduino
int SER_Pin = 8;   //pin 14 on the 75HC595
int RCLK_Pin = 9;  //pin 12 on the 75HC595
int SRCLK_Pin = 10; //pin 11 on the 75HC595





byte etatReg=0;   // <--- variable globale

const byte LedVerte=B00000001; // définition d'une sortie du registre à décalage
const byte LedOrange=B00000010;
const byte LedRouge=B00000100;

/*
   Si on doit changer plusieurs sorties en même temps
   on peut appeler setOuput plusieurs fois de suite
   on ne lance qu'une fois writeRegisters
*/

/* setOutput(byte pin, byte state)
      Positionne la sortie n° pin du registre à la valeur state
      state = 0 on éteind
      state <> 0 on allume
*/
void setOutput(byte pin, byte state){
   byte mask;
   
   mask=1 << pin; // décale le bit à la position occupée par la sorie à changer
   if (state){      // si state est différent de zéro on allume
      etatReg |= mask;
   }else{         // si state==0 on éteind
      etatReg &= ~mask;
   }
   writeRegisters(etatReg);
}

// writeRegisters(byte valeur)
//Transfère valeur dans un registre à décalage
//   Note: on suppose qu'il n'y a qu'un registre à décalage
//   donc la boucle va de 0 à 7

void writeRegisters(byte valeur){
byte tampon;

 tampon = valeur;
 digitalWrite(RCLK_Pin, LOW);

 for(int i = 7; i >=  0; i--){
   digitalWrite(SRCLK_Pin, LOW);

   digitalWrite(SER_Pin, tampon);
   digitalWrite(SRCLK_Pin, HIGH);
   tampon >>= 1;

 }
 digitalWrite(RCLK_Pin, HIGH);

}

void setup(){
 pinMode(SER_Pin, OUTPUT);
 pinMode(RCLK_Pin, OUTPUT);
 pinMode(SRCLK_Pin, OUTPUT);
}

void loop(){
 
 setOutput (LedVerte,0);
 delay (500);
 writeRegisters;
setOutput (LedVerte,1);
 delay (500);
 writeRegisters;
 setOutput (LedOrange,1);
 writeRegisters;
 



Mais voilà ce qui se passe lors du branchement:

Toutes les leds des sorties clignotent avec une intensité lumineuse très basse à peine perceptible, enfin là j'exagère un peu, mais la Led n'éclaire pas comme d'habitude (testé avec plusieurs diodes)...



edité: je m'excuse, je ne m'en étais pas rendu compte

fdufnews

Ton code est illisible.
Lorsque tu utilises la balise code, il ne faut pas mettre d'autre mise en forme toutes les balises sont ignorées.

Go Up