Ancora con Arduino, RTC e keypad...

Jul 11, 2022 12 Replies

Non riesco a uscirne, voglio far vedere il tasto premuto sul display ma o escono 5 righine orizzontali al posto del numero premuto e il ciclo va avanti bene oppure esce il numero giusto ma si blocca tutto, porca puzzola, dove sbaglio? Praticamente funziona bene fino al passo1, scrive il numerino premuto sulla tastiera ma poi non va al passo2 e si blocca completamente il micro. Invece con alcune modifiche funziona tutto bene e i passi avanzano ma invece di scrivere il tasto premuto scrive 5 linee orizzontali per ogni carattere.


#include #include #include RTC_DS3231 rtc; LiquidCrystal_I2C lcd(0x27, 20, 4);



const byte ROWS = 5; //5 righe const byte COLS = 4; //4 colonne char keys[ROWS][COLS] = { {'A','B','#','*'}, {'1','2','3','U'}, {'4','5','6','D'}, {'7','8','9','E'}, {'','T'} }; byte rowPins[ROWS] = {10, 9, 8, 7, 6}; byte colPins[COLS] = {2, 3, 4, 5};



Keypad kpd = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );



unsigned long tempoTEMP; // variabile per timer visualizzazione temperatura sul display unsigned long tempoRTC; // variabile per timer visualizzazione ora sul display char keyM; // variabile che memorizza il tasto premuto che normalmente sarebbe transitorio solo nel momento che si preme



char keyM1; // serve per poterlo utilizzare nel confronto && con kstate


void setup() { Serial.begin(9600);



rtc.begin();



if (rtc.lostPower()) { rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); }



lcd.init(); lcd.setBacklight(1); lcd.clear();



tempoRTC = millis(); // variabile del tempo per scrivere ora e data sul display ogni secondo e non intasare il flusso dei dati tempoTEMP = millis(); // per scrivere la temperatura sul display



lcd.setCursor(0,0); lcd.print("Temp:"); lcd.setCursor(0,1); lcd.print(rtc.getTemperature()); lcd.print (" "); lcd.print ((char) 223); lcd.print("C");


}


void loop() {



if ((millis()- tempoRTC) >= 1000) // ogni secondo manda data e ora al display { DateTime now = rtc.now(); printDateTime(now); tempoRTC=millis(); }



char key = kpd.getKey(); // riceve il valore del tasto premuto



KeyState kstate = kpd.getState(); // riceve lo stato della tastiera HOLD PRESSED IDLE RELEASED



if (key != NO_KEY) // memorizza il valore del tasto premuto { keyM=key; keyM1=key; }


if ((keyM == '*') && (kstate == HOLD)) // se resta premuto il tasto asterisco esegue l'istruzione { lcd.setCursor(0, 3); lcd.print("SET Data: "); lcd.setCursor(10, 3); lcd.print(" / / "); passo=1; }


if (passo == 0)



{ lcd.setCursor(0, 3); lcd.print("ciao "); }



if (passo == 1)



{ while (key != NO_KEY) { setgiorno1(); //qui passa regolarmente al void setgiorno1() } }



if (passo == 2)



{ while (key != NO_KEY) { setgiorno2(); } }



if (passo == 3)



{ while (key != NO_KEY) { setmese1(); } }



if (passo == 4)



{ while (key != NO_KEY) { setmese2(); } }


if ((millis()- tempoTEMP) >= 10000) // ogni 10 secondi manda temperatura al display {



lcd.setCursor(0,0); lcd.print("Temp:"); lcd.setCursor(0,1); lcd.print(rtc.getTemperature()); lcd.print (" "); lcd.print ((char) 223); lcd.print("C"); tempoTEMP=millis(); }


}

void printDateTime(DateTime dt) //questo non ho capito bene come funziona { char dateBuffer[] = " DD/MM/YYYY "; char timeBuffer[] = " hh:mm:ss ";



lcd.setCursor(8, 0); lcd.print(dt.toString(dateBuffer)); lcd.setCursor(9, 1); lcd.print(dt.toString(timeBuffer));



}

