shift register

Salve a tutti , ho collegato in cascata 3 shift register serie 74hc164 e collegandoci una serie di pulsanti ho compilato lo sketch in modo tale che alla pressione di ogniuno si abbia su monitor seriale il valore decimale dello stesso . Premendo il primo tasto collegato all'ingresso n°1 dell'ultimo shift si ha come risposta 2 ,con il secondo tasto si ha risposta 4 e così via , ora una cosa strana perchè premendo il primo tasto mi sarei aspettato come risposta 1 e non 2 . Continuando con la pressione sul secondo shift pigiando il primo tasto ho come risposta 1 poi con secondo tasto ho 2 e così via . Sul primo shift avrò di nuovo 2 come risposta alla pressione del primo tasto . ?? Centra forse qualcosa con lo scorrimento dei bit dato che sono collegati in cascata??

Quando li leggi, leggi tutti i 3 byte (24 bit) ogni volta ? … e poi li converti ? … perche’ ovviamente ogni registro ti rende un byte con valori che vanno da 00 (nessun pulsante premuto) a FF (tutti e 8 i pulsanti premuti) … :wink:

Hai uno schema elettrico o delle foto dove si vede come li hai collegati? Ci dal lo sketch? Ciao Uwe

Allora tramite sketch ho nominato i 3 shift come valorepul,valorepul2 e valorepul3 , ovviamente tutti e tre hanno una condizione simile e cioè che se premo uno qualsiasi dei tasti mi viene stampato il valore a monitor , non penso mi venga letto l’intero dato per tutti e tre gli shift simultaneamente.
Io non faccio nessuna conversione , mi viene stampato direttamente il valore in decimale su monitor seriale , il collegamento degli shift è in cascata , il clock e il latch sono in parallelo su tutti e tre mentre il pin QH pin 9 è l’uscita verso arduino e il pin 10 va al 9 del successivo .

#include <LiquidCrystal.h>
LiquidCrystal lcd (6,5,4,3,2,7);



#define dataled  10                       //filo verde                       //definisce il pin data dello shiftregister hc595 per i led(uscite)
#define clockled  8                       //filo bia                         //definisce il pin clock dello shiftregister hc595 per i led(uscite)
#define pl_led  9                         //filo blù                         //definisce il pin pl dello shiftregister hc595 per i led(uscite)

#define datapul  12                       //filo arancio                     //definisce il pin data dello shiftregister hc165 per i pulsanti(ingressi)
#define clockpul  13                      //filo verde                       //definisce il pin clock dello shiftregister hc165 per i pulsanti(ingressi)
#define plpul  11                         //filo bianco                      //definisce il pin pl dello shiftregister hc165 per i pulsanti(ingressi)


unsigned long  tempo = 0;
unsigned long  trascorso= 0;              // uso del timer interno per le pause
unsigned long  trascorso1= 0;
unsigned long  trascorso2 = 0;
unsigned long  trascorso3 = 0;
byte pausa =1;
byte pausa1 = 500;
byte pausa2 = 200;
int pausa3 = 500;


int controllo = 0;
int valorepul =0;
int valorepulvecchio = 0;
int valorepul2 = 0;
int valorepulvecchio2 = 0;
int valorepul3 = 0;
int valorepulvecchio3 = 0;

byte potenza = 2;
int valore = 16;
int valore1 = 1;


byte gruppo []= {16,32,64,128};
int stato = 0;
int stato1 = 0;
int stato2 = 0;
int stato3 = 0;
int vecchiostato = 0;
byte on[8] = {14,31,31,31,14,14,14,14};               //creazione icone lampadina su display
byte off[8] = {14,17,17,17,10,10,10,14};
byte gradi [8]= {2,5,2} ;      
float temp = 0;
int campionatura = 0;
int conteggio = 0;
float risultato =0;

void setup() {               // definizione di ingressi e uscite



lcd.createChar (1,on);
lcd.createChar (0,off);
lcd.createChar (2,gradi);
lcd.begin (20,4);





  Serial.begin (9600);
  pinMode (dataled,OUTPUT);
  pinMode (pl_led,OUTPUT);
  pinMode (clockled,OUTPUT);
  pinMode (datapul,INPUT);
  pinMode (plpul,OUTPUT);
  pinMode (clockpul,OUTPUT);
 
 
  
    digitalWrite (pl_led,LOW);                                      //settaggio degli shiftregister per le uscite a 0
      shiftOut (dataled,clockled,MSBFIRST,0);
        shiftOut (dataled,clockled,MSBFIRST,0);
      digitalWrite (pl_led,HIGH);
   
}

void loop() {
  
  temp = analogRead (A0);
    temp = (5.0 *temp *100.0 ) /1024;
    
    if (tempo-trascorso2>pausa2) {
      trascorso2=tempo;
       campionatura = campionatura + temp;
        conteggio = conteggio +1;
         if ( conteggio == 5) {
           campionatura = campionatura / 5;
            risultato = campionatura;
            conteggio = 0;
       lcd.setCursor (0,3); 
        lcd.print ("temperatura ");
         lcd.write (byte(2));
           lcd.print("C ");
            lcd.print (risultato);
            }
           }
    
    
       
     lcd.setCursor (0,2);
      lcd.print ("digit code");
      
   
   
  tempo = millis ();
  
  digitalWrite (plpul,LOW);                                           //lettura ingressi shift
  digitalWrite (plpul,HIGH);                                          
   valorepul = shiftIn (datapul,clockpul,MSBFIRST);
    valorepul2 = shiftIn (datapul,clockpul,MSBFIRST);
     valorepul3 = shiftIn (datapul,clockpul,MSBFIRST);
  
 
       if (valorepulvecchio3 != valorepul3) {                       
        valorepulvecchio3 = valorepul3;
        Serial.println (valorepul3);
        }
     
     if (valorepulvecchio2 != valorepul2) {                       
        valorepulvecchio2 = valorepul2;
        Serial.println (valorepul2);
        }
        
        if (valorepulvecchio != valorepul) {                       
        valorepulvecchio = valorepul;
        Serial.println (valorepul);
        }
        
       }
