Direi che quando ci sono cose che non si capiscono bene (perché è la prima volta che le fai) la cosa migliore è sperimentare, sperimentare, e sperimentare ma una cosa alla volta. Provo a spiegarti (non mi piace dare la "pappa pronta" ma è importante cercare di capire).
Prima cosa comunque, inizia ad imparare ad indentare per bene. Non è un problema per programmi piccoli come questo, ma se ci fai l'abitudine quando farai programmi più complessi vedrai che ti troverai molto meglio. Inizia premendo Ctrl-T dentro l'IDE, te lo indenta lui (ma poi erca di mantenere quel tipo di indentazione).
Passiamo alla questione della seriale.
Tu qui vorresti leggere un comando inviato da tastiera tramite monitor seriale ossia un angolo. Quindi ora lascia stare il servo e l'LCD, e cerca di studiare le basi della comunicazione seriale di Arduino ossia scrivere un programma che aspetta un valore numerico tra 0 e 180 digitato dall'utente e quindi una voltaacquisito te lo riporta sulla stessa seriale (così vedi che ha "capito" correttamente).
Questo è quello che intendo "sperimenta una cosa alla volta".
Quindi prima cosa:
int val = Serial.read();*
la Serial.read() restituisce un carattere (in realtà un byte) e non un intero. quindi se tu volessi mandare ad esempio 45 gradi, la read() chiamata la prima volta ti darebbe solo il carattere '4', chiamata una seconda il '5', una terza '\r' ed una quarta '\n'. Questi ultimi perché quando tu da monitor scrivi qualcosa e premi Invio, lui manda i caratteri che hai digitato, seguiti da "fine linea" ossia la sequenza di due caratteri '\r' (carriage return, codice 13) e '\n' (line feed o newline, codice 10).
Quindi dovresti leggere tutti i caratteri ricevuti ed accumularli dentro ad una stringa (ossia un char array) fino a che non ricevi i byte '\r' e '\n' (in sostanza ti basta ignorare il '\r', e considerare finita la stringa quando ricevi '\n'). Fatto questo, devi convertire questa stringa in un intero. E solo allora potrai poi fare:
Serial.println(val);*
e poi potrai pensare di aggiungere il comando del servo, e alla fine aggiungere anche l'lcd. Mai cercare di fare più di una cosa "nuova" contemporaneamente!
Prova a vedere qualche tutorial sulla seriale, tipo questo.
Aiutino: se intanto che aspetti l'input dall'utente non devi fare altro, prova a vedere la funzione Serial.parseint()
Grazie docdoc, forse ho fatto il passo piu lungo della gamba, sopratutto per la parte "comunicazione seriale" del programma.
Ti ringrazio per la spiegazione e link in descrizione
Se faccio degli step in piu aggiorno il post
Tranquillo, ci siamo passati tutti
Sono convinto che una volta che avrai creato quel programmino per leggere dalla seriale riuscirai a fare quello che ti riproponevi di fare.
Considera che la Serial.parseint() anche se per questo caso potrebbe anche risolverti il problema, in genere non si usa molto spesso, per cui quello che ti ho descritto è ciò che si fa in generale via seriale per ricevere dati da "qualcosa" (che può essere un umano o un programma...) quindi ti sarà utile anche in futuro saperlo.
Ultima cosa: anche se in giro dovessi trovare l'uso di variabili "String" (scritte così, con la "S" maiuscola), evitale come la peste perché su Arduino sono più i problemi che crea di quelli che risolve. Studia un poco gli array ed in particolare i "char array" che sono le "stringhe" del linguaggio C: un poco più "ostiche" da digerire all'inizio, ma basta un poco di impegno e le userai con scioltezza.
#include <Servo.h>
#include <LiquidCrystal.h>
const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
Servo servo1;
int val;
void setup() {
lcd.begin(16, 2);
lcd.print("Val.angolo:");
servo1.attach(9);
Serial.begin(9600);
}
void loop() {
if (Serial.available() > 0) {
val = Serial.parseInt();
Serial.print("angolo:");
Serial.println(val);
servo1.write(val);
if (val <= 9) {
lcd.setCursor(11, 0);
lcd.print("00");
lcd.print(val);
lcd.print(" ");
}
if (val > 10 && val <= 99) {
lcd.setCursor(11, 0);
lcd.print("0");
lcd.print(val);
}
if (val >= 100 && val <= 180) {
lcd.setCursor(11, 0);
lcd.print(val);
}
if (val > 180) {
lcd.setCursor(11, 0);
lcd.print("err.");
servo1.write(0);
}
}
}
Con questo codice funziona. Ho solo il problema che quando invio l'angolo, es. 90°, arriva a 90° e poi ritorna a 0°, non mantiene i 90°.
In seriale esce questo:
-angolo:90°
-angolo:0°
Ho anche notato che se inserisco l'angolo, premo invio e mantengo premuto invio, mantiene l'angolo e non ritorna a zero.
aljfox:
Con questo codice funziona. Ho solo il problema che quando invio l'angolo, es. 90°, arriva a 90° e poi ritorna a 0°, non mantiene i 90°.
Mi spiace notare che non hai fatto quasi nulla di ciò che ti ho consigliato, o quantomeno non l'hai capito.
Primo, la soluzione "ti piace vincere facile", ossia usare la Serial.parseInt(), può andare bene per fare questo semplice programma, ma devi leggere i reference di ciò che usi. Leggerai che la parseInt() attende un certo tempo il dato, dopo di che esce ritornando zero (e sta scritto nel reference). Puoi modificare questo timeout, ma come farlo te lo devi andare a leggere nel reference. Oppure se vuoi gestire tu l'input da seriale in modo più controllabile, devi usare l'altro metodo (quando ci sono caratteri provenienti da seriale leggere un carattere per volta ed accumularlo in una stringa buffer, quindi quando ricevi '\n' vedere cosa hai ricevuto). Lo so che è più "complicato" ma ti assicuro che se vuoi imparare a programmare in Arduino (ma qui parliamo comunque del linguaggio C in generale) tu prima o poi devi imparare array e stringhe C (char array)!
Secondo, usando la parseInt() non hai bisogno di controllare Serial.available() perché è questa che aspetta l'input da parte dell'utente (e sta scritto nel reference).
Terzo, se ti dico di sperimentare prima una cosa per volta, sperimenta una cosa per volta! Qundi iniziando da una cosa del genere e vedendo cosa succede:
int val;
void setup() {
Serial.begin(9600);
}
void loop() {
Serial.print("Inserisci l'angolo: ");
val = Serial.parseInt();
Serial.println();
Serial.print("angolo:");
Serial.println(val);
}
..e quindi se non fa quello che pensavi facesse, cercare di capire perché, e come correggerlo.
Ciao! La soluzione è corretta, ma mi chiedo se ci sei arrivato o ti sei limitato a copiare un pezzo di codice
Il risultato per il tuo problema non cambia, cambia solo la filosofia "ho risolto" o "ho imparato"