Go Down

Topic: Thermostat : Ethercard + Temperature = problème de construction d'URL (Read 1 time) previous topic - next topic

vincentes2000

Bonjour

Voila, je suis en train de réaliser un thermostat avec un affichage TFT 1.8' et une carte ethernet basé sur le chipset enc28j60.

Le thermostat est joystick qui permet de régler la température et l'envoie la température choisi à l'aide d'une URL sur ma box de domotique.

le problème est quand je concaténe la url et la valeur de la température, ça fonctionne la première fois mais les fois suivantes, la nouvelle valeur s'ajoute à l'ancienne URL

Exemple :

Premier changement de température : 17°c -> 18°c

Set Temperature Heat
id=variableset&DeviceNum=65&serviceId=urn:upnp-org:serviceId:TemperatureSetpoint1_Heat&Variable=CurrentSetpoint&Value=18

Second changement de température :  18°c -> 19°c

Set Temperature Heat
id=variableset&DeviceNum=65&serviceId=urn:upnp-org:serviceId:TemperatureSetpoint1_Heat&Variable=CurrentSetpoint&Value=1819

-------

Voici la partie du code :

Code: [Select]


void UpdateTemp()
{   
  if (millis() > timer) {
    timer = millis() + 5000;

    Serial.println("Set Temperature Heat");   

    char temperature[2] = "";
    dtostrf(SetInt, 2,0, temperature);

    char* Header = "id=variableset&DeviceNum=65&serviceId=urn:upnp-org:serviceId:TemperatureSetpoint1_Heat&Variable=CurrentSetpoint&Value=";

    strcat(Header, temperature);

    Serial.println(Header);

    ether.browseUrl(PSTR("/data_request?"),Header2, website, my_callback);   
  }
}



L'envoi de l'url fonctionne correctement, c'est juste le problème de contacténation qui pose problème.

Avez vous une idée pour résoudre ce problème ?

Merci d'avance

barbudor

#1
Sep 29, 2013, 12:40 pm Last Edit: Sep 29, 2013, 05:02 pm by Jean-François Reason: 1
Oulalalala
Que de grosses erreurs en quelques lignes de code.
Tu n'as pas compris le fonctionnement des chaines de caractères C, pointeurs sur caractères etc ....

Je t'engage à lire en détails les tutos listés dans la section tuto : http://forum.arduino.cc/index.php?board=74.0

Rapidemment, plusieurs erreurs :

Code: [Select]

char temperature[2] = "";
   dtostrf(SetInt, 2,0, temperature);


En C, une chaine de caractères est une suite de 'char' se terminant par un charactère nul '\0' (0x00).
Une chaine de 2 caractères réels a donc besoin de 3 caractères pour être stockés.
Dans ton cas, le caractère de fin '\0' sera écrit au dela de l'emplacement réservé pour le tableau 'temperature' donc probablement dans une case mémoire qui est utile a quelqu'un autre => risque de pourrissage d'autre variables.

problème similaire avec :
Code: [Select]
char* Header = "id=variableset&DeviceNum=65&serviceId=urn:upnp-org:serviceId:TemperatureSetpoint1_Heat&Variable=CurrentSetpoint&Value=";
   strcat(Header, temperature);


Header est un pointeur de char qui pointe vers une zone de N caractères correspondant exactement à la chaine que tu a écris suivit du caractère terminal '\0'.
Quand tu appelles strcat() tu viens ajouter d'autres caractères à la suite en mémoire au dela de l'espace initialement réservé. Là encore tu as de grande chance de venir pourrir de la mémoire utilisée par quelqu'un d'autre.

De plus, tu as ajouté 17 la première fois mais nul part tu ne l'enlève. C'est pour cela qu'au pasage suivant, 18 se rajoute à la fin. Et plus tu continue, plus tu va puorrir la mémoire et crasher ton programme.

Je suggère le code suivant mais il faut impérativement que tu cherches à comprendre les chaines de caractères, les tableaux et les pointeurs :

Code: [Select]

   char Header[130];
   strcpy( Header, "id=variableset&DeviceNum=65&serviceId=urn:upnp-org:serviceId:TemperatureSetpoint1_Heat&Variable=CurrentSetpoint&Value=" );
   dtostrf(SetInt, 2,0, Header+strlen(Header) );


vincentes2000


Merci de ta réponse, effectivement, je le cache que j'ai beaucoup de mal avec l'utilisation des pointeurs.

La construction de l'url fonctionne bien, si je vérifie avec le debug .. la chaine de caractère n'est plus  utilisable  par la fonction browseUrl :

static void    browseUrl (prog_char *urlbuf, const char *urlbuf_varpart, prog_char *hoststr, void(*cb)(uint8_t, uint16_t, uint16_t))

la fonction BrowseUrl n'envoie plus rien ???

Faut il indiquer le pointeur de la chaine de caractère ?




barbudor

Ben dans ton code initial tu construis Header
Mais c'est Header2 que tu passes à la fonction BrowseUrl()
Si tu ne trouves pas, re-poste un code complet à jour.

Go Up