Go Down

Topic: problema con arduino e keypad 4x4 (Read 1 time) previous topic - next topic

chry2000

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?
:(
Code: [Select]
/* @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);
 
}

superlol

ricorda che in C il significato di
Code: [Select]
2

è diverso da
Code: [Select]
'2'

e sarebbe diverso da
Code: [Select]
"2"

quindi quando fai il confronto magari fallo come salvato nell'array e non col numero puro  ;)
Il nuovo forum italiano sull'elettronica: http://www.electroit.tk/ <--- Nuovamente online!

uwefed

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 é
Code: [Select]
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

chry2000

#3
Dec 24, 2012, 12:54 pm Last Edit: Dec 24, 2012, 12:58 pm by chry2000 Reason: 1
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
Code: [Select]
/* @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);
}

superlol

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 ;)

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 ;)
Il nuovo forum italiano sull'elettronica: http://www.electroit.tk/ <--- Nuovamente online!

chry2000

ecco io ho questo problema http://www.youtube.com/watch?v=F6XBoXezZmk

superlol


ecco io ho questo problema http://www.youtube.com/watch?v=F6XBoXezZmk

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

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 ;)
Il nuovo forum italiano sull'elettronica: http://www.electroit.tk/ <--- Nuovamente online!

chry2000

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 :)

chry2000

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

superlol

prendiamo di esempio il blinkwithoutdelay
Code: [Select]
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 ;)
Code: [Select]
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 ;)

ora passiamo al loop
Code: [Select]
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:
Code: [Select]
  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
Code: [Select]
previousMillis = currentMillis; 

2. 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)
Code: [Select]
    if (ledState == LOW)
      ledState = HIGH;
    else
      ledState = LOW;


3. andare a cambiare lo stato al led assegnandogli il valore di ledState appena cambiato
Code: [Select]
digitalWrite(ledPin, ledState);

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

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?  ;)
Il nuovo forum italiano sull'elettronica: http://www.electroit.tk/ <--- Nuovamente online!

chry2000

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 :)

chry2000

ho tentato a farlo con due led ma non mi viene cosa sbaglio :\
Code: [Select]
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;
}
}

superlol


ho tentato a farlo con due led ma non mi viene cosa sbaglio :\
Code: [Select]
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 :P
scommetto che rimaneva spento :D
Il nuovo forum italiano sull'elettronica: http://www.electroit.tk/ <--- Nuovamente online!

chry2000

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 :\
Code: [Select]
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);
}
}

superlol

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)
Il nuovo forum italiano sull'elettronica: http://www.electroit.tk/ <--- Nuovamente online!

Go Up