Go Down

Topic: Uso libreria Stream e readtString (Read 1 time) previous topic - next topic

AnTrea

Oct 08, 2012, 01:14 pm Last Edit: Oct 09, 2012, 03:29 pm by Trisonic Reason: 1
Salve

Sto giocando con lo sketch webclient dall'ide di arduino.
Ho modificato un pò il codice e ho scritto questa funzioncina:

Code: [Select]
void myPrint()
{
 //char c;
 Serial.println("Simple print...");
 while (client.connected()){  
  if (client.available())
   {
     //Serial.println("hi");
     char c = client.read();
     Serial.print(c);
   }
 }
}



Come posso fare in modo che alla fine di tutta la stampa della risposta del server sulla GET si sconnetta?

Vorrei una cosa del genere: GET -> Stampa tutto -> disconnetti

Non riesco ad innestare una buona condizione di chiusura sul loop... consigli?

In pratica non voglio che la connessione scadi... la devo sconnettere io appena finito di leggere la risposta.
Arduino, MODs e DIY: blackstufflabs.com

AnTrea

#1
Oct 08, 2012, 04:34 pm Last Edit: Oct 08, 2012, 04:39 pm by Trisonic Reason: 1
Alla fine mi sono creato una cosa artigianale:

mi costruisco una stringa byte per byte, quando arrivo ad una sottostringa precisa chiudo la connessione.
Code: [Select]
inChar = client.read();     
      myAvviso += inChar;
      if (myAvviso.endsWith("publishing_date")){
          client.stop();


il problema adesso si pone nel gestire le stringhe molto lunghe....
teoricamente l'oggetto stringa quanto può essere grande?
dopo alcune iterazioni noto che mi tronca l'oggetto string...

....sto cercando di realizzare qualcosa simile ad un rss reader, devo mettere ogni contenuto in una stringa e giocarci.
Arduino, MODs e DIY: blackstufflabs.com

BigByte

Ciao, non credi che cosi corri il rischio di usare tutta la memoria? e se per lo stop del loop ti fai mandare il numero di caratteri che il client intende inviare?

Ciao

AnTrea


Ciao, non credi che cosi corri il rischio di usare tutta la memoria? e se per lo stop del loop ti fai mandare il numero di caratteri che il client intende inviare?

Ciao


Certo che corro il rischio... è tutto in prova.

Se non erro, client.available() dovrebbe fare ciò che dici nella seconda domanda giusto?
Mi ritorna sempre 0...
Arduino, MODs e DIY: blackstufflabs.com

lesto

le stringhe anno potenzialmente lunghezza infinita. Non so come lavora lo shield, ma in teoria ilpacchetto TCP arriva con un MTU noto (lughezza massima del pacchetto, quindi un messaggio più lungo viene spezzato in più pacchetti, e può capitare che venga spezzato in pacchetti più picoli se una parte della rete usa MTU più piccoli). normamente l'MTU è di 1500byte, quindi credo che sia infattibile di base per l'arduino.

non usare endsWith ma leggi byte per byte, considerando che stai implementando a partire dal TCP, ti convene creare un tuo protocollo, e quindi decidi tu la lughezza massima e vari altri parametri. Internet è una brutta bestia, devi fare molta attenzione se esci dalla rete locale.
Il mio approccio in questi casi è chiudere la connessione al minimo errore.
sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

AnTrea


non usare endsWith ma leggi byte per byte, considerando che stai implementando a partire dal TCP, ti convene creare un tuo protocollo, e quindi decidi tu la lughezza massima e vari altri parametri. Internet è una brutta bestia, devi fare molta attenzione se esci dalla rete locale.
Il mio approccio in questi casi è chiudere la connessione al minimo errore.


Sto provando con la libreria textfinder, che fa tutto byte per byte....
Mi semplifica molto la cosa ma... per ora non mi funge la getstring
Arduino, MODs e DIY: blackstufflabs.com

AnTrea

#6
Oct 08, 2012, 06:29 pm Last Edit: Oct 08, 2012, 06:37 pm by Trisonic Reason: 1
Ho cambiato il codice del primo post a favore dell'uso delle funzioni offerte dalla libreria TextFinder (http://www.arduino.cc/playground/Code/TextFinder) che lavora byte by byte

Code: [Select]
void parse()
{
  //String myAvviso = "";
  char myAvviso[500];
  Serial.println("Parsing");
  if (finder.find("title") && finder.getString("title","studenti",myAvviso,500))
  {
    Serial.println("Avviso trovato!");
    //finder.getString("title","publishing",myAvviso,100);
    Serial.println("Avviso: ");
    Serial.println(myAvviso);     
  }
  else
  {   
    Serial.println("Failed parsing...");
   // client.stop();
  }
}



Il mio problema adesso è che ho bisogno di un buffer molto grande (quindi torniamo al problema di prima) per contenere tanto testo compreso tra "title" e "studenti".
L'array di char è troppo piccolo, e se lo aumento inizio ad avere problemi.

Consigli?
Arduino, MODs e DIY: blackstufflabs.com

pablos

Secondo me manca sempre nelle domande.

"vorrei fare con una ethernet e un display .............ecc " (piccolo riassunto del risultato che si vuole ottenere)
no comment

AnTrea


Secondo me manca sempre nelle domande.

"vorrei fare con una ethernet e un display .............ecc " (piccolo riassunto del risultato che si vuole ottenere)


Devo realizzare una specie di rss reader, l'hardware da me utilizzato è questo: http://arduino.cc/forum/index.php/topic,126220.0.html

Mi sono messo in contatto con chi ha scritto la libreria TextFinder e mi ha detto che le funzioni sono state migliorate e incluse nel core di arduino dalla versione dell'ide 1.0 (mi pare) in poi.
Mi ha consigliato di usare la funzione readString però non ho trovato molta documentazione sulla libreria Stream: http://arduino.cc/en/Reference/Stream
Infatti non c'è la readString tra la documentazione, sono costretto a spulciare il file sorgente all'interno del core per vedere come e cosa fa....
...male non mi fa! :)
Arduino, MODs e DIY: blackstufflabs.com

