String troppo "lunga"

Oppure molto più semplicemente SENZA ARRAY (dovrebbe funzionare):

client.print("CtrlCod="); client.print(CtrlCod); 
client.print("&ArduID="); client.print(ArduID);
client.print("&ArduIP="); client.print(ArduIP);
client.print("&a0=");     client.print(a0);
...
client.print("&d9=");     client.println(d9);

Sull’ultima uso println
Con questo ultimo pezzo puoi ulteriormente liberare Sram usando F()

client.print( F("&ArduIP=") );

nid69ita: Oppure molto più semplicemente SENZA ARRAY (dovrebbe funzionare):

client.print("CtrlCod="); client.print(CtrlCod); 
client.print("&ArduID="); client.print(ArduID);
client.print("&ArduIP="); client.print(ArduIP);
client.print("&a0=");     client.print(a0);
...
client.print("&d9=");     client.println(d9);

Sull'ultima uso println Con questo ultimo pezzo puoi ulteriormente liberare Sram usando F()

client.print( F("&ArduIP=") );

Questa è la maniera con cui costruisco l'invio via GET e funziona, purtroppo non lo posso utilizzare con POST, dato che questo, per essere accettato lato server ha bisogno di portare con se l'informazione Content-Length che serve all'interprete per sapere la lunghezza precisa del POST da elaborare.

Non me ne intendo ma mica avrai il problema che ad un certo punto devi fare questo:

 client.println("Content-Lenght: "+PostDataSend.length());

E quindi usavi la String per avere il giusto numero di caratteri? Se è così, ti picchio :grin:

Leggi la reference della print() nella sezione return http://arduino.cc/en/Reference/ClientPrint.

int lun=0;
lun+=n.print("CtrlCod="); lun+=n.print(CtrlCod); 
lun+=n.print("&ArduID="); lun+=n.print(ArduID);
lun+=n.print("&ArduIP="); lun+=n.print(ArduIP);
lun+=n.print("&a0=");     lun+=n.print(a0);
...
lun+=n.print("&d9=");     lun+=n.println(d9);

alla fine lun contiene la lunghezza

@ fvlgnn ... prova a non metterlo proprio il Content-Length ... c'è un'alta possibilità che funzioni ugualmente (... c'ho scritto, in un'altro ambiente, una libreria per DropBox e ... dato che quel parametro dell'HTTP POST mi incasinava sempre la vita ... l'ho eliminato e viaggia che è una meraviglia :grin: :grin: :grin:)

Guglielmo

Edit : Con HTTP 1.1 non sono neanche sicuro che sia obbligatorio ... RFC2616 Sez. 4.4

gpb01: @ fvlgnn ... prova a non metterlo proprio il Content-Length ... c'è un'alta possibilità che funzioni ugualmente (... c'ho scritto, in un'altro ambiente, una libreria per DropBox e ... dato che quel parametro dell'HTTP POST mi incasinava sempre la vita ... l'ho eliminato e viaggia che è una meraviglia :grin: :grin: :grin:) Guglielmo

Ehhh, fatta la legge... trovato l'inganno :grin:

nid69ita: Ehhh, fatta la legge... trovato l'inganno :grin:

... come dicevo, credo che con HTTP 1.1 ... non sia più obbligatorio perché riesce a calcolarsi la lunghezza del messaggio ... guarda le specifiche RFC dell'HTTP 1.1 :roll_eyes:

Guglielmo

nid69ita:
Non me ne intendo ma mica avrai il problema che ad un certo punto devi fare questo:

 client.println("Content-Lenght: "+PostDataSend.length());

E quindi usavi la String per avere il giusto numero di caratteri? Se è così, ti picchio :grin:

Picchiami!!! :.

gpb01: ... come dicevo, credo che con HTTP 1.1 ... non sia più obbligatorio perché riesce a calcolarsi la lunghezza del messaggio ... guarda le specifiche RFC dell'HTTP 1.1 :roll_eyes:

Prima di aprire questo topic avevo già provato a levare il Content-Lenght ma sul server non arrivava niente infatti sembra richiesto 10.4.12 411 Length Required

gpb01: Edit : Con HTTP 1.1 non sono neanche sicuro che sia obbligatorio ... RFC2616 Sez. 4.4

Anche se qui dice che può essere omesso.

