Pages: [1]   Go Down
Author Topic: Estrarre una stringa da client.read  (Read 680 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
God Member
*****
Karma: 0
Posts: 600
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Buongiorno!
Nonostante il mio codice sia terminato nella struttura ed in fase di test... ogni volta che lo riapro mi vengono in mente sempre piccole aggiunte che potrei fare smiley
In particolare avrei bisogno di un consiglio su come fare questa cosa:

Dopo aver inviato i dati a pachube ottengo una risposta che stampo a seriale con questo codice:
Code:
while(client.connected())
    {
      // stay in this loop until the server closes the connection
      while(client.available())
      {
        //client.read();
        char c = client.read(); //gets byte from ethernet buffer
        Serial.print(c); //prints byte to serial monitor
      }
    }


Ed ottengo, per la maggior parte dei casi, una cosa così:
Quote
HTTP/1.1 200 OK
Date: Sun, 26 Feb 2012 10:05:29 GMT
Content-Type: text/plain; charset=utf-8
Connection: close
X-Pachube-Logging-Key: logging.xxxxxxxxxxxxxxxx
X-PachubeRequestId: xxxxxxxxxxxxxxxxxxxxxxxxxx
Cache-Control: max-age=0
Content-Length: 1
Age: 0
Vary: Accept-Encoding

Questo messaggio è fondamentale perché, oltre a svuotare il buffer di ricezione della eth shield (per cui basterebbe un client.read() ) mi permette di vedere lo status di pachube e capire se eventuali malfunzionamenti dipendono da me o da loro.

Quello che vorrei fare è raccogliere dal client.read() i caratteri dal 10 al 15.
In pratica estrarre solo "200 OK" e memorizzarlo in una variabile di 5 caratteri da pubblicare sulla pagina del webserver. Voglio proprio solo 5 caratteri, il resto può essere allegramente troncato smiley
Questo mi permetterebbe di avere un debug anche se non sono connessa tramite pc.

La lista di errori di pachube è varia, ma a me bastano quei cinque caratteri in quella posizione (la stringa HTTP/1.1 è costante).

Suggerimenti per come fare?
Ah dimenticavo la parte difficile... abbiamo solo 0.5 k di sketch e 216 di FREERAM smiley-razz
Lo spazio di sketch posso eventualmente aumentarlo mettendo il bootloader della UNO ma mi piacerebbe mantenere il progetto dentro una duemilanove.

Grazie! smiley

  
« Last Edit: February 26, 2012, 05:22:48 am by DanielaES » Logged

Malo ( VI )
Offline Offline
Sr. Member
****
Karma: 0
Posts: 372
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
      while(client.available())
      {
        //client.read();
        char c = client.read(); //gets byte from ethernet buffer
        Serial.print(c); //prints byte to serial monitor
      }
    }

Na robetta cosi' ?
Quote
    char c = Conn_1.read();
    Testo1.concat(c) ;
    if (Testo1.endsWith(FineRiga)) {
      Serial.print("R1 : ");
      Serial.print(Testo1);
      Testo1 = "" ; }
Testo1 e' una String

FineRiga sono i caratteri \r\n o quelli che ti aspetti alla fine della stringa
« Last Edit: February 26, 2012, 05:51:57 am by brunol949 » Logged

Le mie opere : Flusso correnti nell'impianto fotovoltaico http://arduino.webveneto.net/energy_control/     PING ed E.Mail http://arduino.web

Bergamo
Offline Offline
God Member
*****
Karma: 1
Posts: 663
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

ciao

ti crei un piccolo array di char[] e vi memorizzi i caratteri quando li ricevi, fino ad un certo valore massimo che è la dimensione dell'array.
A quel punto, fuori dal ciclo di ricezione, fai un confronto tra il contenuto dell'array e la stringa che ti aspetti usando strcmp()
Logged

lucadentella.it

Offline Offline
God Member
*****
Karma: 0
Posts: 600
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Na robetta cosi' ?

Se ho capito bene il tuo codice...
Code:
while(client.available())
      {
        //client.read();

        char c = client.read(); //gets byte from ethernet buffer
        Serial.print(c); //prints byte to serial monitor
        String Testo1;
        Testo1.concat(c) ;
        if (Testo1.endsWith("\r\n")) {
          Serial.print("R1 : ");
          Serial.print(Testo1);
          Testo1 = "" ;
        }

      }

Questa robetta occupa 1.4 k!! Sketch too big... serve qualcosa di più ottimizzato :\
Tra l'altro in questo modo mi pare di capire che Testo1 conterrebbe tutta la prima riga, compreso l'HTTP ecc... che io volevo scaricare perché nn mi serve.

@Luca qualche esempio?
Logged

Bergamo
Offline Offline
God Member
*****
Karma: 1
Posts: 663
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

ciao

(codice non provato, dovrebbe cmq essere ok):

Code:
#define BUFFER_SIZE 7
char rxbuffer[BUFFER_SIZE];
int buffer_position = 0;
int char_count = 0;

while(client.connected())
    {
      while(client.available())
      {
char c = client.read();
Serial.print(c);

if(char_count > 8 && char_count < 15) rxbuffer[buffer_position++] = c;
                char_count++;
      }
    }
rxbuffer[buffer_position] = '\0';
if(strcmp(rx_buffer, "200 OK") == 0) Serial.println("OK!")
else Serial.println("KO!);

- definisci un buffer di 7 caratteri ("200 OK" sono 6 caratteri + il terminatore \0 di stringa alla fine)
- tieni un indice che ti conta i caratteri ricevuti dal client e uno che tiene la posizione in cui stai scrivendo nel buffer
- se stai ricevendo i caratteri dal 9 al 14 li salvi nel buffer spostando avanti di uno il puntatore della posizione
- incrementi il contatore caratteri
- alla fine del ciclo aggiungi il terminatore di stringa
- confronti il buffer ricevuto con la stringa che ti aspetti

fammi sapere se funziona!
Logged

lucadentella.it

Offline Offline
God Member
*****
Karma: 0
Posts: 600
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Luca, che dire, complimenti!
Il codice è perfetto, fa esattamente quello che volevo ed occupa solo 84 byte di sketch!! ( e 7 byte di ram).
Non ho messo strcmp perché ho già una variabile " ok - ko ", in questo caso volevo vedere proprio il codice di risposta ed, eventualmente, di errore smiley

Viste le differenze di dimensioni tra le soluzioni proposte inizio a pensare che se IO sapessi programmare probabilmente sarei riuscita a fare stare tutto il mio progetto in un solo arduino, anziché usarne due smiley
Dio solo sa quante risorse sto sprecando...
All'inizio, per risolvere questa questione della stringa, avevo impostato un for da 2.5 k!

Che poi ogni volta che penso che la mia sim del cellulare ha 256k e che io sto a lavorare per stare dentro ad uno 0.4 k... mi vien da ridere e mi fa riflettere smiley

Btw luca, istruiscimi un attimino:
Perché usi il define?
Code:
#define BUFFER_SIZE 7
char rxbuffer[BUFFER_SIZE];

che vantaggi ha rispetto ad un banale:
Code:
char rxbuffer[7];
?

Ed in ogni caso... grazie! Ho ancora quasi 0.4k per pensare di metterci qualcos'altro, oramai questo arduino lo sto farcendo come un tacchino smiley
Logged

Cagliari, Italy
Online Online
Tesla Member
***
Karma: 104
Posts: 6617
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Il problema dell'aumento delle dimensioni è dato dal fatto che appena dichiari
Code:
String testo1;
il compilatore carica tutto il codice della libreria necessario per quel comando.
E' che magari non è necessario perché puoi ottenere lo stesso risultato in altro modo.

Il
Code:
#define BUFFER_SIZE 7
è usato per modificare la lunghezza del buffer comodamente all'inizio del programma senza andare a cercarsi la variabile in tutto il codice.
Un pò come si fa per definire i pin su cui sono mappati i sensori.
La sostituzione avviene prima della compilazione e non comporta l'aumento della dimensione del codice oggetto.
Logged

Code fast. Code easy. Codebender --> http://codebender.cc/?referrer=PaoloP

Bergamo
Offline Offline
God Member
*****
Karma: 1
Posts: 663
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Ciao

confermo quanto ha scritto Paolo: l'uso dei define è comodo per cambiare "in corsa" eventuali valori, senza spulciare tutto il codice per sostituirli... essendo - a differenza delle variabili - sostituiti dal compilatore non ti utilizzano RAM o PROGMEM.
Logged

lucadentella.it

Pages: [1]   Go Up
Jump to: