problema con arduino e keypad 4x4

ciao a tutti oggi ho fatto (o meglio modificato) uno sketch che mi permette di rilevare i tasti schiacciati dal keypad ed in base al tadto schiacciato arduino modifica una variabile e la continua a stampare sulla seriale il problema è che sulla seriale vedo sempre 0 ed anche se schiaccio i tasti la variabile non cambia
dove ho sbagliato?
:frowning:

/* @file CustomKeypad.pde
#include <Keypad.h>
int time;
const byte ROWS = 4; //four rows
const byte COLS = 4; //four columns
//define the cymbols on the buttons of the keypads
char hexaKeys[ROWS][COLS] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'#','0','*','D'}
};
byte rowPins[ROWS] = {2, 3, 4, 5}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {6, 7, 8, 9}; //connect to the column pinouts of the keypad

//initialize an instance of class NewKeypad
Keypad customKeypad = Keypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS); 
int alt;
void setup(){
  Serial.begin(9600);
}
void loop(){
  char customKey = customKeypad.getKey();
   
    if(customKey==1){
       alt=1000;
    }
     if(alt==2){
       alt=2000;
    }
Serial.println(alt);
  
}

ricorda che in C il significato di

2

è diverso da

'2'

e sarebbe diverso da

"2"

quindi quando fai il confronto magari fallo come salvato nell'array e non col numero puro :wink:

Come dice superlol la libreria ti rende un codice del carattere non un numero percui devi fare il confronto col carattere "1" e non col numero 1.
Il secondo errore é

if(alt==2){
       alt=2000;
    }

la variabile alt assume un valore indefinito dalla definizione della varabile (probabilmente il 0) e 1000 se schiacci il tasto "1".
Non diventa mai 2.

Ciao Uwe

ora si che funziona! grazie mille son osempre errori banali ma importantissimi
ora ho un altro piccolo problema voglio far lampeggiare il led con un delay della variabile alt il problema è che devo aspettare che finisca tutto il loop prima di schiacciare un altro tasto altrimenti non lo rileva in poche parole se schiaccio il tasto 1 il led lampeggia con un delay di 1000ms se schiaccio il tasto 2 il delay diventa di 2000ms il problema è che se schiaccio il tasto 2 o 1 mentre il led lampeggia esso non cambia la velocità di lampeggio solo alcune volte lo fa cioè quando il loop reinizia lo so mi spiego come un cane (o peggio)
comunque questo è lo sketch che non va

/* @file CustomKeypad.pde
|| @version 1.0
|| @author Alexander Brevig
|| @contact alexanderbrevig@gmail.com
||
|| @description
|| | Demonstrates changing the keypad size and key values.
|| #
*/
#include <Keypad.h>
int time;
const byte ROWS = 4; //four rows
const byte COLS = 4; //four columns
//define the cymbols on the buttons of the keypads
char hexaKeys[ROWS][COLS] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'#','0','*','D'}
};
byte rowPins[ROWS] = {2, 3, 4, 5}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {6, 7, 8, 9}; //connect to the column pinouts of the keypad

//initialize an instance of class NewKeypad
Keypad customKeypad = Keypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS); 
int alt;
void setup(){
  Serial.begin(9600);
  pinMode(13,OUTPUT);
}
void loop(){
  char customKey = customKeypad.getKey();
   
    if(customKey=='1'){
       alt=1000;
    }
     if(customKey=='2'){
       alt=2000;
    }
    
Serial.println(alt);
  digitalWrite(13,HIGH);
  delay(alt);
  digitalWrite(13,LOW);
  delay(alt);
}

devi usare millis()

il "multitasking" con arduino non esiste però puoi salvare il momento rispetto all'accensione in millisecondi (comando millis) per e lo salvi in una variabile di tipo usigned long (altrimenti dopo poco si azzererebbe per l'overflow mentre così dovrebbe durare oltre 50 anni se non erro) e ad ogni ciclo di loop fai un check e guardi se tra il tempo da quando è stata eseguita l'azione è passato di tanti millisecondi quanti vuoi e quindi se viene restituito vero imposti un tempo per questa azione e mandi un comando :wink:

alla fine è molto più facile di ciò che sembra, ti consiglio di cercare "arduino multitasking" in google e troverai migliaia di codici.

altrimenti ripieghi su leOS o quell'altro che non ricordo sempre fatto da leo su questo forum, (vedi sezione megatopic) che in pratica ti permette di fare una sorta di multitasking :wink:

ecco io ho questo problema - YouTube

