Sono qui che aspetto di vedere il risultato ...
A presto !
Guglielmo
Sono qui che aspetto di vedere il risultato ...
A presto !
Guglielmo
Ciao, bravo, bel lavoro, ora vediamo come proseguire ... prima però alcune cose ....
E' un mio dubbio ... come mai per rimettere i minuti ed i secondi usi delle analogRead() con dei valori particolari su due differenti pin ? Potevo capire usando solo un pin ed utilizzando due valori di tensione all'ingresso differenti, uno per indicare aumenta i minuti e uno per indicare aumenti le ore, ma dato che ne usi due ... perché non usare delle normali digitalRead() di due pulsanti (.... ovviamente facendo o un debounce software o aggiungendo fuori una manciatina di componenti) ???
Nell'aumento delle ore e dei minuti ... a che ti servono quelle delay() messe li così ? Ricadi nel ... "codice fermo" per tutto quel periodo (seppur molto breve).
Come hai letto ... la millis() torna a 0 dopo poco più di 49 gg. quindi ... va benissimo per misurare degli intervalli di tempo ma va malissimo come "orologio" visto che ... ad un certo momento si azzera. :~
Vedo che tu, purtroppo, la usi come orologio :
secs = (millis()/1000)%60;
e questo soffre del suddetto problema !
La correzione del problema al punto 3. è praticamente immediata ... visto che hai già un IF in cui controlli se sono passati più di 999 millis
All'interno di quel IF, invece di assegnare il valore a secs ... semplicemente potresti incrementarlo di 1 e, se > 59 portarlo a 0 e semplificando la logica di tutto l'IF...
...
secs++;
if (secs > 59) {
secs = 0;
mins++;
if (mins > 59) {
mins = 0;
hrs++;
if (hrs > 23) {
hrs = 0;
}
}
}
...
Non solo, ma questo ha il vantaggio che con una una taratura del tuo :
if(currmillis-prevmillis > 999)
... potresti correggere le piccole differenze ed aumentare la precisione (se l'orologio va indietro, diminuire quel 999 se va avanti aumentare quel 999)
Che dici ... sistemi e poi andiamo avanti ?
Guglielmo
Edit : Invece di scrivere variabile = variabile + 1; impara ad usare l'operatore di incremento variabile++;
spero di aver modificato tutto quello che non andava bene
alla domanda 2 ho inserito qui delay perche mi sembrava piu preciso ad incrementare.. ora l'ho un po modificato vediamo se va bene..
#include <LiquidCrystal.h>
#define button 8
#define button1 9
int secs ;
int mins =-1 ;
int hrs ;
int val=0;
LiquidCrystal lcd (12, 11, 5, 4, 3, 2);
unsigned long prevmillis=0;
void setup() {
lcd.begin (16,2);
lcd.setCursor(4,0);
lcd.print(" 0:00:00");
pinMode(button, INPUT);
pinMode(button1, INPUT);
}
void loop(){
aumenta();
orologio();
}
void orologio(){
unsigned long currmillis = millis();
if(currmillis-prevmillis > 999){
prevmillis = currmillis;
if(secs<10){
lcd.setCursor(11,0);
lcd.print(secs);
lcd.setCursor(10,0);
lcd.print(0);
}
else{
lcd.setCursor(10,0);
lcd.print(secs);
}
// Aggiorna i minuti
if(secs == 0){
mins = mins++;
updateMin();
}
secs++;
if (secs > 59) {
secs = 0;
mins++;
if (mins > 59) {
mins = 0;
hrs++;
if (hrs > 23) {
hrs = 0;
}
}
}
}
}
// Funzione aggiornamento minuti
void updateMin(){
if(mins > 59){
hrs = hrs+1;
updateHrs();
mins = 0;
lcd.setCursor(7,0);
lcd.print("00");
}
if(mins < 10){
lcd.setCursor(8,0);
}
else{
lcd.setCursor(7,0);
}
lcd.print(mins);
}
// Funzione aggiornamento ore
void updateHrs(){
if(hrs > 23){
hrs = 0;
}
if(hrs < 10){
lcd.setCursor(4,0);
lcd.print(" ");
lcd.setCursor(5,0);
}
else{
lcd.setCursor(4,0);
}
lcd.print(hrs);
}
void aumenta(){
//aumenta minuti
val= digitalRead(button);
if(val==LOW){
delay(200);
mins = mins++;
updateMin();
}
//auementa ore
val= digitalRead(button1);
if(val==LOW){
delay(200);
hrs = hrs++;
updateHrs();
}
}
No, così l'hai incasinata mischiando la parte che avevi già con la parte che ti ho detto io ... devi fare le cose con più calma e capire bene quello che fai ... non fare copia/incolla senza capire ...
La strada più semplice e breve è normalmente la migliore ... quindi ... semplifichiamo ...
#include <LiquidCrystal.h>
//
const byte button = 8;
const byte button1 = 9;
//
int secs, mins, hrs, val;
unsigned long currmillis, prevmillis;
//
LiquidCrystal lcd (12, 11, 5, 4, 3, 2);
//
void setup() {
prevmillis = 0;
val = 0;
secs = 0;
mins = 0;
hrs = 0;
//
lcd.begin (16,2);
lcd.setCursor(4,0);
lcd.print(" 0:00:00");
//
pinMode(button, INPUT);
pinMode(button1, INPUT);
}
//
void loop(){
aumenta();
orologio();
}
//
void orologio() {
currmillis = millis();
if(currmillis-prevmillis > 999){
prevmillis = currmillis;
// Aggiorna l'orario
secs++;
if (secs > 59) {
secs = 0;
mins++;
if (mins > 59) {
mins = 0;
hrs++;
if (hrs > 24) {
hrs = 0;
}
}
}
// Aggiorna il display
lcd.setCursor(4,0);
if (hrs < 10) lcd.print(" ");
lcd.print(hrs);
lcd.print(":");
if (mins < 10) lcd.print("0");
lcd.print(mins);
lcd.print(":");
if (secs < 10) lcd.print("0");
lcd.print(secs);
}
}
//
void aumenta(){
//aumenta minuti
val= digitalRead(button);
if(val==LOW){
delay(200);
mins++;
//
lcd.setCursor(7,0);
if (mins < 10) lcd.print("0");
lcd.print(mins);
}
//auementa ore
val= digitalRead(button1);
if(val==LOW){
delay(200);
hrs++;
//
lcd.setCursor(10,0);
if (hrs < 10) lcd.print(" ");
lcd.print(hrs);
}
}
Come vedi :
ho usato "const" variabile = valore; al posto dei tuoi #define ... l'effetto sul compilato è lo stesso, ma il compilatore ha, primo la possibilità di vedere se stai passando "tipi" di variabili sbagliate e, secondo, fa una migliore ottimizzazione del codice.
le variabili le ho dichiarate tutte globali ... inutile stare li, nella funzione orologio, che richiami in continuazione ad allocare e deallocare spazio per una variabile, è solo una perdita di tempo ! Ho fatto la dichiarazione in forma un po' più compatta ... tutte quelle dello stesso tipo le ho dichiarate assieme ... per il compilatore è la stessa cosa, per chi legge ... è più breve il codice
le variabili le ho inizializzate tutte nel setup() ... è il posto migliore e, un domani, se ci devi rimettere le mani, hai li tutte le inizializzazioni assieme, senza doverle andare a cercare sparse per il codice
ho reso compatta e molto veloce la funzione orologio() ... calcoli l'ora e aggiorni il display ... inutile farlo pezzetto per pezzetto allungando il codice per nulla ... ogni secondo hai l'ora completamente aggiornata sul display
ho modificato la funzione aumenta() per visualizzare direttamente su LCD il nuovo valore. Occhio, comunque quella funzione va corretta ... manca il controllo sulle ore > 23 e sui minuti > 59 ... uno pigiando il pulsante potrebbe arrivarci
NON si fa variabile = variabile++; ... l'assegnazione è già intrinseca nel operatore di incremento .. se leggi bene e con calma (... senza farti prendere dalla fretta di provare senza capire) quello che ti ho scritto prima vedi che scrivere variabile++ significa già scrivere variabile = variabile + 1
Mi sono fermato qui ... voglio che assimili bene quello che ti ho messo, lo provi e vedi se va ... io non posso provarlo e .. errori possono sempre esserci ... ho una certa esperienza ... ma non sono "infallibile"
Il passo successivo è sistemare appunto quella funzione aumenta() che proprio non mi piace (... se non hai dell'HW esterno, occorre fare il debouncing SW) e poi ... inserire la parte cronometro che volevi
Attendo le tue prove per vedere se funziona prima di proseguire.
Guglielmo
P.S. : Non uso la LiquidCrystal ... ma do per scontato che dopo la print di un carattere il cursore si sposti al successivo ... senza richiedere un nuovo posizionamento ...
Hai letto quanto ho scritto al punto 5. ???
... e quanto ho scritto successivamente ... "Il passo successivo è sistemare appunto quella funzione aumenta() che proprio non mi piace (... se non hai dell'HW esterno, occorre fare il debouncing SW)"
Cerca di vedere se riesci a sistemare la cosa tu ... analizzando bene cosa succede e come poter ovviare ...
... aspetto
Guglielmo
geppopazzo:
cosi incasino anche questo sketch....ahahaha
XD
XD
XD
Guglielmo
Ok ... guarda la nuova funzione aumenta() come è fatta ...
#include <LiquidCrystal.h>
//
const byte button = 8;
const byte button1 = 9;
//
int secs, mins, hrs, val;
unsigned long currmillis, prevmillis;
//
LiquidCrystal lcd (12, 11, 5, 4, 3, 2);
//
void setup() {
prevmillis = 0;
val = 0;
secs = 0;
mins = 0;
hrs = 0;
//
lcd.begin (16,2);
lcd.setCursor(4,0);
lcd.print(" 0:00:00");
//
pinMode(button, INPUT_PULLUP);
pinMode(button1, INPUT_PULLUP);
}
//
void loop(){
aumenta();
orologio();
}
//
void orologio() {
currmillis = millis();
if(currmillis-prevmillis > 999){
prevmillis = currmillis;
// Aggiorna l'orario
secs++;
if (secs > 59) {
secs = 0;
mins++;
if (mins > 59) {
mins = 0;
hrs++;
if (hrs > 24) {
hrs = 0;
}
}
}
// Aggiorna il display
lcd.setCursor(4,0);
if (hrs < 10) lcd.print(" ");
lcd.print(hrs);
lcd.print(":");
if (mins < 10) lcd.print("0");
lcd.print(mins);
lcd.print(":");
if (secs < 10) lcd.print("0");
lcd.print(secs);
}
}
//
void aumenta() {
// Controlla bottone minuti (button)
val = digitalRead(button);
if (val == LOW) {
delay(75); // <<<<<<<<<<<<<<<< si può provare ad abbassarlo
val = digitalRead(button);
if (val == LOW) {
// Pulsante premuto e rimbalzi finiti
mins++;
if (mins > 59) mins = 0;
//
lcd.setCursor(7,0);
if (mins < 10) lcd.print("0");
lcd.print(mins);
}
}
// Controlla bottone ore (button1)
val = digitalRead(button1);
if (val == LOW) {
delay(75); // <<<<<<<<<<<<<<<< si può provare ad abbassarlo
val = digitalRead(button1);
if (val == LOW) {
// Pulsante premuto e rimbalzi finiti
hrs++;
if (hrs > 24) hrs = 0;
//
lcd.setCursor(10,0);
if (hrs < 10) lcd.print(" ");
lcd.print(hrs);
}
}
}
... dove vedi scritto "<<<<<<<<<<<<<<<< si può provare ad abbassarlo" sono i punti in cui si aspetta che terminino i rimbalzi ... 75 msec. sono tanti, se i bottoni che usi sono di buona qualità dovresti poter scendere a 50 msec. se invece non lo sono ... magari ti tocca pure aumentare a 100 msec. XD
Riesci a seguirne la logica ? Capisco il perché della doppia lettura del pin ?
Guglielmo
Ah ... nota che ho fatto una modifica a livello di setup() :
pinMode(button, INPUT_PULLUP);
pinMode(button1, INPUT_PULLUP);
... ho attivato le resistenze di pull-up ... così quando il pin non è collegato da sempre HIGH e da LOW quando lo colleghi a massa
Guglielmo
P.S. : Per i dettagli leggi QUI ... terzo paragrafo ...
Se ho capito bene dal tutorial il doppio controllo serve per capire se c è stato del " rimbalzo" per colpa del pulsante... Cioè io premo una volta però sembra che venga premuto due o più volte...
Ma dal tutorial di arduino era molto più complicato farlo.. Bisognava dichiarare più variabili...
Allora te lo riassumo ... ecco quello che realmente succede quando pigi il bottone :
la sequenza la devi leggere così :
... più chiaro così ?
Guglielmo
Sì sì chiarissimo... Meglio di così non si può....
Ora rimane solo il problema delle ore... I minuti sono perfetti... Le ore vengono prima segnate nei secondi e poi venne nelle ore....
Ps: non ho capito bene perché ora a 59 minuti riparte da zero come è giusto che sia... Cosa è stato aggiunto?.?
grandeeeee ce l'ho fatta...ora le ore vanno bene se incrementano senza problemi... ho modificato questo parametro... va bene???
// incremento ore
....
lcd.setCursor(4,0);
....
l'ho portato a 4 e ora va benissimo... spero che mi dai il consenso anche te se no non so dove sbattere la testa...:)
Certo che va bene ... avevo sbagliato io a posizionare il cursore ... t'ho detto ... controllalo ... che io non lo posso provare quindi ... il debug lo faccio solo in testa e ... qualche cosa per forza sfugge ... XD XD XD
Per l'altra tua domanda ...
... se leggi bene il codice vedrai che sia per i secondi che per i minuti ... dopo c'è sempre un IF > 59 che rimette il valore a 0 mentre per le ore l'IF è fatto per > 23
Ora ... pronto per la funzione "Cronometro" ?
Usiamo altri due bottoni (button2 = start e button3 = stop) o ne vuoi usare uno solo che fa Start/Stop ... dimmi tu e andiamo avanti ...
Guglielmo
Sì sì ho visto rileggendo tutto attentamente ho notato quella cosa... Dai ci sto facendo l occhio...
Allora lo start glielo deve dare qui famosi 24 volt che poi passiamo a 5 con un fotoaccoppiatore ti ricordi??
Per i pulsanti dimmi te come vai meglio.. Per me non ci sono problemi di nessun genere..
Giusto ... avevo dimenticato ... XD
Allora direi che definisci due ulteriori pin, e fai una funzione come aumenta() che li legge, solo che quello che devono fare è ... estremamente più semplice ...
Il primo, lo start, non dovrà fare altro che mettere in una variabile il valore di millis() ed in un altra segnarsi che è partito (... così se riarriva il segnale sullo stesso pin prima dello stop ... lo puoi scartare) ed il secondo non deve far altro che fare la differenza tra il valore che hai salvato allo start e il valore di millis() allo stop e ... ecco che hai esattamente il tempo trascorso tra i due eventi
Ti è chiaro ? Provi a definire questa nuova funzione ?
Guglielmo
geppopazzo:
il pin che serve a me quello che mi simula la 24 volt non lo posso mettere sempre UP vero... lo dovrei mettere DOWN, ma esite la funzione PULLDOWN?? non mi sembra di averla letta..
Purtroppo NO ...
... quindi ... dato che per te lo Start è dato dalla presenza di un segnale +5V (... ricordati che DEVI abbassare quel +24V a +5V e che i segnali GND devono essere messi in comune), dovrai forzare la porta normalmente a LOW con una resistenza che metterai esternamente tra il pin che userai e la massa. Va benone una qualsiasi resistenza tra i 2.2K e i 10K .
Naturalmente dovrai poi invertire il test ovvero, non dovrai più chiederti se il pin è LOW, ma se il pin è HIGH ... per il resto non cambia nulla
Guglielmo
geppopazzo:
allora non ero piu del tutto stupida la mia domanda...:):)
No, affatto, era del tutto legittima ...
geppopazzo:
sto cercando di scrivere lo sketch per il cronometro... ci sto provando...
Ragiona con calma ... segui quanto fatto per aumenta() e vedrai che non sarà difficile ...
Guglielmo
Non ti serve una resistenza di PullDown se usi un fotoacoppiatore
Ottima idea Brunello ... così non gli cambia neanche la logica del programma che ha fatto fino ad ora ...
Guglielmo
P.S. : Anche se ... avrebbe imparato qualche cosa di più ...
sono fermo a una banalita... il mio cervello è entrato in un void loop al quale non riesco a uscire da solo....:)
sono riuscito a fare il cronometro tutto perfetto.. solo che per attivarlo devo premere il pulsate come detto ma appena lo lascio lui smette di contare... non riesco a farlo stare a LOW...