docdoc:
Non ti preoccupare, il forum serve anche per aiutare chi ancora non ha molta esperienza (ed anche io stesso imparo sempre cose nuove).
Provo a darti le risposte ai tuoi dubbi:
*"int valore[NUMTASTI] = { 50, 100 }; // valore da sommare per ogni tasto * Si assegnagno delle specifiche funzioni ai tasti"
Più che funzioni in questo vettore specifico il valore da sommare quando si preme un tasto, ossia 50 per il primo tasto (indice 0, come saprai i vettori hanno indici che iniziano da zero), e 100 per l'altro.
" for(int i=0; i<NUMTASTI; i++)
pinMode(pin[ i ], INPUT);* Non ho ben capito perche i pin vegono assegnati con "i" e di conseguenza vengono portati a zero???"
Quello è un ciclo for() con la variabile "i" che inizia da 0 e si incrementa fino a 1 (NUMTASTI è 2 quindi esce dal for quando i è minore di 2). Come funziona il for() lo leggi QUI.
Con "pin[ i ]" si intende "l'elemento i-esimo della matrice 'pin", e se vedi l'inizializzazione, il primo valore pin[ 0 ] vale 2 quindi al primo ciclo esegue in pratica "pinMode(2, INPUT)". Lo stesso per l'altro pin. Questo serve per generalizzare, ossia se tu in futuro dovessi avere 10 pin, avrai il simbolo NUMTASTI che vale 10 quindi quel ciclo andrà da 0 a 9, e quindi setterà i pin specificati nella matrice pin[].
" mostraPunti(); Ragruppa le istruzioni da eseguire dopo le scritte iniziali."
Non proprio, qui si richiama una nuova funzione chiamata "mostraPunti" che mostra o aggiorna sul display il valore del puteggio attuale. Questo perché la stessa cosa andrà fatta ogni volta che si preme un pulsante per cambiare il punteggio per cui dato che sarebbero istruzioni identiche, è opportune metterle in una funzione separata e richiamare semplicemente questa.
" punti += valore*;* Somma i punti di ogni tasto e aggiorna il totale." Esatto. " if ((val[tasto] == HIGH) && (oldval[tasto] == LOW)){ * oldval[tasto] = val[tasto];* * return true;* * } * Definisce il comando tasto" Non esattamente. la if() verifica se il tasto risulta premuto (HIGH) ma dato che dobbiamo identificare quando il tasto viene premuto e non quando resta premuto (ricorda che il loop di Arduino gira molto rapidamente ogni secondo), se in precedenza il tasto non era premuto (LOW) significa che ho "iniziato" a premerlo quindi memorizzo questa condizione e restituisco "true" per segnalare che quel tasto è stato premuto. La seconda volta che si richiama questa funzione, poiché il precedente valore del tasto è "HIGH", non entro nuovamente nella if quindi non restituisco true ma false (tasto non premuto). Ci sono tanti modi per gestire i pulsanti ovviamente, e questo è solo uno di questi, ma per iniziare va bene. Spero di averti chiarito le idee...
Si diciamo che la maggior parte dei dubbi e stata colmata, ma ora veniamo al bello, ho caricato lo sketch su arduino, e aihme, in pratica non fa quello che vorrei fare io, ma inizia a sommare le cifre che abbiamo assegnato hai pin e non succede nulla quando premo i tasti.
Sicuramente ci sarà qualche errore nel loop della somma dei punti ma non saprei proprio cosa andare a modificare per provare a fermarlo
Saluti a tutti
Allora, intanto quando quoti cerca di quotare solo le parti "salienti" del precedente messaggio (ossia quelle singole frasi alle quali stai rispondendo) e non tutto il messaggio intero. O anche nulla, se non è necessario per la comprensione della tua risposta.
A parte questo, devi dirci anche come hai collegato i pulsanti. Ad esempio hai messo resistenze di pull-down? O pullup?
Questo e il metodo con cui ho collegato i pulsanti non so se sia pull-dpwn o pull-up.
A tal proposito siccome io a fine progetto dovrò utilizzare dei classici pulsanti NO a due contatti, la resistenza non va eliminata? E il nuovo schema come diventerebbe?
Melo92:
Questo e il metodo con cui ho collegato i pulsanti non so se sia pull-dpwn o pull-up.
Quella resistenza è collegata a massa quindi è pull-down ossia porta a massa (LOW) il pin se il pulsante non è premuto. Ed è corretto. Ma qui non è indicato, anche il secondo pulsante lo hai collegato esattamente così? E quando dici che non funziona (ma te l'avevo comunque detto che l'ho scritto senza poterlo provare.. ), cosa intendi esattamente? Se noti ho messo una istruzione "Serial.println(punti);", se apri il monitor seriale senza toccare i tasti, cosa leggi?
A tal proposito siccome io a fine progetto dovrò utilizzare dei classici pulsanti NO a due contatti, la resistenza non va eliminata? E il nuovo schema come diventerebbe?
Non capisco, quello che hai lì è già un pulsante a due contatti, ha 4 piedini perché sono collegati a due a due, ma lo schema resta valido, e la resistenza è necessaria.
Quella resistenza è collegata a massa quindi è pull-down ossia porta a massa (LOW) il pin se il pulsante non è premuto. Ed è corretto. Ma qui non è indicato, anche il secondo pulsante lo hai collegato esattamente così? E quando dici che non funziona (ma te l'avevo comunque detto che l'ho scritto senza poterlo provare.. ), cosa intendi esattamente? Se noti ho messo una istruzione "Serial.println(punti);", se apri il monitor seriale senza toccare i tasti, cosa leggi?
Si il secondo pulsante e collegato allo stesso modo.
Ma si infatti non ti sto dando colpe, anzi ti sono veramente grato per l'aiuto, questo e il risultato che compare nel monitor seriale.
Ad ogni secondo incrementa le due cifre.
Non capisco, quello che hai lì è già un pulsante a due contatti, ha 4 piedini perché sono collegati a due a due, ma lo schema resta valido, e la resistenza è necessaria.
Beh qui inizia l'esperienza di debugging che devi imparare a fare, no?.. Non è per non aiutarti, ma per stimolarti a prendere pratica con la cosa più difficile della programmazione, il debugging!
Allora, iniziamo: di quanto vedi che si incrementa? Di 150 punti, che è -guarda caso- la somma di 50 + 100 ossia come se risultassero premuti entrambi i pulsanti. Come mai? Devi capirlo.
Inizia mettendo dei Serial.println() in giro nel codice per capire meglio cosa "vede" e quindi come agisce, ad esempio nella funzione "leggiTasto":
Si, dal punto di vista dello schema e quindi dei collegamenti è identico a quello che hai sulla breadboard. Un piedino di questo corrisponde ai due di sinistra, l'altro ai due di destra. Uno va al pin di Arduino E alla resistenza verso massa, l'altro a +5V.
Melo92:
Da quanto ho capito i tasti commutano da 0 a 1 da soli giusto?
No, non hai messo i print che ti ho detto, ne hai messo uno solo, e che tra l'altro mostra solamente il valore dell'indice del tasto e non il suo valore.
Usa il MIO codice.
Melo92:
Si ora si ecco il risultato, in pratica alla pressione di ogni tasto viene indicato quale viene premuto.
Ok, quindi da questo output cosa ne deduci? Che incrementa sempre il totale. E dove incrementa il totale? Nel ciclo for():
for (int i=0; i<NUMTASTI; i++)
if ( leggiTasto(i) ) {
punti += valore[i];
aggiorna = true;
delay(200);
}
Ora, dato che l'incremento avviene solo dentro alla if() che a sua volta vale solamente se la funzione leggiTasto() torna true, dove potrebbe essere il problema? Cosa restituisce leggiTasto se non c'è nessun tasto premuto? (questo è un MIO bug, non voluto, ma prova a trovarlo tu, se non ci riesci dimmelo -dopo averci provato VERAMENTE- e provo a dirti qualcosa).
Poi mi spiegheresti qual'e la differenza fra "Serial.print" e "Serial.println"?
println() è una print() seguita da un fine riga (ln = line) ossia i caratteri per andare a capo.
Trovi tutto QUI.
PS: per catturare l'immagine della sola finestra Windows corrente, invece di premere solo il tasto Stamp prova con Alt+Stamp, avrai la sola finestra (nell'esempio, il serial monitor).
PPS: posso darti anche un altro consiglio? Non so se già lo conosci, ma esiste un sito Tinkercard Circuits che ti permette di progettare/disegnare i tuoi circuiti e persino simularli! provalo, è comodo per poter fare prove varie o anche provare circuiti interi o quasi!
bool leggiTasto(int tasto) { //definisce la funzione tasto
val[tasto] = digitalRead(pin[tasto]); // Assegna il valore "tasto" uguale alle letture dei pin
if ((val[tasto] == HIGH) && (oldval[tasto] == LOW)){ //Definisci le condizioni del valore "tasto"
Serial.print("Tasto ");
Serial.print(tasto);
Serial.println(" premuto");
oldval[tasto] = val[tasto]; //Eguaglia oldval a val, e secondo me e qui l'errore perchè hanno due condizioni diverse.
return true;
Ho provato a commentare le righe e credo di aver trovato l'errore ma non ne sono sicuro.
PS: per catturare l'immagine della sola finestra Windows corrente, invece di premere solo il tasto Stamp prova con Alt+Stamp, avrai la sola finestra (nell'esempio, il serial monitor).
PPS: posso darti anche un altro consiglio? Non so se già lo conosci, ma esiste un sito Tinkercard Circuits che ti permette di progettare/disegnare i tuoi circuiti e persino simularli! provalo, è comodo per poter fare prove varie o anche provare circuiti interi o quasi!
Grazie mille per i suggerimenti non ne sapevo nulla.
Melo92:
//Eguaglia oldval a val, e secondo me e qui l'errore perchè hanno due condizioni diverse.
Ho provato a commentare le righe e credo di aver trovato l'errore ma non ne sono sicuro.
Ci sei andato vicino ma non è quello. È che la funzione deve restituire sempre o true o false. E poco sotto se ci fai caso finisce senza restituire nulla, quindi devi aggiungere un "return false;" (perché se passa da lì significa che il tasto non è stato premuto).
Prova e vedrai.
Grazie mille adesso funziona.
Ora ci sarebbe da aggiungere un tasto per il reset punti, io avrei pensato, invece di aggiungere un altro tasto ai pin ed andare a modificare il codice, perchè non mettere un pulsante NC direttamente sull'alimentazione in modo che alla sua pressione apra il circuito non facendo passare piu corrente ed una volta rilasciato chiuda il circuito al punto di riavviare arduino. Cosa ne pensi?
Non c'è bisogno di andare sull'alimentazione, c'è il pin RESET. Se lo colleghi ad un pulsante NA e dall'altro capo lo mandi a GND fa quello che chiedi.
Si, ma la soluzione dipende da cosa ti serve. Di quanti pin hai bisogno, e input o output?
Considera che anche gli analogici puoi usarli come input digitali.
docdoc:
Si, ma la soluzione dipende da cosa ti serve. Di quanti pin hai bisogno, e input o output?
Considera che anche gli analogici puoi usarli come input digitali.
Bhe diciamo che i pulsanti, invece che due sarebbero piu di 10 XD
Melo92:
Bhe diciamo che i pulsanti, invece che due sarebbero piu di 10 XD
Beh, primo, Arduino UNO ha 13 porte digitali, ma diciamo che in genere ne usi 10 (2 sono per la seriale a la 13 spesso si lascia come output del LED builtin), meno quelli eventualmente usati per le periferiche.
Però puoi usare anche gli analogici come input, quindi ne hai altri 6 ed arrivi a 16 (sempre se non hai altre periferiche, ad esempio se usi LCD I2C non puoi usare A4 e A5).
Però puoi usare un pin analogico tramite un piccolo partitore resistivo collegare diciamo fino a 4 pulsanti ad un singolo pin (a patto che tu non debba poterne premere più di uno per volta di questi 4) come trovi QUI.
Altrimenti si possono usare shift register per aumentare gli ingressi o uscite.
Oppure passare ad Arduino Mega che di porte ne ha tantissime.
Quindi le possibilità sono tante, per cui se come immagino stai pensando ad un tastierino numerico ad esempio, ce ne sono già fatti e si collegano con soli 7 pin come QUESTO esempio, magari con una tastiera come QUESTA.
Oppure iniziare con uno shield che integra LCD e alcuni tasti come QUESTO.
docdoc:
Beh, primo, Arduino UNO ha 13 porte digitali, ma diciamo che in genere ne usi 10 (2 sono per la seriale a la 13 spesso si lascia come output del LED builtin), meno quelli eventualmente usati per le periferiche.
Però puoi usare anche gli analogici come input, quindi ne hai altri 6 ed arrivi a 16 (sempre se non hai altre periferiche, ad esempio se usi LCD I2C non puoi usare A4 e A5).
Però puoi usare un pin analogico tramite un piccolo partitore resistivo collegare diciamo fino a 4 pulsanti ad un singolo pin (a patto che tu non debba poterne premere più di uno per volta di questi 4) come trovi QUI.
Altrimenti si possono usare shift register per aumentare gli ingressi o uscite.
Oppure passare ad Arduino Mega che di porte ne ha tantissime.
Quindi le possibilità sono tante, per cui se come immagino stai pensando ad un tastierino numerico ad esempio, ce ne sono già fatti e si collegano con soli 7 pin come QUESTO esempio, magari con una tastiera come QUESTA.
Oppure iniziare con uno shield che integra LCD e alcuni tasti come QUESTO.
No no, non e un tastierino, devo proprio aggiungere altri pulsanti come quelli che ci sono adesso, comunque credo proprio che usero gli analogici anche se c'e gia il display con l'i2c.
A tal proposito gli analogici come li devo indicare sullo sketch?