lesto

dovremmo fare una copia del reference sul palyground e sistemarlo per bene..
ci sono un sacco di funzioni interessanti non documentate
sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

AnTrea


dovremmo fare una copia del reference sul palyground e sistemarlo per bene..
ci sono un sacco di funzioni interessanti non documentate


Quindi non mi ero sbagliato che mancano un pò di funzioni nuove sul reference?!

Mi sono letto 4/5 volte QUELLA pagina e non riuscivo a trovare readString(), pensavo di avere qualche problema di lettura.... lettura dei miei occhi...  :.
Arduino, MODs e DIY: blackstufflabs.com

BigByte

e se modifichi il metodo getString aggiungendo da quale punto vuoi iniziare a leggere, provo a fare un esempio

Code: [Select]

//questo nella libreria
int TextFinder::getString( char *pre_string, char *post_string, char *buffer,int start, int length)
  { 
    if( find(pre_string) ){
      int index = 0;   
      *buffer = 0;
      while(index < length-1 ){
       
char c = myRead();

if(start == 0)
{       
if( c == 0 ){
return 0;   // timeout returns 0 !
}
else if( c == *post_string ){
buffer[index] = 0; // terminate the string
return index;               // data got successfully
}
else{
buffer[index++] = c;   
}
}
else
{
start--;
}
      }
 
      buffer[index] = 0;
      return index; // Note: buffer full before the closing post_string encountered
    }   
    return 0;    //failed to find the prestring
  }

// le tuo codice fai una cosa tipo

char myAvviso[500];
  int len = 0; 
 
  while (client.available()) {             
len = len + finder.getString("title","studenti",myAvviso,len,500);
--aggiungo myAvviso[] i in una memoria + grande esempio SD
  }



non so se funziona non l'ho provato ma vedi se può esserti utile

lesto

#12
Oct 09, 2012, 03:20 pm Last Edit: Oct 09, 2012, 03:23 pm by lesto Reason: 1
visto che la mole di dati probabilmente non ti starà in memoria, la soluzione è avere un piccolo buffer circolare; immagino che ci sia un tag particolare che cerchi per individuare l'inizio e la fine dei messaggi che ti interessano.

a questo punto hai 2 stati da gestire:

stato 1: riempi len(tagInizio) buffer e cerchi il tag di inizio. Se lo trovi carichi il buffer fino a quando il tag di inizio non ne esca ed entri nello stato 2
stato 2: cerchi il tag di fine. copi il contenuto del buffer fino alla fine o all'eventiale tag di fine in una string. Se hai trovato il tag di fine, elimina l'eventuale parziale di tag fine ed elabora la stringa ed entra nello stato 1. se non la trovi, riempi il buffer di len(tagFine) (ricordati da dove sei arrivato a salvare eh!) e ricomincia lo stato 2

in questo modo con un piccolo buffer (grande almeno quanto il massimo tra la lungheza id tag di inizio e di tag fine) sei in grado di leggere infiniti mesaggi. Sta a te a questo punto fare in modo che i mesaggio salvato durante la fase 2 non sfondi la ram. per esempio puoi dire che a priori lo stato 2 non può leggere più di X lettere, e quindi esce anche in caso di tag fine on trovato ma limite raggiunto.

oppure non salvi ed elabori la stringa completa, ma elabori ad ogni stato2 la stringa parziale col rischio però di elaborare anche il tag fine quando ti arriva parziale. per eliminare il problema ad ogni lettura viene eseguita la stringa precedente se il tag fine non viene trovato, altrimenti si triggera il cambio stato a 1 che si occupa di eliminare il tag fine e ricrearti il partziale del turno precedente+questo turno pulito del tag
sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

AnTrea

#13
Oct 09, 2012, 03:29 pm Last Edit: Oct 09, 2012, 03:42 pm by Trisonic Reason: 1

in questo modo con un piccolo buffer (grande almeno quanto il massimo tra la lungheza id tag di inizio e di tag fine) sei in grado di leggere infiniti mesaggi.


E' proprio quello che sto cercando di fare da qualche giorno!
Ma un pò per la scarsa documentazione, un pò per i limiti hardware e software, un pò per piedinature comuni (vedi l'altro post), ancora non sono riuscito a realizzare ciò.

Il problema che mi/vi pongo è:
Se il messaggio tra tag inizio e tag fine è bello lungo.... diciamo 1000char, rischio overflow?
O meglio, cosa succede all'arduino se durante l'esecuzione cattura una stringa tale da far andare in overflow la ram? si resetta? tronca? non compila? cosa fa in running?
Vorrei capire questo particolare in modo tale da accorgermi se qualcosa non va.




e se modifichi il metodo getString aggiungendo da quale punto vuoi iniziare a leggere, provo a fare un esempio


Grazie per l'aiuto!

Come ho scritto prima, questi metodi sono stati modificati e migliorati nella classe Stream.
Credo che utlizzerò queste funzioni con qualche idea che mi è venuta prima e che ho scritto poche righe più su.
Arduino, MODs e DIY: blackstufflabs.com

AnTrea

...forse è meglio cattuare la stringa a gruppi di Xchar, stamparli, ricatturare Xchar da Xchar+1
fino al tag di fine e amen...

un pò più macchinoso ma mi evito problemi di overflow
Arduino, MODs e DIY: blackstufflabs.com

Go Up