assegnare un valore ad una variabile tramite seriale.

Salve allora , io vorrei settare un valore di una variabile o più variabili tramite seriale. un ipotesi che ho fatto è la seguente:

void setup(){
a= Serial.read();
b=Serial.read();
...
}

ma quando vado a stampare questi valori ci sono attribuiti valori del tutto diversi xD

Purtroppo non funziona così ... bisogna che ti studi i vari metodi della classe Serial() !

In particolare presta attenzione a Serial.available() , il cui uso è fondamentale e a come funziona esattamente la Serial.read().

Guglielmo

un esempio per schiarirmi le idee, e da un giorno che cerco esempi e cerco di capire quella funzione :fearful:

La Serial.read() la puoi fare se ... c'è qualche cosa da leggere ... altrimenti, [u]come c'è chiaramente scritto[/u], ti ritorna sempre -1 !

Quindi ... ... [u]prima[/u] di una Serial.read() [u]verifichi[/u] che ci sia veramente qualche cosa da leggere :

if ( Serial.available() > 0 ) {
   inChar = Serial.read();
   ...
   ...
}

Guglielmo

Ma se io inserisco dei valori interi tramite seriale quando li vado a stampare poi mi da che 1 è equivalente a 49 2 a 50 e così via...

Tramite seriale, se invii da un programma, puoi decidere di mandarli in binario, ma se li mandi dal monitor seriale di Arduino o da un terminale seriale, i caratteri vengono inviati in ASCII

Quindi il carattere ‘1’ viene trasmesso NON come 0x01 (decimale 1), ma come 0x31 (decimale 49) che è il suo codice ASCII.

Se devi trasmettere un numero di più cifre e riceverlo con Arduino, la cosa si complica, perché dovrai fare un loop che riceve ogni singolo carattere fino ad un determinato carattere che gli dice che hai finito (es. il CR 0x0D), dovrai mano mano memorizzare i caratteri ricevuti in una stringa di tipo char array terminandola, secondo la sintassi del C con il terminatore 0x00 e quindi usare una funzione per convertire la stringa in numero (es. per i numeri interi atoi()).

Guglielmo

Edit : Comunque è un argomento che è stato trattato un’infinità di volte qui sul forum. Se fai un po di ricerche trovi svariate discussioni ed esempi.

Cioè , tramite seriale lui li passa il corrispondente in ASCII , quindi di conseguenza se io passassi 1 e lo vorrei incrementare al secondo ciclo mi darebbe 50 invece di 49... E se io volessi ovviare a questo problema ?? In pratica il mio scopo e quello di implementare un orologio su display, ma la prima fase e svilupparlo stampandolo tramite Serial.println , che ad ogni avvio lui mi chiede di inserire l ora esatta.. Il problema nn sussiste quando assegno alle variabili ore e minuti il valore esatto dell ora es:

Int ora = 17;
Int minuti=36;

Così va.... Ma nn é quello che voglio io.

Se hai ben letto, ti ho appena spiegato che devi convertire la sequenza di caratteri ASCII in un numero !

Esempio, 0x31, 0x32, 0x33, 0x00, che in decimale vale 49, 50, 51, 00 corrisponde alla stringa di char "123" (osserva i doppi apici che identificano la stringa di char). Per avere da questa stringa il numero 123, devi usare la atoi().

Queste sono le BASI del C, quindi ... il mio consiglio è che, prima di metterti a fare programmi che richiedano certe funzioni, ti metti a studiare seriamente il C così da capire tutti i vari meccanismi ;)

Guglielmo

Il problema é che io vengo dal C su calcolatore , ed assegnare un intero tramite scanf è molto semplice ! ... Infatti mescolo le due cose, tra calcolatore e arduino :~ Comunque sto vedendo questo funzione che é molto interessante , naturalmente mai usata perche come le ripeto su calcolatore scanf fa tutto lei

Pessima abitudine di usare funzioni che occupano tonnellate di memoria ... XD :grin: XD :grin: XD

Qui sei su una MCU ... hai poco spazio per il codice (considera che ci sono chip Atmel che hanno un paio di KB di Flash) e ancora meno SRAM (su Arduino hai 32KB di Flash e solo 2 KB di SRAM) ... :roll_eyes:

Ti consiglio un attento studio della AVR libc che è automaticamente inclusa dal IDE di Arduino e che ti mette a disposizione tantissime funzioni molto efficienti ;)

Guglielmo

int val;
char val_in[3];
void setup () {

  Serial.begin(9600);
}