chry2000:
ecco io ho questo problema - YouTube

ma il codice non è lo stesso, il suo sarebbe molto più facile :stuck_out_tongue:

comunque il problema l'avevamo capito (anche grazie al codice) e la soluzione te l'ho scritta sopra..

ah inoltre se la libreria che usi non implementa una cosa chiamata debounce (metti che quando schiacci legge 2 volte che hai schiacciato il pulsante) dovrai implementare anche quello nello stesso modo :wink:

sisi stavo infatti cercnado su itnernet e sto trovando parecchie cose e sto cercando di capirle
PS:quando ho inviato il post del video nn mi ero accorto della tua risposta :slight_smile:

uff non ci capisco proprio niente :frowning:
c è qualcuno che sarebbe cosi gentile da modificare lo sketch? non vi voglio chiedere la pappa pronta ma volevo capire come funzionava questa funzione

prendiamo di esempio il blinkwithoutdelay

const int ledPin =  13;      // the number of the LED pin

// Variables will change:
int ledState = LOW;             // ledState used to set the LED
long previousMillis = 0;        // will store last time LED was updated

// the follow variables is a long because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long interval = 1000;           // interval at which to blink (milliseconds)

void setup() {
  // set the digital pin as output:
  pinMode(ledPin, OUTPUT);      
}

void loop()
{
  // here is where you'd put code that needs to be running all the time.

  // check to see if it's time to blink the LED; that is, if the
  // difference between the current time and last time you blinked
  // the LED is bigger than the interval at which you want to
  // blink the LED.
  unsigned long currentMillis = millis();
 
  if(currentMillis - previousMillis > interval) {
    // save the last time you blinked the LED
    previousMillis = currentMillis;  

    // if the LED is off turn it on and vice-versa:
    if (ledState == LOW)
      ledState = HIGH;
    else
      ledState = LOW;

    // set the LED with the ledState of the variable:
    digitalWrite(ledPin, ledState);
  }
}

scorporiamo il codice in modo da capirlo per bene tutto in ogni sua parte :wink:

const int ledPin =  13;
int ledState = LOW; 
long previousMillis = 0; 
long interval = 1000;

allora in questo caso crea 4 variabili:
1 con lo stato attuale del led (HIGH acceso, LOW spento)
poi ledPin che è dove ha connesso il led
previousMillis che è il tempo rispetto all'accensione di arduino in cui ha cambiato lo stato al led per l'ultima volta
infine interval che è il tempo in millisecondi per cui vuole che il led sia acceso/spento

il setup immagino si possa saltare :wink:

ora passiamo al loop

 unsigned long currentMillis = millis();

