Lettura seriale dati su arduino Aiuto

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.

Ma il dato inviato ha lunghezza fissa, sempre 1 carattere e poi due cifre ? Anche cifra 5 = a05 ? 3 caratteri ?

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

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

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

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ì.

Guarda l'esempio che ti ho fatto sopra

char str2[MAX_STR];

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

Dovrebbe essere equivalente.

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

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

nid69ita:
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.

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#”

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

MA TE L'HO SCRITTO SOPRA!!!

scusami ma non riesco a capire. è questa:

char str2[MAX_STR];

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

Sì!

Puoi farmi un esempio piu completo che non riesco a capire
Grazie

Non riesci a capire cosa, di preciso? Una stringa è un vettore di char in C, e si copia con strcpy() o strncpy(). Si possono saltare i primi N caratteri semplicemnte sommando N al puntatore alla stringa.

Occhio però che anche la strcpy() si aspetta di trovare il fine stringa NULL '\0' (terminatore)
Tanto vale usare direttamente la strtol() per convertire dal char+1 come dicevo prima.
Ma come detto do @astro, DEVI avere la stringa memorizzata in un array di char e terminata da carattere di fine stringa.

@dany perdona ma quell'esempio VB non è ammissibile! In vb ragioni su una stringa completa mentre in Arduino con la serial.read() ricevi 1 char alla volta. Quindi, nel tuo codice, dove hai messo i dati ricevuto ? Posta un benedetto pezzo di codice ARDUINO, del vb chissefrega. la strcpy fa tipo la mid() ma scimiottare il VB in C è un non sense.

nid69ita:
Ma come detto do @astro, DEVI avere la stringa memorizzata in un array di char e terminata da carattere di fine stringa.

Esatto, il primo problema da risolvere è avere un array di char terminato con 0x00, in alternativa conoscere l'esatta lunghezza, perché dalla seriale, non importa se hardware o software, ottieni solo una sequenza di byte, tipicamente uno per volta, nell'ordine di ricezione.
Come ho già spiegato i modi più semplici per procedere sono inserire un carattere univoco, durante la trasmissione, che identifica la fine del pacchetto dati, oppure usare un time out, le alternative sono decisamente più complesse da gestire, sopratutto con wiring in mezzo alle scatole che lascia zero controllo sulla seriale.

In verità mi pare di capire che lui abbia sempre stringhe di un numero fisso di caratteri. Per cui basta leggerne altrettanti dalla seriale, quindi processare. Per quello ho usato strncpy() nel mio suggerimento, senza preoccuparmi troppo della terminazione della stringa.

Mi dispiace ma non ci capisco più niente esiste un esempio completo per farmi capire come funziona?
lasciamo perdere i miei esempi e cominciamo da capo.
allora mettiamo che io ho un arduino con collegato 10 sensori di temperatura e via seriale devo inviare i dati ad un altro arduino, come faccio a leggerli e inviarli ad un display che mi scrive tutte e 10 le temperature separate?
Vi avverto che non sono un veterano vi ringrazio per la pazienza