[RESOLU] => MERCI Remplacer client.print par un client.write(buf, len); (Wifi)

Bonjour,

Je fais des petites mise a jour, amélioration sur mon code.

Pourriez vous m'aidé aux modifications "client.print" par un "client.write(buf, len)"?

Mes données actuellement son de se format:

void sendDataToServer() 
{
    String data;
   
    data = "do=data&func=0&to=0&val=0&valfloat=0&date=0&data="+dateTimeForWeb()+","
        +EEPROM.readByte(EElightPwmMax1)+","+EEPROM.readByte(EElightPwmMax2)+","+EEPROM.readByte(EElightPwmMax3)+","+EEPROM.readByte(EElightPwmMax4)+","
        +EEPROM.readInt(EElightStartTime1)+","+EEPROM.readInt(EElightStartTime2)+","+EEPROM.readInt(EElightStartTime3)+","+EEPROM.readInt(EElightStartTime4);
   
    if (client.connect(ipServer, portHttpServer)) 
    {
        startTime = millis();
    
        client.println( "POST /functions.php HTTP/1.1" );
        client.println( "Host: " + String(ipServer) );
        client.println( "Content-Type: application/x-www-form-urlencoded" );
        client.println( "User-Agent: DuduInoWifi" );
        client.print( "Content-Length: " );
        client.println( data.length() );
        client.println();
        client.print( data );
        client.println( "Connection: close" );
    }
   
    client.flush();
    client.stop();
   
    Serial.println(F("| Connection terminee"));
    Serial.print(F("| Donnees transmises en: "));
    duration = millis() - startTime;
    Serial.print(duration);
    Serial.println(F("ms"));
    Serial.println(F(""));
 }

Merci d'avance!

bonjour,
quel est le soucis exactement?

Salut,

Je cherche tout simplement pour optimiser le temps de transfert, à mettre en buffer mes variables que je veux envoyer en poste.

Cela va me permettre d'alléger le temps de tranfert.

Je vois pas du tout comment mettre en place le buffer. Remplacer client.print par un client.write(buf, len);

dans le code ci-dessus.

Merci

print() utilise write() alors je vois pas à quelle optimisation tu penses

J'ai tout simplement lu ça, sur la toile:

La méthode client.println(), qui a l'air toute simple comme ça, est en réalité une horreur en terme de traitements déclenchés : chaque caractère est envoyé unitairement dans un paquet protocolé sur le réseau.
Plus lourd y a pas.

Cette méthode est à bannir de tout code digne de ce nom.
A remplacer par un client.write(buf, len).

http://forum.arduino.cc/index.php?topic=191266.0

je te le met brut de decofrage mais j'avais ecrit cela donc si ça peut t'aider :

#define tBufferEnvoi 32 /// taille de buffer TCPIP
uint8_t m_Buff_Envoi[tBufferEnvoi];
int m_cursBuffer;/// curseur de buffer
///*************************************************************///
void writeInBuff(char c)
{
    m_Buff_Envoi[m_cursBuffer-1]=uint8_t(c);/// ecrire dans le buffer le caractere reçu

    if(m_cursBuffer==tBufferEnvoi)/// on verifi que l'on ne depasse pas la taille du buffer
    {
        sendBuff();
    }
    else
    {
        m_cursBuffer++;   ///sinon on incremente notre curseur
    }
    return;
}
///*************************************************************///
void sendBuff()
{


    m_client.write(m_Buff_Envoi, (m_cursBuffer));/// on envoi le buffer
    delay(1);
    for (int i=0; i<tBufferEnvoi; i++) /// on efface les donné du buffer
    {
        m_Buff_Envoi[i]=uint8_t(0);
    }
    m_cursBuffer=1;/// on reposition notre curseur en debut de buffer
   #ifdef DEBUG_SERIAL
    Serial.println(F("fin envoi donnes :"));
    #endif
    return;
}

aprés il te faudra réécrire le fonction print comme ça par exemple

void print(char*tabChar)
{
    char c=0;
    byte i=0;
    c =tabChar[i];/// lit  le 1er caractere de chaine
    i++;
    while( c!=0)/// tan que le carra tere de chaine et different du caractere de fin de chaine
    {
        writeInBuff(c);
        //Serial.print(c);
        c =tabChar[i];///lire le caractere suivant
        i++;
    }
    return;

}