lcd.createChar (2,gradi);
lcd.begin (20,4);

Penso che il lcd.begin devi farlo prima del lcd.createChar e mettere in mezzo una delay(10);

A quale piedino del Shift Register hai collegato il primo pulsante? Ciao Uwe

angelosalvatelli:
… non penso mi venga letto l’intero dato per tutti e tre gli shift simultaneamente.

Ehm … e’ un registro SERIALE, se non leggi l’intero dato ogni singola volta, e’ ovvio che non hai il valore corretto … perche’ mentre li leggi, il contenuto dei registri precedenti viene spostato nei successivi …

Immagina una fila di 24 palline (i tuoi 3 banchi da 8 ingressi) in un tubo che non sia trasparente … se una pallina cambia colore (pulsante premuto), per sapere qual’e’, tu devi per forza farle uscire tutte quante … lo stesso succede per i registri seriali in cascata, se un pulsante del secondo o del terzo registro viene premuto, devi per forza leggere tutti e tre i bytes, mettendoli nelle tue variabili, e poi andare a leggerle per vedere quale pulsante di quale registro e’ stato premuto … inoltre, subito dopo la lettura sarebbe opportuno fare un clear di tutti i registri, per essere sicuri che la lettura successiva sia corretta … (errore mio, ho dimenticato che i 165 hanno solo l’enable, non il clear … e’ l’eta’ :P)

Inoltre, suppongo che tu stia usando degli HC165 o dei 4021, e non degli HC164 come hai scritto nel primo post, dato che i 164 se non ricordo male sono serial input parallel output, quindi registri seriali di uscita, non di ingresso … :wink:

EDIT: comunque si, come dice anche uwe, uno schema elettrico aiuterebbe parecchio a capire il tutto … almeno, di solito aiuta :wink:

ARIEDIT: a proposito, uno schema elettrico e’ una cosa tipo quella allegata, non una roba fatta con fritzing (si, lo so … sono Kattiiiivo … :stuck_out_tongue: :D)

Salve ragazzi , scusate se mi sono assentato per qualche giorno ma sono stato stimolato dalle vostre domande nel fare prima delle altre prove.
Allora ho semplificato lo sketch :

#define plpul 11
#define clockpul 13
#define datapul 12
#define plled 9
#define clockled 8
#define dataled 10


int valore = 0;
int valore1 = 0;
int uscita = 0;
int uscita1 = 0;


void setup() {
 pinMode (plpul,OUTPUT);
 pinMode (datapul,INPUT);
 pinMode (clockpul,OUTPUT);
 pinMode (plled,OUTPUT);
 pinMode (clockled,OUTPUT);
 pinMode (dataled,OUTPUT);
 Serial.begin (9600);

}

void loop() {
  digitalWrite (plpul,HIGH);
   delay (20);
    digitalWrite (plpul,LOW);
     valore = shiftIn (datapul,clockpul,MSBFIRST);
      valore1 = shiftIn (datapul,clockpul,MSBFIRST);
      
    digitalWrite (plled,LOW);
     delay (20);
      digitalWrite (plled,HIGH);
        shiftOut (dataled,clockled,MSBFIRST,uscita);
         shiftOut (dataled,clockled,MSBFIRST,uscita1);
      
      uscita = valore ;
       uscita1 = valore1;

}

Ho cambiato i 74hc165N con i cd4021BE per capire meglio anche se il problema potesse derivare da questi ultimi , niente stessa cosa .
Infatti quello che chiedo ad arduino tramite sketch è di riprodurre pari pari l’accensione di un led corrispondente alla pressione di un tasto e quello che mi succede è che premendo il primo tasto collegato al secondo shift register"4021" mi si accende il secondo led collegato al primo schift register “74hc595N”.

Per ricapitolare io ho n°2 shift register collegati in cascata per n°16 led (74hc595N) e n°2 shift register collegati in cascata per n°16 pulsanti (4021).

pulsanti.jpg

per lo shift out io uso questa sequenza

...
digitalWrite(latchPin, LOW);          //Pull latch LOW to start sending data
  shiftOut(dataPin, clockPin, MSBFIRST, B00000000);
  shiftOut(dataPin, clockPin, MSBFIRST, B00000000);
  digitalWrite(latchPin, HIGH);         //Pull latch HIGH to stop sending data
...

per lo shift in io uso questa sequenza

...
  digitalWrite(latchPinIN, HIGH);  //set it to 1 to collect parallel data, wait
  delayMicroseconds(50);     
  digitalWrite(latchPinIN, LOW); //set it to 0 to transmit data serially  
  //while the shift register is in serial mode
  //collect each shift register into a byte
  //the register attached to the chip comes in first 
  switchVar2 = shiftIn(dataPinIN, clockPinIN);//1_5
  switchVar1 = shiftIn(dataPinIN, clockPinIN);//6_10
...

Niente , purtroppo non va neanche con questa seguenza .

gli shiftin vanno messi tra digitalWrite (plled,HIGH); e digitalWrite (plpul,HIGH); hai provato a usare LSBFIRST e ad invertire l'ordine delle veriabili in cui memorizzi i byte?

un consiglio: commenta lo sketch perchè non si comprende cosa hai collegato a cosa