tastiera a membrana con shift register

Salve a tutti , ho collegato una tastiera 4x4 a membrana su ingressi e uscite di due shift register quindi seguendo il concetto di funzionamento di molti esempi già esistenti in rete sono nella situazione attuale ,
da premettere che non utilizzo nessuna libreria e quindi tramite sketch controlo lo stato dei bit alti uno x uno sull'uscita dello shift a cui sono collegate le line di colonna e in ingresso su altro shift le 4 collegate in ingresso per le righe . Tutto funziona ma trovo difficoltà nel trovare una soluzione software per far si che alla pressione venga memorizzato un numero e venga riconosciuto il rilascio dello stesso .
Mi spiego meglio , premo il tasto uno e x controllare lo stato uso il monitor seriale ,su monitor viene scritto uno fin tanto che non rilascio . Quello che vorrei capire è come faccio a far comparite soltanto una volta il numero uno anche tenedo premuto il tasto ?
Inserisco linea di sketch x mostrarvi come riconosco la pressione del tasto ;

if ((valore == 16 && valorepul == 2 )){
numero = 1;
Serial.println ("tasto1");
}

dove valore è il dato seriale inviato per le colonne e valorepul è il riconoscimento del tasto premuto in ingresso allo shift .

ciao
posta tutto lo sketch, comunque dovresti mettere una condizione di uscita e fare qualcosa di simile al blink senza delay() dove si confronta il valore iniziale con quello successivo

Ciao , questo è lo sketch , spero non sia troppo incasinato dato che lo uso per fare anche altre cose con un display ,

#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 bianco                      //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;
int pausa =1;
int pausa1 = 60;
int pausa2 = 30;
int pausa3 = 500;
//---------------------------------------------------------------------------------
int valoreled =0;
int valoreledvecchio = 0;
int valorepul =0;
int valorepulvecchio = 0;
int valorepul2 = 0;
int valorepulvecchio2 = 0;
int valorepul3 = 0;
int valorepulvecchio3 = 0;
int valorepul4 = 0;
int valorepulvecchio4 = 0;
byte potenza = 2;
int valore = 16;
int valore1 = 1;
int valore2 =32;
int valore3 =1;
int stato = 1;


int numero =0;
int vecchionumero=0;

byte on[8] = {14,31,31,31,14,14,14,14};
byte off[8] = {14,17,17,17,10,10,10,14};
       




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