tu utilisera ensuit

print( "ce que tu veux");
 sendBuff();// pour envoyer les donné ou etre sur qu'il ne reste plus de donnee a transféré

l'envoi ce fait automatiquement des que le buffer ateind 32octet( tu peut changer pour 64 eventuelement ou plus) ou lorsque tu utilise sendbuff().
je suis conssien que cela n'est pas parfait mais jesper que ça te servira de base de reflexion
brute de decofrage ça ne marchera pas a toi de l'adapté!

oui il peut effectivement augmenter , moi je me suis limiter a 32 car j'utilise beaucoup de la ram de ma mega.

par contre il semble que se ne soit pas telement recomender d'utiliser l'alocation dynamique avec new() et delete() car il me semble avoir lu que l'architecture des atmega ne gere pas correctement la liberation de la pile ( ou d'un autre .. ) . mais comme je ne maitrise pas dutou le sujet( pour pas dire que j'y pije que dalle) , je vous laise confirmé ou infirmé mes dires. :grin:

il me semble que cela produit une fuite memoire !

Super pour ces info les gars!

Merci pour le code, je vais bidouillé ça a ma façon et on regardera ensemble pour optimiser tout ça avec mes retours de test.

Pour info:

  • Voilà ma petite chaine de caractère que j'envois (environ 6 secondes pour l'envois). Dans mon premier poste ce n'est qu'une infime portion de ce que j'envois. Mon string :o va encore s'agrandir dans ma programmation futur. (oui il y a déjà des optimisations à faire comme la date par exemple qui pourrait être envoyé au format unix).
Mardi 9 Decembre 2014 - 20:28:18,1,0,1,1,192,168,1,240,8080,192,168,1,211,8888,80,0,127,0,0,1,19.8,19.8,19.9,19.8,47.0,0,1,2,0,-6.7,21.0,22.0,23.0,20.5,25.0,22.5,27.0,24.5,29.0,26.5,27.5,1,1,1,1,1,0.0,0.0,0.0,0.0,255,255,255,255,480,600,660,720,720,480,240,120,240,180,120,60,1,1,1,1,0,0,0,0,26,26,26,26,1,1,390,420,1,1,0,0,2,2,1,1,0,0,0,6.5,7.0,6.5,7.5

Voilà le résultat de mon utilisation mémoire:

Ram utilisee: 4649/8192 octets                       // Avant de lancé ma fonction

-> Ram utilisee: 5459/8192 octets                           //Après construction de ma chaine de caractère

-> Connection au serveur: 192.168.1.211:80
 |-> Envois des donnees pour affichage sur le serveur
 |-> S U C C E S de la connection au serveur
 |-> Connection terminee
 |-> Donnees transmises en: 6031ms

 |-> Envois une confirmation de la reception des packets: 
do=udp&func=2&to=0&val=acknowledged&valfloat=0&date=0

-> Ram utilisee: 4539/8192 octets                           // Ici on est au repos dans la boucle principale

Je remonte le résultat dès que possible, ce week end surement! :wink:

Salut,

J'aimerais comprendre la fonction write avec les données à en envoyé de type "const unsigned int" virtual size_t write(const uint8_t *buf, size_t size);

En faite je m'attendais plus a un tableau de caractères.

J'ai testé un cast, dèsfois que...

Le client se connecte, mais pas d'envois de données.

Quelqu'un peut m'instruire, je nage :cry:

char data[] = {"do=data&func=0&to=0&val=0&valfloat=0&date=0&data=Mardi 9 Decembre 2014 - 20:28:18,1"};


      //client.println("Transfer-Encoding: chunked");
      client.print( "Content-Length: " );
      client.println( data.length() );
      client.println();

      client.write((uint8_t *)data[], data.length() );

je suis pas sur de comprendre ton probléme mais ,

write(const uint8_t *buf, size_t size);

const unint8_t*buf : c'est un pointeur il reçoi donc une adresse, il est donc posible de lui passé un tableau ou une chaine de caractere entre "guillemet".

size_t size: c'est la taille de la chaine de caractére ou du tableau

comme la fonction attend un pointeur de type uint8_t* il faut donc lui envoyer un tableau de ce type
il est préférable de passer par un buffer mais sinon il te faudra ecrire quelque chose comme ça

//client.write((uint8_t *)data[], data.length() );// pas bon
//convertir le tableau de char en tableau unint8_t

unint8_t  datat8[sizeof(data)-1];

for( int i=0 ; i<sizeof(data);i++){
 if(data[i]!=0){
datat8[i]=uint8_t(data[i]);}

}
// envoyer le tableau unint8_t

client.write(datat8, sizeof(datat8) );//normalement la bone methode

Si si, tu as bien compris mon problème...

Je suis pas un pro du développement et en faite je n'avait pas compris le type "unint8_t".
En faite, c'est l'adresse du pointeur que l'on demande.

Ah les pointeur, je les ai mis de coté depuis que je tripote l'arduino.

Ca va être le point de l'évolution de mon code d'ailleurs.

Je me remet a l'ouvrage.

Super, Merci Heloderma-kris.

Ah...

Encore une chose: "deprecated conversion from string constant to 'char*'"

Oui par "mesure de simplicité", j'ai utilisé String comme type de données pour data.

Comment mettre toute mes données dans le bon format pour éviter cela?
Désolé j'ai vraiment un soucis avec String, string,char, et le tout combiné avec les arrays et les pointeurs... Merci d'avance.

format actuel:

String data;
   
    data = "do=data&func=0&to=0&val=0&valfloat=0&date=0&data="+dateTimeForWeb()+","
        +EEPROM.readByte(EElightPwmMax1)+","+EEPROM.readByte(EElightPwmMax2)+","+EEPROM.readByte(EElightPwmMax3)+","+EEPROM.readByte(EElightPwmMax4)+","
        +EEPROM.readInt(EElightStartTime1)+","+EEPROM.readInt(EElightStartTime2)+","+EEPROM.readInt(EElightStartTime3)+","+EEPROM.readInt(EElightStartTime4);

C'est simple : oublie les String :slight_smile:

char data[400];
char temp[20];

memset(data,NULL,400);

strcat(data, "do=data&func=0&to=0&val=0&valfloat=0&date=0&data=");
strcat(data,dateTimeForWeb());
strcat(data,",");

memset(temp,NULL,20);
itoa(EEPROM.readByte(EElightPwmMax1),temp,10);

strcat(data,temp);

....

Merci,

Je mets en service ce week end!

+1 avec B@tto ,
il parait plus simple au debut d'utilisé les string mais c'est ce voilé la face et repouser le probléme des pointeur alors qu'avec un peut de travail on les comprend bien et ça devien efficase!
perso je ne les utilise jamais ( les string), par contre juse et abuse des tableaux de char et des pointer!

Merci les gars!

Je sais bien, c'est pour ça que je fais appelle a vous!

Avec ces exemples, je vais pouvoir en abusé maintenant...

Bon je vais commencer a être chiant, mais c'est pas très pratique pour calculer la taille de mon tableau automatiquement.

J'ai besoin de la valeur réelle a envoyé pour le transfert en POST.
J'aime pas trop le mode chunked, car il est même pas fonctionnel pour apache 2.4.9. Dans la version 2.5, il sera mieux implanté.

Bonne soirée.

je ne me souvient pas si c'est la taille complete de la trame avec les donne poste qu'il faut ou juste la taille de chaine des variable passer en POST car sinon vu que tu met tout dans un tableau un rapide parcour avec un index qui s'incrémente et s'aréte lorsque tu tombe sur 0 et donnera la taille en octet puisque un char =un octet.

Heloderma-kris:
je ne me souvient pas si c'est la taille complete de la trame avec les donne poste qu'il faut ou juste la taille de chaine des variable passer en POST car sinon vu que tu met tout dans un tableau un rapide parcour avec un index qui s'incrémente et s'aréte lorsque tu tombe sur 0 et donnera la taille en octet puisque un char =un octet.

c'est bien la taille de la chaine passer en poste qui compte, je regarde pour faire ça. Pour le fin de ligne, c'est bien 2 caractères qu'il faut compter?

en générale la fin de la requete doit ce terminer par "\r\n\r\n" ou "\r\n" donc CR LF CR LF ou CR LF donc soit 2 soit 4 character