void setgiorno1() { lcd.setCursor(10, 3); lcd.print(keyM1);//scrive regolarmente il numero premuto poi si blocca completamente e non va al passo2 passo=2; delay(20); }



void setgiorno2() {



lcd.setCursor(11, 3); lcd.print(keyM1); passo=3; delay(20);



}

void setmese1() {



lcd.setCursor(13, 3); lcd.print(keyM1); passo=4; delay(20);



}

void setmese2() {



lcd.setCursor(14, 3); lcd.print(keyM1); passo=5; delay(20);



}

Saluti da Drizzt, quello vero! www.agidone.altervista.org MAI PIU' UN CESSO DI OPEL IN VITA MIA!!!! http://www.tappezzeriagraziella.com/

Drizzt do'Urden ha scritto:

Guarda che "anima buona" e "buonanima" non sono mica sinonimi... Per la buonanima ci vuole una seduta spiritica :-)

Elio Fabri

Il 11/07/2022 14:56, Drizzt do'Urden ha scritto:

uscire dal loop, usa if se vuoi farlo girare una sola volta, e questo vale anche per gli altri.

Il 11/07/2022 15:26, Elio Fabri ha scritto:

lol non ci avevo pensato :-D

Saluti da Drizzt, quello vero! www.agidone.altervista.org MAI PIU' UN CESSO DI OPEL IN VITA MIA!!!! http://www.tappezzeriagraziella.com/

Il 11/07/2022 16:27, Franco Af ha scritto:

ho usato while per aspettare che venga premuto un tasto altrimenti prende qualsiasi cosa ci sia ma effettivamente qualcosa si incasina, non vorrei fosse colpa della libreria keypad che non azzera certe variabili. Altrimenti un modo per attendere un pulsante per poi scriverlo sul display e passare a quello successivo come potrebbe essere? Sto provando con gli if ma non funziona, scrive il primo tasto che premo consecutivamente in tutti gli spazi dati dai vari passi.

In pratica voglio scrivere sul display un tasto alla volta nella posizione che dico io quindi deve esserci un controllo per evitare che il primo tasto corra in tutte le posizioni.

Saluti da Drizzt, quello vero! www.agidone.altervista.org MAI PIU' UN CESSO DI OPEL IN VITA MIA!!!! http://www.tappezzeriagraziella.com/

Il 11/07/2022 21:10, Drizzt do'Urden ha scritto:

Quella variabile "key" viene impostata solo quando usi key=kpd.getKey() altrimenti rimane invariata, e non uscirai mai dal loop.

poi devi impostare il progetto in modo che richieda di nuovo il carattere sulla tastiera (senza passare dagli altri if)

Il 11/07/2022 22:12, Franco Af ha scritto:

Ok, sembra che ci sia riuscito come dici tu, con gli if, ora riesco a

In pratica creando numeri di passo secondari sono riuscito a far aspettare che si prema il tasto successivo, ora devo memorizzare i tasti

if (passo == 0)

{ lcd.setCursor(0, 3); lcd.print("Hold * for Menu'"); }

if ((keyM == '*') && (kstate == HOLD)) // se resta premuto il tasto asterisco esegue l'istruzione { lcd.setCursor(0, 3); lcd.print("SET Data: "); lcd.setCursor(10, 3); lcd.print(" / / "); delay(1000); //tempo di attesa per rilasciare il tasto

passo=1; }

if ((passo == 1) && (key != NO_KEY)) // scrive il primo tasto e avanza di un passo { lcd.setCursor(10, 3); lcd.print(keyM1); delay(500); passo=2; }

if ((passo == 2) && (kstate == RELEASED)) //controlla che il tasto sia stato rilasciato