Faccio una prova veloce e aggiorno.

  n.println("POST /stream.php HTTP/1.1");
  n.println("Host: www.myhost.it");
  n.println("Content-Type: application/x-www-form-urlencoded");
  n.println("Connection: close");
  n.println("User-Agent: Arduino/1.0");
  //n.print("Content-Length: ");
  //n.println(PostDataSend.length());
  n.println();
  //n.print(PostDataSend);
  n.print("CtrlCod=");
  n.print(postCod);
  n.print("&");
  n.print("ArduID=");
  n.print(ArduID);
  n.print("&");
  n.print("ArduIP=");
  n.print(ArduIP);
  n.print("&");
  n.print("a0=");
  n.print(a0);
  n.print("&");
 ...
  n.print("&");
  n.print("d9=");
  n.print(d9);
  n.println();

Scritto così arduino lavora bene la freememomy è uguale a 319 ma su lato server non arriva niente :~

Ciao, ho provato anche su un altro server nel caso il mio hosting avesse vincoli precisi ma ninte, Arduino lavora ma il POST non ne vuole sapere di arrivare a destinazione, ho fatto una miriade di prove levando o aggiungendo intestazioni della head del post ma niente. A questo punto sono convinto che il Content-Length sia obbligatorio. Detto ciò c'è una maniera per passare quella miriade di dati via POST calcolando la lunghezza della stringa?

fvlgnn: Detto ciò c'è una maniera per passare quella miriade di dati via POST calcolando la lunghezza della stringa?

E qui cosa ho fatto, scusa? quella lun alla fine è la tua PostDataSend.lenght http://forum.arduino.cc/index.php?topic=230626.msg1665313#msg1665313

EDIT: azzo, tu lo devi sapere prima!!!. Prova a vedere se per caso puoi mettere quel pezzo

n.print("Content-Length: ");
n.println(lun);

come ultimo.

nid69ita: EDIT: azzo, tu lo devi sapere prima!!!. Prova a vedere se per caso puoi mettere quel pezzo

n.print("Content-Length: ");
n.println(lun);

come ultimo.

Ho fatto delle prove e scivendo a mano Content-Length nella head del POST, calcolato con lun i dati arrivano alla grande, purtroppo se invio il Content-Length dopo i dati da inviare il server li rifiuta. Content-Length è propedeutico per l'elaborazione del POST. Devo trovare una maniera contare i dati da inviare via POST senza saturare la SRAM di Arduino e senza usare un Content-Length statico anzichè dinamico. Quindi ho pensato di contare i dati prima di inviarli in questa maniera

lun=0;
lun+=("CtrlCod=");
lun+=(postCod);
lun+=("&");
...
lun+=("d9=");
lun+=(d9);

ma giustamente il compilatore mi da un errore error: invalid conversion from 'const char*' to 'int' quindi cercando sul forum ho trovato una funziona che si chiama atoi che dovrebbe convertire un array di caratteri ASCII in un numero intero ed ho provato a fare

char buf[75];
snprintf(buf, 75, "CtrlCod=%d&ArduID=%s&ArduIP=%s", postCod, ArduID,  ArduIP);
lun=atoi(buf);

Ma Arduino si "incarta" ... quindi per contare la lunghezza di questo benedetto POST forse dovrei usare un ciclo di for che conta carattere per carattere ma quersto implica l'utilizzo di una Stringa, che come provato in precedenza satura la SRAM ... non mi vengono in mente altre soluzioni. Come faccio a contare la lunghezza del POST? :~

Io suggerisco di calcolare a mano i dati fissi. Quelli li sai tranquillamente. E' una rottura ma ci arrivi. "CtrlCod=" sono 8 caratteri. Il problema a questo punto sono le parti variabili. Rinfrescami la memoria. Quante variabili e di che tipo sono. da a0 a a5 e da d0 a d9 ? intere? poi ?

Teoricamente ogni variabile non è difficile sapere quanto sarà lunga. se a0 contiene 123 si può sapere quanto è lunga o con delle divisioni oppure convertendola in testo. Per questo converrebbe una piccola funzione.

byte LunIntero(int p_Val) 
{ char tmp[6]=itoa(p_val);
  return(strlen(tmp));
}
...
lunghezza=LunIntero(a0);

Per la ArduIP è semplice, strlen(ArduIP)-> numero caratteri

Un'altra prova, non è che per caso se il contextlengh è un pò più grande gli piace lo stesso. Spedisci 80 char, gli metti 100, magari accetta comunque ? E' pur sempre un tentativo

nid69ita: Io suggerisco di calcolare a mano i dati fissi. Quelli li sai tranquillamente.

Era quello che stavo pensando di fare ;)