lcd.createChar (1,on);
lcd.createChar (0,off);
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() {
 

  
  
 tempo = millis ();
 digitalWrite (plpul,LOW);
 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 (tempo-trascorso>pausa){ 
     trascorso = tempo ;
        valore = potenza * valore; 
         if ( valore == 256 ) valore = 16;
        }
         if (tempo-trascorso1>pausa1){ 
          trascorso1 = tempo ;
           valore1 = potenza * valore1;
            if ( valore1 == 256 ) valore1 = 1;
        }
       
       
      
       
  digitalWrite (pl_led,LOW);
       digitalWrite (pl_led,HIGH);
        shiftOut (dataled,clockled,MSBFIRST,valore);
         shiftOut (dataled,clockled,MSBFIRST,valore1);
       
     
      
       if ((valore == 16 && valorepul == 2 )){
        Serial.println ("tasto3");
       }
       
     if ((valore == 32&&valorepul == 2)){
         Serial.println ("tastoA");
       }
       if ((valore == 64 && valorepul == 2)){
         Serial.println ("tasto1");
     
         
        }
   
       if ((valore == 128 && valorepul == 2)){
         Serial.println ("tasto2");
       }
      
       if ((valore == 16 && valorepul == 4)){
         Serial.println ("tasto6");
       }
       if ((valore == 32 && valorepul == 4)){
         Serial.println ("tastoB");
       }
         if ((valore == 64 && valorepul == 4)){
         Serial.println ("tasto4");
       }  
       if ((valore == 128 && valorepul == 4)){
         Serial.println ("tasto5");
       }
       if ((valore == 16 && valorepul == 8)){
         Serial.println ("tasto9");
       }
       if ((valore == 32 && valorepul == 8)){
         Serial.println ("tastoC");
       }
       if ((valore == 64 && valorepul == 8)){
         Serial.println ("tasto7");
       }
      if ((valore == 128 && valorepul == 8)){
         Serial.println ("tasto8");
       } 
       if ((valore == 16 && valorepul == 16)){
         Serial.println ("tasto#");
       }
       
       if ((valore == 32 && valorepul == 16)){
         Serial.println ("tastoD");
       }
       if ((valore == 64 && valorepul == 16)){
         Serial.println ("tasto*");
       }
       if ((valore == 128 && valorepul == 16)){
         Serial.println ("tasto0");
       
       }
     if (valore1 == 1) {  
lcd.setCursor (0,0);
lcd.write (byte(1));
}
else {
 lcd.setCursor (0,0);
lcd.write (byte(0));
}
if (valore1 == 2) {  
lcd.setCursor (2,0);
lcd.write (byte(1));
}
else {
 lcd.setCursor (2,0);
lcd.write (byte(0));
}
if (valore1 == 4) {  
lcd.setCursor (4,0);
lcd.write (byte(1));
}
else {
 lcd.setCursor (4,0);
lcd.write (byte(0));
}
if (valore1 == 8) {  
lcd.setCursor (6,0);
lcd.write (byte(1));
}
else {
 lcd.setCursor (6,0);
lcd.write (byte(0));
}
if (valore1 == 16) {  
lcd.setCursor (8,0);
lcd.write (byte(1));
}
else {
 lcd.setCursor (8,0);
lcd.write (byte(0));
}
if (valore1 == 32) {  
lcd.setCursor (10,0);
lcd.write (byte(1));
}
else {
 lcd.setCursor (10,0);
lcd.write (byte(0));
}
if (valore1 == 64) {  
lcd.setCursor (12,0);
lcd.write (byte(1));
}
else {
 lcd.setCursor (12,0);
lcd.write (byte(0));
}
if (valore1 == 128) {  
lcd.setCursor (14,0);
lcd.write (byte(1));
}
else {
 lcd.setCursor (14,0);
lcd.write (byte(0));
 }
}
    
  
 
 
 


   
   

   
   
    
    

    
    
    
    
 
       
 

[code]

[/code]

appena riesco provo a studiarmi il codice, ma se hai una tastiera 4x4 non ti basta un solo shiftin il byte che leggi lo confronti con un vettore 2*8 in cui inserisci la combinazione di bit e il tasto corrispondente

Inserisci lo sketch nei tag "code", prima che passi di qui un mod e ti tiri dietro qualcosa :wink:

ho utilizzato un hc595 per le 4 colonne ed un hc165 per le righe , lo sketch anche se scritto un po in maniera confusionale ti assicuro che funziona , infatti premendo un qualsiasi tasto viene stampato a monitor il tasto corrispondente , il problema è come chiedevo nel primo post che vorrei fosse riconosciuta la pressione del tasto e venisse stampato una sola volta a monitor , poi al rilascio solo in caso di nuova pressione un nuovo risultato stampato su monitor.

Avevo creato una variabile dove all'interno della condizione cambiava di stato e quindi in parte avevo risolto solo che trovandosi all'interno dell' if alla pressione non mi stampava più nulla . Ti faccio un esempio :

if ((valore == 16 && valorepul == 2 && vecchiostato == 0 )){
vecchiostato = bitRead (valore,4);
Serial.println ("tasto3");

succede infatti che inizialmente vecchistato che si trova a 0 dopo la pressione diventa alto ma e quindi mi stampa solo una volta su monitor "tasto3" ma poi al rilascio l'istruzione essendo racchiusa nell' if non ritorna più a zero , ne ho provate un sacco , ora ho la testa piena di confusione e magari la soluzione è cosi semplice .

Aggiungi in coda all'if un secondo if che ti resetta lo stato della variabile quando lasci andare il pulsante :wink:

Tipo, a grandi linee:

...
if ((statovariabile == 0) && (pulsante == 1))
  { 
    statovariabile = 1
    tue istruzioni
  }
if ((statovariabile == 1) && (pulsante == 0))
  { 
    statovariabile = 0
  }

Il secondo if viene eseguito solo una volta quando rilasci il pulsante, proprio come il primo viene eseguito solo una volta quando lo premi :wink:

OK :wink: , Grazie mille mi è stato di aiuto.