{ passo=21; //e passa al prossimo step di controllo }

if ((passo==21) && (key != NO_KEY)) // scrive il secondo tasto { lcd.setCursor(11, 3); lcd.print(keyM1); delay(500); passo=3; }

if ((passo == 3) && (kstate == RELEASED)) //stesso schema per tutte le cifre della data.

{ passo=31; }

if ((passo==31) && (key != NO_KEY)) { lcd.setCursor(13, 3); lcd.print(keyM1); delay(500); passo=4; }

if ((passo == 4) && (kstate == RELEASED))

{ passo=41; }

if ((passo==41) && (key != NO_KEY))

{ lcd.setCursor(14, 3); lcd.print(keyM1); delay(500); passo=5; }

ecc ecc...

Saluti da Drizzt, quello vero! www.agidone.altervista.org MAI PIU' UN CESSO DI OPEL IN VITA MIA!!!! http://www.tappezzeriagraziella.com/

Il 12/07/2022 21:42, Drizzt do'Urden ha scritto:

se funziona :) Memorizzare i tasti premuti credo sia la parte meno difficile, se sei

Il 12/07/2022 21:53, Franco Af ha scritto:

Ora vado a studiarlo... sperem ben :-D

-- Saluti da Drizzt, quello vero!

formatting link
MAI PIU' UN CESSO DI OPEL IN VITA MIA!!!!
formatting link

Il 12/07/2022 21:53, Franco Af ha scritto:

Dunque, finalmente con il solito paziente vostro aiuto, sono riuscito a far funzionare il tutto,

formatting link

ho creato le variabili dove memorizzare i tasti premuti, ho creato quelle che si aspetta la libreria RTClib per modificare data e ora e ho concatenato i valori dei tasti per creare data e ora, siccome i tasti sono dati char li ho convertiti in INT da spedire al rtc, ho trovato il modo in rete.

int g1; //variabili giorno mese anno ore minuti secondi int g2; int M1; int M2; int a1; int a2; int a3; int a4; int h1; int h2; int m1; int m2; int s1; int s2;

int year; //variabili che accetta RTC per modificare data e ora int month; int day; int hour; int min; int second;

if ((passo == 1) && (key != NO_KEY)) //inizia la sequenza per modificare data e ora { lcd.setCursor(10, 3); lcd.print(keyM1); char giorno1=keyM1; //i caratteri della tastiera sono char g1=giorno1-'0'; //togliendo '0' (48) al char premuto si ha la conversione in INT delay(500); passo=2; }

e cosi di seguito fino al termine:

if (passo == 14)

{ int year=(a1*1000 + a2*100 + a3*10 + a4); //concatenazione delle variabili singole int month=(M1*10 + M2); int day=(g1*10 + g2); int hour=(h1*10 + h2); int min=(m1*10 + m2); int second=00; rtc.adjust(DateTime(year, month, day, hour, min, second)); passo = 0; delay(500); }

questi i dati di memoria su arduino uno, spero mi basti per fare il resto: Lo sketch usa 12998 byte (40%) dello spazio disponibile per i programmi.

Le variabili globali usano 735 byte (35%) di memoria dinamica, lasciando

per gestire l'erogazione delle crocchette per il gatto :-)

Saluti da Drizzt, quello vero! www.agidone.altervista.org MAI PIU' UN CESSO DI OPEL IN VITA MIA!!!! http://www.tappezzeriagraziella.com/

semplicissimo, ma ci sei riuscito. Poi dicono che con arduino non impari nulla, tu sei un esempio che

stimolo a proseguire nello studio.

Il 17/07/2022 18:44, El_Ciula ha scritto:

non metterci mano se non per kit belli che pronti.

Questo succede con tutte le cose, non solo per l'elettronica, chi ha voglia di imparare viene stimolato facendo progetti interessanti.

Il 17/07/2022 18:44, El_Ciula ha scritto:

Infatti, la gestione del RTC digitando direttamente data e ora da tastiera non l'ho trovata da nessuna parte, tutti che, o scrivono dal serial monitor oppure usano due tasti per aumentare o diminuire i

pratico :-)

Saluti da Drizzt, quello vero! www.agidone.altervista.org MAI PIU' UN CESSO DI OPEL IN VITA MIA!!!! http://www.tappezzeriagraziella.com/

Join the Discussion

Have something to add? Share your thoughts — no account required.

Didn't find your answer?

Ask the community — no account required