assegna ad ogni inizio ciclo il valore di quel momento (sempre rispetto all'accensione, misurato in millisecondi) ad una variabile, infatti il ciclo ci mette del tempo ad eseguirsi sulla base di quanto "pesante" è il codice (il tempo dei loop si misura in genere in cicli di clock necessari per le istruzioni ma a noi non interessa).

quindi passiamo alla parte forte:

  if(currentMillis - previousMillis > interval) {
    previousMillis = currentMillis;  

    if (ledState == LOW)
      ledState = HIGH;
    else
      ledState = LOW;

    digitalWrite(ledPin, ledState);
  }

il primo if fa un controllo e dice "se io al tempo attuale elimino il tempo dell'ultimo cambio del led, questo è superiore all'intervallo che devo aspettare?", insomma è passato un tempo interval dall'ultima istruzione?
se si allora dobbiamo fare 3 cose:

  1. assegnare il valore attuale a previousMillis, infatti noi ora andiamo a dare un'istruzione al led quindi ora è il momento in cui è stata fatta l'ultima istruzione
previousMillis = currentMillis;
  1. cambiare lo stato alla variabile ledState che contiene come dovrebbe essere il nostro led, quindi andiamo ad invertirne il valore (se prima il led era acceso ora settiamo la variabile a spento e vice versa)
    if (ledState == LOW)
      ledState = HIGH;
    else
      ledState = LOW;
  1. andare a cambiare lo stato al led assegnandogli il valore di ledState appena cambiato
digitalWrite(ledPin, ledState);

di per se potresti fare un copia incolla del codice iniziale ma non capiresti quindi te l'ho scorporato :stuck_out_tongue:

mettiamo invece che tu voglia far lampeggiare 2 led con velocità diverse dovrai rifare lo stesso codice 2 volte (quindi avrai un tempo di delay del led 1 e uno del led 2, un check per il led 1 e uno per il led 2 ed un tempo di istruzione per il led 1 e per il led 2), con 3 led 3 volte(3 tempi di delay ecc..)

capito? :wink:

ammazza + chiari di cosi non si poteva essere ! grazie mille adesso o domani(o forse dopodomani visto che è natale :P) cercherò di modificare il codice che ho modificato
ancora grazie :slight_smile:

ho tentato a farlo con due led ma non mi viene cosa sbaglio :\

const int ledPin =  13;      

int ledState = LOW;            
long previousMillis = 0;       

long interval = 1000;     

const int ledPin2 =  5;      
int ledState2 = LOW;   
long interval2 = 500;  
long previousMillis2 = 0;   
void setup() {
  // set the digital pin as output:
  pinMode(ledPin, OUTPUT);    
 pinMode(ledPin2, OUTPUT);  
}

void loop()
{
  // here is where you'd put code that needs to be running all the time.

  // check to see if it's time to blink the LED; that is, if the
  // difference between the current time and last time you blinked
  // the LED is bigger than the interval at which you want to
  // blink the LED.
  unsigned long currentMillis = millis();
 
  if(currentMillis - previousMillis > interval) {
    // save the last time you blinked the LED
    previousMillis = currentMillis;  

    // if the LED is off turn it on and vice-versa:
    if (ledState == LOW)
      ledState = HIGH;
    else
      ledState = LOW;

    // set the LED with the ledState of the variable:
    digitalWrite(ledPin, ledState);
    
  }
    if(currentMillis - previousMillis2 > interval2) {
    // save the last time you blinked the LED
    previousMillis2 = currentMillis;  

    // if the LED is off turn it on and vice-versa:
    if (ledState2 == LOW)
      ledState2 = HIGH;
    else
      ledState2 = LOW;
}
}

chry2000:
ho tentato a farlo con due led ma non mi viene cosa sbaglio :\

const int ledPin =  13;      

int ledState = LOW;           
long previousMillis = 0;

long interval = 1000;

const int ledPin2 =  5;     
int ledState2 = LOW;   
long interval2 = 500; 
long previousMillis2 = 0;   
void setup() {
  // set the digital pin as output:
  pinMode(ledPin, OUTPUT);   
pinMode(ledPin2, OUTPUT); 
}

void loop()
{
  // here is where you'd put code that needs to be running all the time.

// check to see if it's time to blink the LED; that is, if the
  // difference between the current time and last time you blinked
  // the LED is bigger than the interval at which you want to
  // blink the LED.
  unsigned long currentMillis = millis();

if(currentMillis - previousMillis > interval) {
    // save the last time you blinked the LED
    previousMillis = currentMillis;

// if the LED is off turn it on and vice-versa:
    if (ledState == LOW)
      ledState = HIGH;
    else
      ledState = LOW;

// set the LED with the ledState of the variable:
    digitalWrite(ledPin, ledState);
   
  }
    if(currentMillis - previousMillis2 > interval2) {
    // save the last time you blinked the LED
    previousMillis2 = currentMillis;

// if the LED is off turn it on and vice-versa:
    if (ledState2 == LOW)
      ledState2 = HIGH;
    else
      ledState2 = LOW;
}
}

per forza: manca un digitalWrite sul secondo led :stuck_out_tongue:
scommetto che rimaneva spento :smiley:

ora si che va sono proprio un rimbambito xD però non capisco perchè il secondo led lampeggia una volta veloce e poi una volta più lento :\

const int ledPin =  13;      

int ledState = LOW;            
long previousMillis = 0;       

long interval = 1000;     

const int ledPin2 =  5;      
int ledState2 = LOW;   
long interval2 = 500;  
long previousMillis2 = 0;   
void setup() {
  // set the digital pin as output:
  pinMode(ledPin, OUTPUT);    
 pinMode(ledPin2, OUTPUT);  
}

void loop()
{
  // here is where you'd put code that needs to be running all the time.

  // check to see if it's time to blink the LED; that is, if the
  // difference between the current time and last time you blinked
  // the LED is bigger than the interval at which you want to
  // blink the LED.
  unsigned long currentMillis = millis();
 
  if(currentMillis - previousMillis > interval) {
    // save the last time you blinked the LED
    previousMillis = currentMillis;  

    // if the LED is off turn it on and vice-versa:
    if (ledState == LOW)
      ledState = HIGH;
    else
      ledState = LOW;

    // set the LED with the ledState of the variable:
    digitalWrite(ledPin, ledState);
    
  }
    if(currentMillis - previousMillis2 > interval2) {
    // save the last time you blinked the LED
    previousMillis2 = currentMillis;  

    // if the LED is off turn it on and vice-versa:
    if (ledState2 == LOW)
      ledState2 = HIGH;
    else
      ledState2 = LOW;
      digitalWrite(ledPin2, ledState2);
}
}

oddio così ad occhio ammetto che nel codice non sembrano esserci problemi:
un pin è collegato al pin 13 ed uno al pin 5 e il codice è corretto od almeno anche io lo farei così..

prova a spiegare meglio il problema

inotre usi le giuste resistenze tra pin e led? (sui 470 ohm in genere vanno bene)

ti giuro che non so cosa è successo! l ho lasciato attaccato 3 ore ed è andato poi tranquillamente!! ora funziona però non ho nessuna idea su come trasportare il codice sullo sketch del keypad :((((

il codice dei led è identico quindi lasci tutto invariato, e poi fai un vero copia e incolla del codice già fatto (il loop nel loop, setup nel setup e i resto nel resto :stuck_out_tongue: )
l'unica differenza è che tu al posto di interval hai val nel tuo codice :wink:

nel tuo caso val sarebbe il delay, che nel codice dei led sarebbe interval

per il resto rimane davvero identico

ho fatto questo ma non funziona lo so che sto rompendo troppo perchè sbaglio sempre? :frowning:

/* @file CustomKeypad.pde
|| @version 1.0
|| @author Alexander Brevig
|| @contact alexanderbrevig@gmail.com
||
|| @description
|| | Demonstrates changing the keypad size and key values.
|| #
*/
#include <Keypad.h>        
long previousMillis = 0;       
long interval = 1000;         
long interval2 = 500;  
long previousMillis2 = 0;   
int time;
const byte ROWS = 4; //four rows
const byte COLS = 4; //four columns
//define the cymbols on the buttons of the keypads
char hexaKeys[ROWS][COLS] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'#','0','*','D'}
};
byte rowPins[ROWS] = {2, 3, 4, 5}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {6, 7, 8, 9}; //connect to the column pinouts of the keypad

//initialize an instance of class NewKeypad
Keypad customKeypad = Keypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS); 
int alt;
void setup(){
  Serial.begin(9600);
  pinMode(13,OUTPUT);
}
void loop(){
  char customKey = customKeypad.getKey();
     unsigned long currentMillis = millis();


     if(currentMillis - previousMillis > interval) {
    // save the last time you blinked the LED
    previousMillis = currentMillis;  
        if(customKey=='1'){
       alt=1000;
    }
  }
    if(currentMillis - previousMillis2 > interval2) {
    // save the last time you blinked the LED
    previousMillis2 = currentMillis;  
         if(customKey=='2'){
       alt=2000;
    }

}
Serial.println(alt);
  digitalWrite(13,HIGH);
  delay(alt);
  digitalWrite(13,LOW);
  delay(alt);
}
/* @file CustomKeypad.pde
|| @version 1.0
|| @author Alexander Brevig
|| @contact alexanderbrevig@gmail.com
||
|| @description
|| | Demonstrates changing the keypad size and key values.
|| #
*/
#include <Keypad.h>

int ledState = LOW; 
long previousMillis = 0; 

int time;
const byte ROWS = 4; //four rows
const byte COLS = 4; //four columns
//define the cymbols on the buttons of the keypads
char hexaKeys[ROWS][COLS] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'#','0','*','D'}
};
byte rowPins[ROWS] = {2, 3, 4, 5}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {6, 7, 8, 9}; //connect to the column pinouts of the keypad

//initialize an instance of class NewKeypad
Keypad customKeypad = Keypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS); 
int alt;
void setup(){
  Serial.begin(9600);
  pinMode(13,OUTPUT);
}
void loop(){
  char customKey = customKeypad.getKey();
   
    if(customKey=='1'){
       alt=1000;
    }
     if(customKey=='2'){
       alt=2000;
    }
    
   Serial.println(alt);
   unsigned long currentMillis = millis(); 
   if(currentMillis - previousMillis > alt) {
    previousMillis = currentMillis;  

    if (ledState == LOW)
      ledState = HIGH;
    else
      ledState = LOW;

    digitalWrite(13, ledState);
  }
}

così non è corretto?

ahhhhh andava sul led ora funziona alla grande sei un grande grazie infinitivamente milleeeeeeeeeeeeee ( ti ho messo 3 karma)