AIUTOOO!!Leggere e controllare un dato da tastiera

ciao a tutti, lo so che probabilmente, anzi che sicuramente sono il più netto di tutti e che questa domanda è assolutamente insulsa, ma ci sto provando da 2 giorni e non ne esco, quindi eccomi qua a chiedere aiuto a voi espertissimi.

Sostanzialmente quello che non mi riesce è leggere un dato da tastiera, e controllare che quel dato sia valido, ovviamente fino a quando esso non è valido vorrei che il programma rimanesse “fermo li ad aspettare” fino a quando non viene inserito un numero corretto.

il codice che ho scritto è sicuramente una porcheria che ovviamente non funziona:

void gioco(){
  Serial.println("seleziona il numero di led con i quali vuoi giocare");
  nLed = Serial.read();
  while(Serial.available() <= 0){
    while((nLed<=0) || (nLed >= 3)){
      nLed = Serial.read();
    }
  }
}

La variabile nLed è intera e globale, e l’ho inizializzata = 0 nel setup.

ciao,

  1. ricevi correttamente la domanda “seleziona il numero di led con i quali vuoi giocare”?
  2. che risposta dai a questa domanda? ‘0’ (carattere zero) è diverso da 0 (numero zero)

sì la domanda la ricevo, perche sul setup faccio Serial.begin(9600); quindi sincronizzo arduino. il problema è il numero, qualsiasi numero io immetta, il risultato non cambia.

dai un occhio qui.
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1274190329/13#13
o qui …
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1274252175
diverse le domande ma simili poi le possibili soluzioni (credo)
poi … nn puoi usare in due momenti diversi il serial read… quando leggi scarichi il buffer … e il secondo se nn digiti niente ha valore “/0”
nullo…
per cui … devi mettere il serial raed in una variabile e poi eventuualmente rileggerlo.
poi secondo me c’è un problema coi i comparatori
“while(Serial.available() <= 0)” se mai “!=0” o “>0”
idem while((nLed<=0) || (nLed >= 3)) “>=0” “<=3”
davide

dalla tastiera del pc non ricevi un numero ma un codice ascii (vedi qui http://it.wikipedia.org/wiki/ASCII).
quindi:

nLed = 48 - Serial.read();

ma ti conviene sempre prima fare una verifica per non incorrere in risultati inattesi:

nLed = Serial.read();
if(nLed > 47 && nLed < 58) { //solo numeri da 0 a 9
nLed = nLed - 48;
}

Così dovrebbe funzionare:

void gioco(){
Serial.println(“seleziona il numero di led con i quali vuoi giocare”);
while(Serial.available())
{
nLed = Serial.read();
if(nLed > 48 && nLed < 52) //
{
nLed = nLed - 48;
//qui accendi il led corrispondente
} else {
Serial.println(“solo numeri tra 1 e 3, grazie!”);
}
}
}

Davide, dimmi se sbaglio ma se io impostassi Serial.avialable()>0 all’interno di un while la condizione sarebbe sempre falsa perchè è umanamente impossibile tenere sempre premuto un pulsante della tastiera, cioè lo fa solo chi ha fatto il programma e quindi il codice interno ad esso non verrebbe mai eseguito, mentre io voglio che il programma fino al momento in cui non gli venga fornito un dato valido interno al range da me stabilito, stia fermio li dov’è senza fare altre operazioni.

ah!!! ho capito !!! kokiua sei stato chiarissimo!!! Ma quindi è sbagliato dichiarare nLed come variabile intera ?

vi ringrazio davvero un casino !!!

beh... io ho dato per scontato che tu l'avessi dichiarata come variabile globale all'esterno della funzione gioco() per poterla leggere anche in altre funzioni... ;)

Chiaramente DEVI prima dichiarare la variabile :P

per averla dichiarata l'ho dichiarata, volevo sapere se era giusto dichiararla come variabile intera.

in realtà è sufficiente un byte, ma anche un int funziona senza problemi. Certo che se devi fare i conti con lo spazio a disposizione della ram è sempre meglio dimensionare le variabili per quel che servono.. ;)

aggiungo: si, è giusta una variabile intera e senza segno!

ti ringrazio davvero un casino!!!

si .. e no ... kokiua ti ha risposto ... nel senso che tu leggi sempre la serial.reed e la utilizzi quando ti serve con lo "if" per quello Serial.available())>0 o semplicemente (Serial.available()).... e appunto leggi una sola volta il tasto... nn sapevo invece della "traduzione" all'ascii ... Grazie

già, quel maledetto ascii… infatti ora ho risolto, funziona tutto, o quasi tutto, ma i “problemi” che ho ora sono errori miei e riesco ad andare avanti anche da solo, ma leggere un tasto da tastiera per me con arduino in questo anno è sempre stato un problema irrisolvibile… e nonostante a scuola io abbia chiesto più volte spiegazioni nessuno me le ha mai dateplete com… mi dicevano sempre fai Serial.available()>0, e poi Serial.read() e poi il prof. andava a farsi gli affaracci suoi “usando la scusa: eh ma dovete imparare da soli…”.
tutti sono bravi a fare il prof. così…
Davvero ancora una volta vi ringrazio un casino!!!

con Serial.read(), arduino legge 1 solo carattere, esiste un comando che ne legge più di uno ? quindi fare una lettura bufferizzata ?

La devi fare tu... Crei un array di byte della lunghezza del buffer che ti serve quindi con un loop leggi n caratteri sino a quando non incontri un CR (tasto [invio], vedi corrispondente ascii = 13). Per evitare che il programma ti si "inchiodi" sino a quando non premi CR puoi inizializzare una variabile con un valore di tempo che confronterai all'interno del loop di lettura della seriale, raggiunto un tempo limite esci comunque dal loop anche senza pressione di CR (ignorando i caratteri letti...). Ce la fati da solo, vero? ;)

quasi tutto, ci sono sl 2 cose che mi lasciano un pò perplesso la cosa del tempo, ed il tasto invio... per il tempo dovrei fare una variabile che chie si incrementa... ma così il programma finisce subito... il codice del tasto invio si deve memorizzare all'interni dell'array ?

e comunque dovrei leggere sempre un tasto alla volta giusto ?

Praticamente tutto quello che ti ho scritto ti da difficoltà … :-/

Devi per forza leggere un tasto alla volta… (e ricordati che sono sempre informazioni in ascii, ma se devi convertire numeri > di 9 puoi usare le funzioni di conversione previste in C).

Non hai bisogno di memorizzare il tasto invio, ma solo usarlo per controllare l’uscita dal loop.

Poi:
Sai che in Arduino esistono delle funzioni di tempo, vero? (es: http://arduino.cc/en/Reference/Millis), devi definire una variabile PRIMA del loop che legge la tastiera e gli assegni il valore corrente, es:

#define RITARDO 1000 //impostazione del ritardo prima di uscire dalla lettura tastiera
unsigned long time; //variabile per memorizzare il tempo corrente
char carattere; //variabile di lettura ultimo tasto

time = millis();

while( ( millis() < (time + RITARDO) || Serial.available() ) && carattere != 13 ){
//qui tratti il buffer
}

E ricordati di prevenire il superamento del buffer… nel senso che se ti arrivano + caratteri della lunghezza del buffer ti conviene impostare “carattere = 13” così non hai sforamenti di memoria

Ora però ti devi mettere al lavoro e imparare anche facendo qualche errore e correggendolo (si impara meglio), ok?

ho capito... beh il programma che non riuscivo a fare l'ho finito e funziona... quindi qualcosa alla fine credo di aver imparato...(almeno spero)... comunque io speravo che si potesse leggere una stringa senza immettere un carattere alla volta, però effettivamente è anche vero ke arduino non ha a disposizione tnt memoria... xò una funzione del genere potevano anche farla... x me non vale la pena fare una funzione per leggere solamente 2 numeri... anchev perchfine il risultato è uguale... comunque proverò lo stesso a farla... sì le funzioni di tempo so ke ci sn... ho letto e riletto il mini manuale presente nel software di arduino prima di chiedere aiuto qui...

solo un'altra cosa... a cosa serve unsigned ? non l'hov trovato all'interno della guida...

grazie davvero