Go Down

Topic: Lettura Stringa android arduino (Read 274 times) previous topic - next topic

DANI9191

Buonasera a tutti.
Se possibile avrei bisogno di un aiuto. Sto provando a creare un app in android studio che comunica con arduino tramite lan, i dati inviati da arduino verso android li leggo e funzion bene,ma viceversa non so come gestire una lunga stringa contenente piu informazioni che da android arriva ad arduino.
 Questo è quello che invio con android, (questo è solo un esempio per riuscire a capire il concetto).


String setT1="50";
String setT2="50";// al momento valori fissi,poi saranno cambiati con un editText
String setT3="50;

("Temp1=" + setT1 + "," + "Temp2= " + setT2 + "," + "Temp3=" + setT3);
Come vedete sono 3 variabili nominative con 3 diversi valori separati da una ","

Dal lato arduino ricevo la stringa cosi:

String request= read.stringUnitl(\r);
Il mio problema è come faccio a separare la stringa e prelevare il valore?

int setT1;// andra il valore di Temp1
int setT2;// andra il valore di Temp2
int setT3;//andra il valore di Temp3

Un amico mi aveva gia spiegato come fare

if( request.idexOf(Temp1=)==0);
int t=&request[6]; // naturalmente convertendo la stringa in int

ma questo funziona bene solo se ho un singolo valore, ma nel mio caso ho piu valori, separati da una ","

Ho provato anche con substring(6,8), ma il problem è che il valore da prelevare puo essere da 1 carattere o anche 3 caratteri. Spero di essermi spiegato bene.

Ps.come avrete capito sono un dilettante.
Ps2.per correttezza vi dico che ho chiesto aiuto anche altrove,ma a quanto pare sembra che si impossibile quello che voglio fare..
Help me grazie

fabpolli

#1
Apr 03, 2019, 09:26 am Last Edit: Apr 03, 2019, 09:33 am by fabpolli
Ciao, primo problema l'uso della classe String, se cerchi sul forum troverai una quantità imbarazzante di post che dicono di NON usare la classe String ma di usare le stringhe classiche del C (vettore di caratteri). Questo perché sul momento sembra funzionarti a dovere dopo un po' che il programma è in funzione ci sono ottime possibilità che il programma si blocchi all'improvviso senza apparente motivo, solo apparente perché il motivo c'è ed è ben noto ovvero la frammentazione e saturazione della memoria derivante dall'uso della classe String.
Detto ciò la base su cui ti consiglio di partire è questa:
Leggere la stringa in ingresso e inserirla in un array di caratteri
Quando l'hai letta tutta, processarla con la funzione strtok visto che non sai esattamente dove è posizionata la virgola (il tuo separatore). Ogni volta che hai, mediante la funzione sopra citata, la porzione di stringa da analizzare ci sono due possibilità, la prima è che hai 9 o meno temperature quindi sai esattamente dove si trova il carattere che identifica la temperatura (Es. Temp1, Temp2) prelevando il quindto carattere puoi semplicemente determinare quale temperatura stai analizzando, se invece sono dieci o più occorre proseccare ulteriormente la stringa cercando il carattere =, eliminare la parte fissa Temp e quello che resta sarà il numero della temperatura che stai analizzando ma nel caso ci torneremo in seguito.
Seguendo la strada delle 9 o meno temperature sai anche dove inizierà il valore delle temperatura ricevuta e copiando questa porzione di stringa tramite la funzione strncpy e trasformandola in intero tramite la funzione atoi avrai il valore.
Se invece sono valori con anche la parte decimale separata dal punto allora la funzione da usare è un altra ma casomai ci torniamo su anche su questo.
Ok ti ho ubriacato abbastanza credo  :)
Parti con la base del programma ovvero ricevi la stringa su un array di char opportunamente dimensionato (ovvero che possa contenere la stringa che ricevi) e posta il codice se non funziona o se vuoi un riscontro sulla correttezza, dopodiché procediamo con i punti successivi.

DANI9191

Ok grazie della risposta,Si sono piu confuso di prima :)

Ok allora andiamo per gradi vedo di riuscire a capire intanto come funziona la stringa classica del C.

Vi aggiorno

DANI9191

#3
Apr 03, 2019, 07:48 pm Last Edit: Apr 03, 2019, 07:49 pm by DANI9191
Allora sto provando qualche esempio in base alla guida che mi hai linkato, ma mi stampa solo la prima parte di stringa tutto il resto dopo la "," non me lo stampa sulla seriale.

Spero di aver capito quello che mi hai detto


  char request[50];
  const char s[2] = ",";
  char *token;
  char dest[12];

String request2= client.readStringUntil('\r'); //leggo la stringa(get/,TD:50,PD:50,PlD:50,HTTP/1.1
);

 request2.toCharArray(request, 50); //la converto in array
 token = strtok(request, s);//spezzetto la striga ad ogni ","   ?

Serial.print(token);  //mi stampa solo get / (tutto il resto viene ignorato)

Questo è quello che invio con android
invia( "," +"TD:" + (SetTTh2oDesiderato) + "," + "PD:" + (SetTh2oPDesiderato) + "," + "PlD:" + (SetTPh2oDesiderato)+ ",");



gpb01

#4
Apr 03, 2019, 08:16 pm Last Edit: Apr 03, 2019, 08:16 pm by gpb01
>DANI9191:   ti ricordo che in conformità al regolamento, punto 7, devi editare il tuo post (quindi NON scrivendo un nuovo post, ma utilizzando il bottone More -> Modify che si trova in basso a destra del tuo post) e racchiudere il codice all'interno dei tag CODE (... sono quelli che in edit inserisce il bottone con icona fatta così: </>, tutto a sinistra).

