Ciao a tutti, ho un problemino con la ricezione di una stringa da seriale. Al momento utilizzo il seguente codice:
int i;
char c;
void setup() {
Serial.begin(9600);
}
void loop() {
if (Serial.available()) {
char stringa[5];
i=0;
do {
if (Serial.available()) {
c = Serial.read();
if (c != '\n'){
stringa[i]=c;
i++;
}
}
} while (c != '\n');
Serial.println(stringa);
}
}
Il codice funziona; chiaramente devo impostare nella schermata del monitor seriale di inviare il carattere di fine riga, altrimenti non può funzionare. Siccome Arduino dovrà ricevere una stringa tramite bluetooth da un cellulare (app android), sull'applicazione non ho modo di far inviare anche il carattere di fine riga, pertanto questo codice non funzionerebbe. Per intenderci sull'applicazione ci sarà una text-box in cui verrà inserita la stringa da inviare. Avevo pensato di utilizzare un ciclo for invece che un do-while, visto che sono a conoscenza della lunghezza massima della stringa. In particolare la lunghezza della stringa varia tra 3 e 5 caratteri. Potrebbe essere un'idea? Mi serve ricevere una stringa da bluetooth perchè sto realizzando un plastico di una casa domotica; la stringa opportunamente interpretata comanderà un punto luce (con lunghezza di tre caratteri) oppure sarà il codice dell'antifurto (con lunghezza di cinque caratteri). Spero di essere stato chiaro...
Grazie come sempre...
ciao...ma l'app del cellulare, quella che invierà la stringa di comando, chi l'ha scritta!?...nel senso...se l'hai scritta tu fai in modo di accodare, prima dell'invio, il '\n' alla fine del messaggio digitato...se non l'hai scritta tu ...che app è!?
Non è il massimo dell'eleganza... ma puoi usare un qualunque carattere come terminatore...
Se decidi di usare il carattere * quando scrivi nel textbox dell'app il comando alla fini scrivi anche l'...
Ovviamente nel tuo sketch controlli '' invece di '\n'.
L'applicazione è Bluetooth Electronics e permette di inviare un eventuale carattere terminatore, senza ovviamente che sia l'utente a digitarlo. Non funziona con "\n" perchè quando lo digito nella schermata di impostazione dell'applicazione, in realtà esso si compone di due caratteri: "" e "n" che (presumo) vengono spediti dal cellulare come due caratteri separati e il mio codice fallisce. Ho quindi usato un carattere terminatore qualsiasi (in tal caso 'z') e sembra funzionare. Mi sorgono però due problemi: siccome il vettore di char che utilizzo è di 4 elementi
(5 elementi meno il carattere di fine \0) se invio una stringa di 2 elementi, mi viene in realtà restituita una stringa di 4, in cui gli ultimi due elementi sono dei caratteri "strani" (due quadrati). Non mi spiego come sia possibile visto che faccio gli opportuni controlli sulla disponibilità della seriale (Bluetooth).
Il secondo problema è il seguente: se digito una stringa più lunga della stringa che ho dichiarato, la ricezione avviene comunque; pensavo invece che ciò avrebbe causato qualche errore. Sicuramente sarà dovuto a una gestione non proprio corretta della stringa; purtroppo non conosco molto bene le stringhe in c. Sapete darmi una dritta su come evitare di ricevere stringhe più lunghe di un certo limite?
Vi posto il nuovo codice.
#include <SoftwareSerial.h>
SoftwareSerial bluetooth(2, 3);
char c;
int i;
void setup() {
Serial.begin(9600);
bluetooth.begin(9600);
}
void loop() {
if (bluetooth.available()) {
char stringa[5];
i = 0;
do {
if (bluetooth.available()) {
c = bluetooth.read();
if (c != 'z') {
stringa[i] = c;
i++;
}
}
} while (c != 'z');
Serial.println(stringa);
}
}
Grazie ancora e spero di essere stato sufficientemente chiaro!
Ale_S:
se invio una stringa di 2 elementi, mi viene in realtà restituita una stringa di 4, in cui gli ultimi due elementi sono dei caratteri "strani" (due quadrati). Non mi spiego come sia possibile visto che faccio gli opportuni controlli sulla disponibilità della seriale (Bluetooth).
Probabilmente tu ne ricevi 2 ma ne visualizzi 4... in questo caso gli ultimi 2 caratteri dipendono da quello che c'è nella memoria di arduino... Prova a inizializzare il vettore con AAAA e prova ad inviare dal cell BB. Se a video ti visualizza BBAA allora è come dico io.
Ale_S:
Il secondo problema è il seguente: se digito una stringa più lunga della stringa che ho dichiarato, la ricezione avviene comunque; pensavo invece che ciò avrebbe causato qualche errore.
Se ricevi più caratteri della lunghezza del vettore vai a scriverli sulla memoria "oltre" il vettore... se quella memoria è libera poco male... se è occupata da altro lo vai a sovrascrivere e potresti avere dei malfunzionamenti del codice.
Ale_S:
Sapete darmi una dritta su come evitare di ricevere stringhe più lunghe di un certo limite?
Tu controlli solo l'arrivo del terminatore. Dovresti controllare anche a quanto arriva i... se supera la lunghezza del vettore ti fermi.
I tuoi problemi sono dovuti al fatto che non aggiungi il carattere terminatore stringa '\0', in quel modo non può stabilire quando la stringa termina e stampa più caratteri strani. Se inserisci invece una stringa più lunga, saranno comunque salvati in memoria, ma una parte di memoria ram non "riservata" all'array, esempio l'array e di 5 elementi e tu inserisci dieci caratteri, verranno inseriti nelle celle di memoria successiva alla quinta, ma questa memoria non è riservata all'array, quindi può essere scritta da altri dati, ma se questo non avviene rimarranno li e tu li visualizzi "per casualità".
Esempio di soluzione al tuo problema
#include <SoftwareSerial.h>
SoftwareSerial bluetooth(2, 3);
char c;
int i;
void setup() {
Serial.begin(9600);
bluetooth.begin(9600);
}
void loop() {
if (bluetooth.available()) {
char stringa[5];
i = 0;
do {
if (bluetooth.available()) {
c = bluetooth.read();
if (c != 'z') {
stringa[i] = c;
i++;
}
}
} while (c != 'z');
stringa[i]='\0'; // Aggiungo il terminatore stringa, la variabile i sara lunghezza stringa +1, perché
// viene incrementata nel ciclo, ultimo carattere stringa[i]=c; e poi i++
Serial.println(stringa);
}
}
Quando nel programma dovrai confrontare le stringhe, usa la funzione strcmp(stringa,"parola");
Grazie per le risposte. Ho compreso il problema e penso di aver capito anche la soluzione. Appena ho tempo provo su Arduino. Nel caso vi domanderò ancora...