# Lettura seriale dati su arduino Aiuto

**URL:** <https://forum.arduino.cc/t/lettura-seriale-dati-su-arduino-aiuto/378788>\
**Category:** Software\
**Created:** [April 10, 2016, 10:27pm UTC](https://forum.arduino.cc/t/lettura-seriale-dati-su-arduino-aiuto/378788 "2016-04-10T22:27:00Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![danyevo](https://avatars.discourse-cdn.com/v4/letter/d/f04885/32.png) [@danyevo](https://forum.arduino.cc/u/danyevo)\
**Post date:** [April 10, 2016, 10:27pm UTC](https://forum.arduino.cc/t/lettura-seriale-dati-su-arduino-aiuto/378788/1 "2016-04-10T22:27:00Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![nid69ita](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/nid69ita/32/901258_2.png) [@nid69ita](https://forum.arduino.cc/u/nid69ita)\
**Post date:** [April 11, 2016, 7:04am UTC](https://forum.arduino.cc/t/lettura-seriale-dati-su-arduino-aiuto/378788/2 "2016-04-11T07:04:02Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![danyevo](https://avatars.discourse-cdn.com/v4/letter/d/f04885/32.png) [@danyevo](https://forum.arduino.cc/u/danyevo)\
**Post date:** [April 11, 2016, 7:21am UTC](https://forum.arduino.cc/t/lettura-seriale-dati-su-arduino-aiuto/378788/3 "2016-04-11T07:21:40Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![danyevo](https://avatars.discourse-cdn.com/v4/letter/d/f04885/32.png) [@danyevo](https://forum.arduino.cc/u/danyevo)\
**Post date:** [April 11, 2016, 7:47am UTC](https://forum.arduino.cc/t/lettura-seriale-dati-su-arduino-aiuto/378788/4 "2016-04-11T07:47:58Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![SukkoPera](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/sukkopera/32/215233_2.png) [@SukkoPera](https://forum.arduino.cc/u/SukkoPera)\
**Post date:** [April 11, 2016, 7:52am UTC](https://forum.arduino.cc/t/lettura-seriale-dati-su-arduino-aiuto/378788/5 "2016-04-11T07:52:34Z")

</div>

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

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

---

<div class="post-metadata">

**Author:** ![danyevo](https://avatars.discourse-cdn.com/v4/letter/d/f04885/32.png) [@danyevo](https://forum.arduino.cc/u/danyevo)\
**Post date:** [April 11, 2016, 8:07am UTC](https://forum.arduino.cc/t/lettura-seriale-dati-su-arduino-aiuto/378788/6 "2016-04-11T08:07:41Z")

</div>

Guarda l'esempio che ti ho fatto sopra

---

<div class="post-metadata">

**Author:** ![SukkoPera](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/sukkopera/32/215233_2.png) [@SukkoPera](https://forum.arduino.cc/u/SukkoPera)\
**Post date:** [April 11, 2016, 8:21am UTC](https://forum.arduino.cc/t/lettura-seriale-dati-su-arduino-aiuto/378788/7 "2016-04-11T08:21:48Z")

</div>

```cpp
char str2[MAX_STR];

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

```

Dovrebbe essere equivalente.

---

<div class="post-metadata">

**Author:** ![nid69ita](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/nid69ita/32/901258_2.png) [@nid69ita](https://forum.arduino.cc/u/nid69ita)\
**Post date:** [April 11, 2016, 9:10am UTC](https://forum.arduino.cc/t/lettura-seriale-dati-su-arduino-aiuto/378788/8 "2016-04-11T09:10:59Z")

</div>

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

```cpp
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

```

---

<div class="post-metadata">

**Author:** ![astrobeed](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/astrobeed/32/214099_2.png) [@astrobeed](https://forum.arduino.cc/u/astrobeed)\
**Post date:** [April 11, 2016, 9:21am UTC](https://forum.arduino.cc/t/lettura-seriale-dati-su-arduino-aiuto/378788/9 "2016-04-11T09:21:07Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![nid69ita](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/nid69ita/32/901258_2.png) [@nid69ita](https://forum.arduino.cc/u/nid69ita)\
**Post date:** [April 11, 2016, 10:05am UTC](https://forum.arduino.cc/t/lettura-seriale-dati-su-arduino-aiuto/378788/10 "2016-04-11T10:05:15Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![danyevo](https://avatars.discourse-cdn.com/v4/letter/d/f04885/32.png) [@danyevo](https://forum.arduino.cc/u/danyevo)\
**Post date:** [April 11, 2016, 11:37am UTC](https://forum.arduino.cc/t/lettura-seriale-dati-su-arduino-aiuto/378788/11 "2016-04-11T11:37:06Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![SukkoPera](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/sukkopera/32/215233_2.png) [@SukkoPera](https://forum.arduino.cc/u/SukkoPera)\
**Post date:** [April 11, 2016, 12:24pm UTC](https://forum.arduino.cc/t/lettura-seriale-dati-su-arduino-aiuto/378788/12 "2016-04-11T12:24:14Z")

</div>

MA TE L'HO SCRITTO SOPRA!!!

---

<div class="post-metadata">

**Author:** ![danyevo](https://avatars.discourse-cdn.com/v4/letter/d/f04885/32.png) [@danyevo](https://forum.arduino.cc/u/danyevo)\
**Post date:** [April 11, 2016, 1:40pm UTC](https://forum.arduino.cc/t/lettura-seriale-dati-su-arduino-aiuto/378788/13 "2016-04-11T13:40:02Z")

</div>

scusami ma non riesco a capire. è questa:

char str2[MAX\_STR];

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

---

<div class="post-metadata">

**Author:** ![SukkoPera](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/sukkopera/32/215233_2.png) [@SukkoPera](https://forum.arduino.cc/u/SukkoPera)\
**Post date:** [April 11, 2016, 2:03pm UTC](https://forum.arduino.cc/t/lettura-seriale-dati-su-arduino-aiuto/378788/14 "2016-04-11T14:03:59Z")

</div>

Sì!

---

<div class="post-metadata">

**Author:** ![danyevo](https://avatars.discourse-cdn.com/v4/letter/d/f04885/32.png) [@danyevo](https://forum.arduino.cc/u/danyevo)\
**Post date:** [April 11, 2016, 2:05pm UTC](https://forum.arduino.cc/t/lettura-seriale-dati-su-arduino-aiuto/378788/15 "2016-04-11T14:05:52Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![SukkoPera](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/sukkopera/32/215233_2.png) [@SukkoPera](https://forum.arduino.cc/u/SukkoPera)\
**Post date:** [April 11, 2016, 2:15pm UTC](https://forum.arduino.cc/t/lettura-seriale-dati-su-arduino-aiuto/378788/16 "2016-04-11T14:15:19Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![nid69ita](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/nid69ita/32/901258_2.png) [@nid69ita](https://forum.arduino.cc/u/nid69ita)\
**Post date:** [April 11, 2016, 2:20pm UTC](https://forum.arduino.cc/t/lettura-seriale-dati-su-arduino-aiuto/378788/17 "2016-04-11T14:20:11Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![astrobeed](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/astrobeed/32/214099_2.png) [@astrobeed](https://forum.arduino.cc/u/astrobeed)\
**Post date:** [April 11, 2016, 2:24pm UTC](https://forum.arduino.cc/t/lettura-seriale-dati-su-arduino-aiuto/378788/18 "2016-04-11T14:24:38Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![SukkoPera](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/sukkopera/32/215233_2.png) [@SukkoPera](https://forum.arduino.cc/u/SukkoPera)\
**Post date:** [April 11, 2016, 2:37pm UTC](https://forum.arduino.cc/t/lettura-seriale-dati-su-arduino-aiuto/378788/19 "2016-04-11T14:37:15Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![danyevo](https://avatars.discourse-cdn.com/v4/letter/d/f04885/32.png) [@danyevo](https://forum.arduino.cc/u/danyevo)\
**Post date:** [April 11, 2016, 2:51pm UTC](https://forum.arduino.cc/t/lettura-seriale-dati-su-arduino-aiuto/378788/20 "2016-04-11T14:51:12Z")

</div>

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

[Next page](https://forum.arduino.cc/t/lettura-seriale-dati-su-arduino-aiuto/378788.md?page=2)