In pratica, tutto il tuo codice dovrà trovarsi racchiuso tra due tag: [code] _il _tuo_ codice_ [/code] così da non venire interpretato e non dare adito alla formazione di caratteri indesiderati o cattiva formattazione del testo. Grazie. :)

Guglielmo
Search is Your friend ... or I am Your enemy !

docdoc

#5
Apr 03, 2019, 08:19 pm Last Edit: Apr 03, 2019, 08:20 pm by docdoc
token = strtok(request, s);//spezzetto la striga ad ogni ","   ?
Serial.print(token);  //mi stampa solo get / (tutto il resto viene ignorato)
La strtok() non "spezzetta" nulla, non è mica la "Split()" di altri linguaggi... La strtok() ti dà il puntatore alla prima occorrenza, poi la usi ciclicamente per determinare i successivi (passando, dalla seconda in poi, puntatore nullo).
Vedi QUI una spiegazione della funzione.
Se programmi in C devi scordarti String e altre cose di linguaggi di alto livello... ;)
Alex "docdoc"
- "Qualsiasi cosa, prima di rompersi, funzionava"

DANI9191

Perdon Guglielmo, dovrebbe essere cosi,giusto?

Ok ora funziona

Code: [Select]

con android invio direttamente i valori senza i caratteri tanto essendo in seguenza so a cosa corrispondono e mi arriva cosi la stringa "get / ,50,50,50,http1.1"

String datiRicevuti= client.readStringUntil('\r');//
 
  char dati[50];
  char *vettore;
  char divisore[]=",";
 
  int valori[4]={0,0,0,0};
   
  datiRicevuti.toCharArray(dati, 50);
  vettore=strtok(dati,divisore);
 
for(int i=0; i<4;i++){
  valori[i]=atoi(vettore);
  Serial.println(valori[i]);
  vettore=strtok(NULL,divisore);
}

  setT=valori[1];
  setPu=valori[2];
  setP=valori[3];


Pero avrei ancora altri 2 dubbi,
 
>fabpolli:con questo sistema, se ho piu di 10 valori da leggere funziona lo stesso?


 >gpb01:Se programmi in C devi scordarti String e altre cose di linguaggi di alto livello... ;), intedi questa riga? String datiRicevuti= client.readStringUntil('\r'); ho provato a scrivere char datiRicevuti[50]= client.readStringUntil('\r'); ma non funziona mi da errore,cosa sto sbagliando?

ps.. come faccio a editare un pezzo di messaggio?

gpb01

#7
Apr 04, 2019, 08:25 pm Last Edit: Apr 04, 2019, 08:25 pm by gpb01
ps.. come faccio a editare un pezzo di messaggio?
... seguendo quanto ti ho dettagliatamente scritto nel mio post #4 che infatti ti chiedeva di editare il tuo post #3 NON di riscriverlo ;)

Guglielmo

P.S.: è docdoc che ti ha detto di NON usare la classe "String" non io, ma mi associo al suo consiglio.
Search is Your friend ... or I am Your enemy !

DANI9191


fabpolli

#9
Apr 05, 2019, 09:26 am Last Edit: Apr 05, 2019, 09:28 am by fabpolli
Code: [Select]

con android invio direttamente i valori senza i caratteri tanto essendo in seguenza so a cosa corrispondono e mi arriva cosi la stringa "get / ,50,50,50,http1.1"

String datiRicevuti= client.readStringUntil('\r');//
  
for(int i=0; i<4;i++){
  valori[i]=atoi(vettore);
  Serial.println(valori[i]);
  vettore=strtok(NULL,divisore);
}

>fabpolli:con questo sistema, se ho piu di 10 valori da leggere funziona lo stesso?

Si funziona con N valori in arrivo, solo due cose al posto del for che potrebbe portare a risultati catastrofici se ti arrivano per qualsivoglia motivo un numero inferiore di valori fai anzi una cosa simile a questa:
Code: [Select]

byte valoreAttuale = 0;
while(vettore != NULL)
{
  valori[valoreAttuale]=atoi(vettore);
  Serial.println(valori[valoreAttuale]);
  valoreAttuale ++;
  vettore=strtok(NULL,divisore);
}

E comunque mi associo al coro e ribadisco il mio suggerimento del post #2, non usare la classe String, tu la stai ancora usando per ricevere il dato, non è che se la usi poco allora risolvi il problema leggi un carattere alla volta in arrivo e mettili direttamente nell'array di destinazione, altrimenti il problema salterà fuori comunque, più tardi forse ma saltera fuori
[/code]

DANI9191

Ok penso di aver capito, mi sfuggiva ancora il fatto della lettura della stringa allora leggo i singoli caratteri,questa sera provo

DANI9191

Si funziona con N valori in arrivo, solo due cose al posto del for che potrebbe portare a risultati catastrofici se ti arrivano per qualsivoglia motivo un numero inferiore di valori fai anzi una cosa simile a questa:

Funziona perfettamente, l array di caratteri un po meno,devo studiarmi meglio il funzionamento,perche mi fa la lettura,arrivato a un certo punto si blocca tutto,ma ci ritorno dopo, ora ho un problema con la ethernet shield w5100, con arduino uno funziona perfettamente,ma il progetto finale e basato su arduino mega,oggi lo testato,ma non so per quale motivo non funziona nulla. Sul monitor seriale a volte mi dice connesso all ip 255.255.255.255 e  volte 0.0.0.0, mentre l ip che io ho assegnato è 192.168.0.1. Il modulo e connesso tramite il connettore icps.
Intanto ancora un grazie a tutti per i prezziosi aiuti.

Go Up