Go Down

Topic: Lettura seriale dati su arduino Aiuto (Read 2108 times) previous topic - next topic

danyevo

Ciao a tutti mi sono dimenticato una cosa che avevo fatto alcuni anni fa...
Se io invio una stringa seriale su arduino tipo:
a23
b34
c56
d32

come si fa per leggere la prima lettera della stringa e la cifra seguente?
tipo leggi cosa è scritto nella prima casella
poi leggi cosa è scritto nella seconda e terza casella

esempio pratico:


if (prima lettera è "a") variabile = alla cifra che segue
if (prima lettera è "b") variabile = alla cifra che segue
ecc ecc


praticamente devo ricevere da un arduino ad un altro arduino vari valori che per riconoscerli gli assegno la lettera seguiti dal valore, l'arduino che riceve deve leggere la prima lettera per capire su quale variabile deve salvare il valore.

nid69ita

Ma il dato inviato ha lunghezza fissa, sempre 1 carattere e poi due cifre ?  Anche cifra 5 = a05  ? 3 caratteri ?
my name is IGOR, not AIGOR

danyevo

#2
Apr 11, 2016, 09:21 am Last Edit: Apr 11, 2016, 09:30 am by danyevo
No il carattere dopo può essere da 1 a 3 cifre.
mi ricordo che gli davo la posizione con le parentesi quadre ma non mi vorrei sbagliare con un altro linguaggio.
Tipo puo essere a1 o a10 oppure a100
La lettera rimane sempre 1 ma il numetro no
Io devo leggere prima la lettera per capire che informazione è poi la cifra per salvarla nella variabile

danyevo

#3
Apr 11, 2016, 09:47 am Last Edit: Apr 11, 2016, 10:04 am by danyevo
Su VB faccio così per capirsi io ho già letto letto la stringa arrivata dalla seriale e è stata memorizzata su una variabile chiamata dr


        str1 = ""   azzero le variabili
        str2 = ""
       
          str1 = Mid(dr, 1, 1) leggo prima lettera della stringa chiamata dr e meorizzo su str1

        If str1 = "a" Then       se il primo carattere è a 
           
          str2 = Mid(dr, 2, 5)    leggo la cifra dal carattere 2 al 5 della stringa e memorizzo su str2
           
        End If


SukkoPera

Se hai già letto la stringa, allora hai un array di char, per cui:

Code: [Select]
if (a[0] == 'a') {
  // ...
} else if (a[0] == 'b') {
  // ...
}


Puoi anche fare uno switch case su a[0], meglio ancora.

Poi non ho ben capito la logica con cui estrai i caratteri successivi, per cui non posso dirti più di così.
"Code is read much more often than it is written, so plan accordingly. Design for readability."

Guida rapida a ESP8266: https://goo.gl/kzh62E

danyevo

Guarda l'esempio che ti ho fatto sopra

SukkoPera

#6
Apr 11, 2016, 10:21 am Last Edit: Apr 11, 2016, 10:22 am by SukkoPera
Code: [Select]
char str2[MAX_STR];

if (str1[0] == 'a') {
  strncpy (str2, str1 + 1, 5);
}


Dovrebbe essere equivalente.
"Code is read much more often than it is written, so plan accordingly. Design for readability."

Guida rapida a ESP8266: https://goo.gl/kzh62E

nid69ita

#7
Apr 11, 2016, 11:10 am Last Edit: Apr 11, 2016, 12:03 pm by nid69ita
Se hai ricevuto e messo i dati in un array di char i vari caratteri e terminano con carattere speciale NULL  ovvero '\0'   (fine stringa)
allora semplicemente usa la strtol()  passando pero l'indirizzo del vettore +1
Code: [Select]
str[0]='a';
str[1]='2';
str[2]='5';
str[3]='\n';
int x=strtol(str+1,NULL,10);       // secondo parametro non serve quindi null, terzo 10 = la base


my name is IGOR, not AIGOR

astrobeed

Se hai in un array di char i vari caratteri e terminano con carattere speciale NULL  ovvero '\0'   (fine stringa)
Non è applicabile con la ricezione seriale in quanto si tratta di un buffer senza nessun terminatore, è in fase di ricezione dei caratteri che deve essere creato un eventuale array con terminatore.
Solitamente quando si inviano stringhe di dati sulla seriale si usa un carattere dedicato per l'inizio e uno, diverso, per la fine, p.e. '@' e '#', in questo modo mentre ricevi i dati puoi definire la lunghezza esatta della stringa ed estrapolare con facilità i dati che interessano.
Altro metodo, non richiede il carattere di fine stringa, è usare un timeout, ovvero non appena ricevi il carattere di inizio dati fai partire un timer, allo scadere del tempo sai che è finita la trasmissione e inizi ad analizzare i dati, ovviamente questo metodo richiede una trasmissione a pacchetti con pause minime tra gli stessi leggermente superiori al timeout.
Rammento che fare il polling della seriale ad ogni ciclo della loop porta inevitabilmente a ricevere i dati un byte alla volta perché il ciclo loop, di norma, è molto più veloce della ricezione di un byte sulla seriale, sopratutto quando si lavora con bassi baud rate.

Scientia potentia est

nid69ita

#9
Apr 11, 2016, 12:05 pm Last Edit: Apr 11, 2016, 12:07 pm by nid69ita
Potrebbe anche spedire i dati a lunghezza fissa, se fattibile.
Quindi la cifra occupare sempre tre caratteri fillato di 0 davanti, esempio   "a003" oppure "a025"
Anche in questo caso avere un terminatore è comunque consigliato  esempio     "a025#" 
my name is IGOR, not AIGOR

danyevo

#10
Apr 11, 2016, 01:37 pm Last Edit: Apr 11, 2016, 01:37 pm by danyevo
Grazie ma per ora lasciamo perdere i terminatori torniamo a come prelevare il primo carattere che arriva e salvarlo in una variabie e la cifra che segue in un altra variabile.

torniamo all'esempio che io utilizzo in VB
       
        dr = Serial.read();
       
          str1 = Mid(dr, 1, 1) leggo la prima lettera della (stringa chiamata dr) e meorizzo su variabile str1

        If str1 = "a" Then       se il primo carattere è a 
           
          str2 = Mid(dr, 2, 5)    leggo la cifra dal carattere 2 al 5 della stringa e memorizzo su variabile str2
           
        End If

io devo fare una cosa simile

qualche anno fà avevo già fatto questa cosa ma non mi ricordo come

SukkoPera

"Code is read much more often than it is written, so plan accordingly. Design for readability."

Guida rapida a ESP8266: https://goo.gl/kzh62E

danyevo

scusami ma non riesco a capire. è questa:

char str2[MAX_STR];

if (str1[0] == 'a') {
  strncpy (str2, str1 + 1, 5);
}

SukkoPera

"Code is read much more often than it is written, so plan accordingly. Design for readability."

Guida rapida a ESP8266: https://goo.gl/kzh62E

danyevo

#14
Apr 11, 2016, 04:05 pm Last Edit: Apr 11, 2016, 04:06 pm by danyevo
Puoi farmi un esempio piu completo che non riesco a capire
Grazie

Go Up