void loop(){
  val_in=Serial.read();
  val=atoi(val_in);
  Serial.println(val);
}

mi dice sketch_may31a.ino: In function ‘void loop()’: sketch_may31a.ino:9:9: error: incompatible types in assignment of ‘int’ to ‘char [3]’

T'ho già spiegato che :

gpb01: Se devi trasmettere un numero di più cifre e riceverlo con Arduino, la cosa si complica, perché dovrai fare un loop che riceve ogni singolo carattere fino ad un determinato carattere che gli dice che hai finito (es. il CR 0x0D), dovrai mano mano memorizzare i caratteri ricevuti in una stringa di tipo char array terminandola, secondo la sintassi del C con il terminatore 0x00 e quindi usare una funzione per convertire la stringa in numero (es. per i numeri interi atoi()).

bisogna che ti STUDI bene i metodi della classe Serial !

  1. la Serial.read() legge UN carattere alla volta e NON una stringa di char e ritorna -1 se non ci sono char. Come ti ho detto DEVE essere condizionata alla Serial.availble().

  2. NON puoi di conseguenza assegnare ad un pointer (val_in è il [u]puntatore[/u] all'array di caratteri, val_in[ i ] è il [u]carattere[/u] a posizione i) un carattere.

... e bisogna che ti dai una ripassata alle BASI del C perché queste sono cose che sono valide sia un PC che su MCU !!!

Guglielmo

P.S. : Hai provato a fare un po' di ricerche qui sul forum ??? Perché, come ho detto, è un argomento che è stato discusso molte volte.

Nessun errore , penso di aver capito come funziona “forse”

ma quando stampo su monitor seriale, da sempre 0

int arraynumber[3];
char arraychar[3];
int i;
void setup () {
  Serial.begin(9600);

}

void loop(){

   while(i<3){
     Serial.println("insert number");
     delay(2000);
     arraychar[i]=Serial.read();
     arraynumber[i]=atoi(arraychar[i]+"\0");
     Serial.println(arraynumber[i]);
     i++;
   }

}

Tu dei fare una cosa … CANCELLA TUTTO QUELLO CHE SAI SU PC … e ricomincia studiando l’ANSI C XD XD XD

NON è assolutamente ammesso concatenare due char come hai fatto tu … in quel modo hai solo detto al compilatore di sommare algebricamente il valore 0x00 ad arraychar[ i ] !!!

Ti consiglio di definire un carattere che identificherà quando hai finito di scrivere il numero sul monitor seriale, ad esempio il CR (0x0D) che puoi dire al monitor seriale di aggiungere quando invia la stringa e poi fare un ciclo per la lettura.
Lo scheletro è più o meno questo :

byte idx;
char caratteri[8]; // massimo 7 caratteri + lo 0x00 di fine stringa
int numero;
...
...
idx = 0;
while(1) {
  if ( Serial.available() ) {
    caratteri[idx] = Serial.read();
    if (caratteri[idx] == 0x0D) break; // se ricevo il CR esco
    idx++;
    if (idx > 6) break; // se dopo il 7 carattere ancora non ho ricevuto CR esco perché non ho più spazio
  }
}
caratteri[idx] = 0x00; // metto il terminatore di fine stringa al posto giusto
numero = atoi(caratteri);
...
...

ATTENZIONE : codice NON provato, scritto direttamente sul forum e NON verificato nel IDE. E’ da considerarsi solo uno spunto, potrebbe anche non compilare né funzionare.

Guglielmo

il codice va... diciamo che c'è un piccolo intoppo , se io stampo tutti i numeri dell 'array char caratteri non ci sono problemi, ma se stampo gli interi convertiti se superano le 6 cifre sballa la stampa dando un valore -6254

Mi sembra anche ovvio non ti pare ??? ]:D

Abbiamo definito prima di tutto un array che al massimo contiene un intero (-32768 .. +32767) e usiamo una funzione, atoi(), che converte gli interi !!!

Devi ovviamente adattare il tutto al tipo di numero che vuoi gestire ... esempio per un long ( -2.147.483.648 .. +2.147.483.647) come minimo dovrai definire l'array da 13 char e dovrai usare la atol() !

Guglielmo

PERFETTO :D :D :D

GRAZIE MILLE ;)

Io provavo cn unsigned long, ma usavo sempre atoi () :cold_sweat:

:) ... fai sempre riferimento alle funzioni che trovi nella AVR libc ... spesso ti tirano fuori dai guai XD

Guglielmo