nid69ita: Il problema a questo punto sono le parti variabili. Rinfrescami la memoria. Quante variabili e di che tipo sono. da a0 a a5 e da d0 a d9 ? intere?

Sono interi che variano da 0 a 255 quindi i valori possono assumere da 1 a 3 caratteri.

nid69ita: Un'altra prova, non è che per caso se il contextlengh è un pò più grande gli piace lo stesso. Spedisci 80 char, gli metti 100, magari accetta comunque ? E' pur sempre un tentativo

Avevo già provato ma se la lunghezza dei caratteri non è precisa il server rifiuta il POST. Faccio la prova con la funzione che mi hai suggerito e aggiorno il topic.

Rimangono però postCod e ArduID, di che tipo sono?

nid69ita: Rimangono però postCod e ArduID, di che tipo sono?

postCod è un codice di controllo del post di 12 cifre alfanumeriche che utilizzo sulla webapp come controllo univoco (una sicurezza in più che ho creato per evitare spider sul post) e ArduID è un codice di 4 cifre. Quindi in questi termini conosco la lunghezza di questi valori.

nid69ita: byte LunIntero(int p_Val) { char tmp[6]=itoa(p_val);   return(strlen(tmp)); } ... lunghezza=LunIntero(a0);

Ho provato ad utilizzare questo codice ma non sono riuscito a capirne in pieno il funzionamento. Dato che i d# (i/o digitali) hanno un unico carattere, gli a# (ingressi analogici) hanno da 1 a 3 caratteri e gli altri li conosco posso provare ad usare string.length() per calcolare i caratteri di a#, non dovrei saturare troppo la SRAM se utilizzo fino ad un massimo di 18 blocchi di memoria. E' una "toppa" che sto mettendo, non mi piace molto ma attualmente è l'unica soluzione che mi viene in mente.

byte LunIntero(int p_Val) 
{ char tmp[6]=itoa(p_val);
  return(strlen(tmp));
}
...
lunghezza=LunIntero(a0);

In pratica passiamo il valore contenuto in a0, lo convertiamo in testo con itoa() e poi con la strlen() contiamo quanti caratteri sono. Si poteva usare snprintf():

byte LunIntero(int pVal) 
{ char tmp[6];
  snprintf(tmp,6,"%d",pVal);  // stampo pVal dentro a tmp come testo
  return(strlen(tmp));
}

nid69ita: Si poteva usare snprintf():

byte LunIntero(int pVal) 
{ char tmp[6];
  snprintf(tmp,6,"%d",pVal);  // stampo pVal dentro a tmp come testo
  return(strlen(tmp));
}

In questa maniera capisco meglio la funzione byte e il sistema funziona:

int pVal;
byte LunIntero(int pVal) {
char tmp[4];
snprintf(tmp,4,"%d",pVal);  // stampo pVal dentro a tmp come testo
return(strlen(tmp));
}
...
lun=0;
lun+=LunIntero(a0);
lun+=LunIntero(a1);
lun+=LunIntero(a2);
lun+=LunIntero(a3);
lun+=LunIntero(a4);
lun+=LunIntero(a5);
lun+=ALTRICARATTERI
...
n.print("Content-Length: ");
n.println(lun);

Con itoa il compilatore continuava a darmi un errore sulla prima graffa della funzione byte.

Vorrei anche aggiungere che è possibile disabilitare, lato server, il check sull'intestazione del POST. Per farlo se si usa un server web apache bisogna creare un file .htaccess dentro la cartella lato server dove c'è la pagina in listening del POST con scritto all'interno ServerSignature Off e nel php.ini disabilitare il parametro expose_php expose_php = Off Tengo a precisare che è altamente sconsigliato effettuare questa operazione in quanto si disabilitano due parametri importanti per la sicurezza del server web. La fonte per effettuare le modifiche sopra descritte è la seguente Configure Apache with a htaccess file to strip out unneeded respond-headers Vorrei aspettare ancora del tempo prima di mettere il tag RISOLTO sul topic in quanto adesso funziona ma vorrei ottimizzare e dinamizzare il contatore ulteriormente. Ringrazio vivamente @nid69ita per il supporto e le dritte! Un sentito grazia anche a tutti quanti hanno partecipato a questa discussione insegnandomi e illuminadomi sul mondo delle Stringhe e degli Array che fino ad oggi tendevo a non utilizzare per ignoranza ... newbie sono e newbie rimango :grin:

fvlgnn: Ringrazio vivamente @nid69ita per il supporto e le dritte!

Di nulla. E nessuno nasce "imparato". :grin: