Remplacer les sockets php

Bonjour,

Ce qui fonctionnne:
Je me suis fait un petit programme qui envois les températures des sondes sur une base de données et je les affiches sur mon site sous forme de courbe. (matériel: arduino 2560 + carte wifi avec méthode post)

Ce qui est à revoir:
J'ai fait une petite interface (ajax+php) pour le réglage des seuils d'alarme et j’envoie les données sur l'arduino par une connexion socket... Cela fonctionne en local avec un serveur wamp, mais pas chez un hebergeur qui bloque les connexions sockets sur leur firewall)

Je souhaiterais connaître les possibilitées qui me sont à disposition pour remplacer ma connexions sockets, par une autre méthode.

Merci.

Bonsoir,

Pourquoi ne pas rendre ton Arduino serveur web grâce au protocole HTTP de chez toi et en ouvrant le port 80 (ou autre que toi seul connaisse pour éviter les attaques) sur ta box ?

Je me suis amusé à faire ça avec mon Uno et ma carte ethernet sur base d'un script récupérant la température d'une pièce avec le DHT22.

Ensuite vu que tu connais PHP, il suffit de faire depuis ton hébergement distant un file_get_contents() sur http://tonip/ pour récupérer la valeur de température. Une tâche CRON peut éventuellement être programmée sur ton hébergement pour récupérer à intervalles réguliers la température et générer des courbes horaire.

Nico.

c'est ce que je fais actuellement en mode client, cette partie fonctionne.

Ce que je voudrais c'est recevoir des information du serveur exemple de la trame actuelle:
do=udp&func=3&valMin1=23&valMax1=25&valMin2=23&valMax2=25

Actuellement j'utilise les sockets sur le serveur pour envoyer les données. Mais je voudrais un autre façon de faire.

//IP to send 
           $host=CONFIG_IP;

           //port to send
           $port=CONFIG_PORT;

           //Create Socket
           $socket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
    
           //Make socket request
           $sock = socket_sendto($socket, $to.','.$val.','.$func.','.$date, strlen($to.','.$val.','.$func.','.$date), 0, $host, $port);

           //Close socket
           socket_close($socket);

Peux être que je pourrais mettre en place un envois de flux xml en php avec curl.

Mais je serais obligé de mettre ma carte wifi en mode serveur?

Bonjour,

En fait, ton arduino est en mode client et balance des requêtes POST sur un script alpha.php sur un serveur web distant ; de ce fait tu récupères la température dans le array $_POST que tu insères ensuite dans une table MySQL (reprends moi si je me trompe).

Donc pour ton réglage d'alarme, à mon gout, je ferais de cette manière : Générer un code XML avec tes seuils d'alarmes dans le script PHP même que ton arduino va lire à chaque fois qu'il exécute sa requête POST. Je peux t'écrire un exemple si je ne suis pas assez clair.

Si j'ai bien compris ton système, ça devrait le faire ... :roll_eyes:

bonjour,
un truc que je ne comprends pas, ton seuil d’alarme fait quoi et pourquoi l’envoyer sur l’arduino?

comme dit meteobiduletrucmuche (on se connait très bien :slight_smile: ), ton arduino envoie les requêtes sur l’hebergeur.
à partir de ce moment là, ton ajax peut travailler tout seul pour avoir les alarmes en live sur ton pc.

arduino=>requete=>hebergeur
comparaison des valeurs dans ton script php qui va parser les données, insertion en bdd (si besoin)
si valeur < alarme=>rien ne se passe
si valeur > alarme=>affichage alarme

pourquoi se compliquer la vie?

Bonjour,

Je comprend pas pourquoi tu te compliques la vie.

Ton hébergeur accepte forcément les requêtes GET et POST, de fait tu peut :
Faire un GET d'un fichier de config pour tes seuils de manière régulière.
Faire un POST de tes données comme c'est le cas actuellement.

Pour la génération du fichier de config c'est pas compliqué, au lieu de faire un socket tu écrit dans un fichier, fini.

Salut,

J'ai pas mal avancé sur le projet, en gros depuis mon hebergement sur pc local.

  • J'envois sur mysql plus une vingtaine de variable toute les minutes que j'utilise pour tracé des courbes. (fonctionne nikel)
  • Je peux parametrer une trentaine de variable qui me permette de configurer mon automate. (super rapide nikel)

Mais à chaque connexion au site web, l'envois de la trentaine de variable en GET me prend 6 secondes, dans mon php j'ai mis une tempo de 10 secondes d'attente pour la réception des données, mon soucis est pluôt coté arduino, cette envois de données bloque mon programme pendant 6 secondes, l'envois des données en xml serais pas plus rapide?

Vous pouvez jetté un oeuil! http://duduino.no-ip.org

Avec le code arduino se serait mieux :wink:

Bonjour,
J'espère que ton site n'est qu'un exemple, parce que là je pense que tes poissons vont pas vivre longtemps.
Pas dit que ce soit sûr pour tes pc non plus...

Hors point de vue sécurité, très beau travail !!!

Merci!

Voici un exemple de GET envoyé sur le serveur:

do=data&data=Jeudi 6 Fevrier 2014 - 01:13:12,0,0,1,1,192,168,1,240,8080,192,168,1,211,8888,80,0,127,0,0,1,24.3,21.3,21.3,21.3,0,1,2,2,14.5,21.0,22.0,23.0,20.5,21.5,22.5,23.5,24.5,25.5,26.5,27.5,1,1,1,1,1,0,0,0,0,255,255,255,255,540,570,600,630,720,660,600,540,60,60,60,60,1,1,1,1,0,0,0,0,30,30,30,30,0,0,390,420,1,1,0,0,2,2,1,1,0,0,0,0.0,7.1,6.5,7.5

Je précise que les variables s'affiche très rapidement dans le terminal et que la led bleu de la carte wifi clignote pendant 6 secondes.

Voici mon code Arduino:

void sendDataToServer(byte whatDataSent) 
{
  String data;
  float light1Power = 0.0, light2Power = 0.0, light3Power = 0.0, light4Power = 0.0;

  // SONDE DE TEMPERATURE
  // Convertion de float en string à 0.1 degré près
  tempAquaTankStr = dtostrf(tempAquaTank,0,1,tempAquaTankTmp);
  tempAquaTankSoilStr = dtostrf(tempAquaTankSoil,0,1,tempAquaTankSoilTmp);
  tempFillingTankStr = dtostrf(tempFillingTank,0,1,tempFillingTankTmp);
  tempAmbientStr = dtostrf(tempAmbient,0,1,tempAmbientTmp);

  tempAquaTankSetPointStr = dtostrf(EEPROM.readFloat(EEaquaTankSetPoint),0,1,tempAquaTankSetPointTmp);
  tempAquaTankSoilSetPointStr = dtostrf(EEPROM.readFloat(EEaquaTankSoilSetPoint),0,1,tempAquaTankSoilSetPointTmp);
  tempFillingTankSetPointStr = dtostrf(EEPROM.readFloat(EEfillingTankSetPoint),0,1,tempFillingTankSetPointTmp);
  tempAmbientSetPointStr = dtostrf(EEPROM.readFloat(EEambientSetPoint),0,1,tempAmbientSetPointTmp);

  alarmMiniTempAquaTankStr = dtostrf(EEPROM.readFloat(EEalarmMiniTempAquaTank),0,1,alarmMiniTempAquaTankTmp);
  alarmMaxiTempAquaTankStr = dtostrf(EEPROM.readFloat(EEalarmMaxiTempAquaTank),0,1,alarmMaxiTempAquaTankTmp);
  alarmMiniTempAquaTankSoilStr = dtostrf(EEPROM.readFloat(EEalarmMiniTempAquaTankSoil),0,1,alarmMiniTempAquaTankSoilTmp);
  alarmMaxiTempAquaTankSoilStr = dtostrf(EEPROM.readFloat(EEalarmMaxiTempAquaTankSoil),0,1,alarmMaxiTempAquaTankSoilTmp);
  alarmMiniTempFillingTankStr = dtostrf(EEPROM.readFloat(EEalarmMiniTempFillingTank),0,1,alarmMiniTempFillingTankTmp);
  alarmMaxiTempFillingTankStr = dtostrf(EEPROM.readFloat(EEalarmMaxiTempFillingTank),0,1,alarmMaxiTempFillingTankTmp); 
  alarmMiniTempAmbientStr = dtostrf(EEPROM.readFloat(EEalarmMiniTempAmbient),0,1,alarmMiniTempAmbientTmp);
  alarmMaxiTempAmbientStr = dtostrf(EEPROM.readFloat(EEalarmMaxiTempAmbient),0,1,alarmMaxiTempAmbientTmp);

  // ECLAIRAGE
  light1Power = light1Pwm / 2.55;
  light2Power = light2Pwm / 2.55;
  light3Power = light3Pwm / 2.55;
  light4Power = light4Pwm / 2.55;

  light1PowerStr = dtostrf(light1Power,0,0,light1PowerTmp);
  light2PowerStr = dtostrf(light2Power,0,0,light2PowerTmp);
  light3PowerStr = dtostrf(light3Power,0,0,light3PowerTmp);
  light4PowerStr = dtostrf(light4Power,0,0,light4PowerTmp);

  // SONDE CO2
  // Convertion de float en string à 0.1 degré près
  phStr = dtostrf(ph,0,1,phTmp);
  phSetPointStr = dtostrf(EEPROM.readFloat(EEphSetPoint),0,1,phSetPointTmp);
  alarmMiniPhStr = dtostrf(EEPROM.readFloat(EEalarmMiniPh),0,1,alarmMiniPhTmp);
  alarmMaxiPhStr = dtostrf(EEPROM.readFloat(EEalarmMaxiPh),0,1,alarmMaxiPhTmp);  

  // Envois les valeurs a afficher sur le site
  if (whatDataSent == 1)
  {  
    data = "do=data&data="+String()+displayRtc()+","
      +EEPROM.readBit(EEhardwareResetStatus,0)+","+EEPROM.readBit(EEhardwareRebootStatus,0)+","
      +EEPROM.readBit(EElanguage,0)+","+EEPROM.readBit(EEdisplayError,0)+","
      +EEPROM.readByte(EEipArduinoOctet1)+","+EEPROM.readByte(EEipArduinoOctet2)+","+EEPROM.readByte(EEipArduinoOctet3)+","+EEPROM.readByte(EEipArduinoOctet4)+","
      +EEPROM.readInt(EEportUdpArduino)+","
      +EEPROM.readByte(EEipServerOctet1)+","+EEPROM.readByte(EEipServerOctet2)+","+EEPROM.readByte(EEipServerOctet3)+","+EEPROM.readByte(EEipServerOctet4)+","
      +EEPROM.readInt(EEportUdpServer)+","+EEPROM.readInt(EEportHttpServer)+","
      +EEPROM.readBit(EErestrictAcces,0)+","
      +EEPROM.readByte(EEipAllowedOctet1)+","+EEPROM.readByte(EEipAllowedOctet2)+","+EEPROM.readByte(EEipAllowedOctet3)+","+EEPROM.readByte(EEipAllowedOctet4)+","

      +tempAquaTankStr+","+tempAquaTankSoilStr+","+tempFillingTankStr+","+tempAmbientStr+","
      +EEPROM.readByte(EEindexSensorAquaTank)+","+EEPROM.readByte(EEindexSensorAquaTankSoil)+","+EEPROM.readByte(EEindexSensorFillingTank)+","+EEPROM.readByte(EEindexSensorAmbient)+","
      +tempAquaTankSetPointStr+","+tempAquaTankSoilSetPointStr+","+tempFillingTankSetPointStr+","+tempAmbientSetPointStr+","
      +alarmMiniTempAquaTankStr+","+alarmMaxiTempAquaTankStr+","
      +alarmMiniTempAquaTankSoilStr+","+alarmMaxiTempAquaTankSoilStr+","
      +alarmMiniTempFillingTankStr+","+alarmMaxiTempFillingTankStr+","
      +alarmMiniTempAmbientStr+","+alarmMaxiTempAmbientStr+","
      +EEPROM.readBit(EEalarmTemp1,0)+","+EEPROM.readBit(EEalarmTemp2,0)+","+EEPROM.readBit(EEalarmTemp3,0)+","+EEPROM.readBit(EEalarmTemp4,0)+","
      +EEPROM.readBit(EEtemperatureCelciusFahrenheit,0)+","

      +light1PowerStr+","+light2PowerStr+","+light3PowerStr+","+light4PowerStr+","
      +EEPROM.readByte(EElightPwmMax1)+","+EEPROM.readByte(EElightPwmMax2)+","+EEPROM.readByte(EElightPwmMax3)+","+EEPROM.readByte(EElightPwmMax4)+","
      +EEPROM.readInt(EElightStartTime1)+","+EEPROM.readInt(EElightStartTime2)+","+EEPROM.readInt(EElightStartTime3)+","+EEPROM.readInt(EElightStartTime4)+","
      +EEPROM.readInt(EElightOperatingTime1)+","+EEPROM.readInt(EElightOperatingTime2)+","+EEPROM.readInt(EElightOperatingTime3)+","+EEPROM.readInt(EElightOperatingTime4)+","
      +EEPROM.readByte(EElightDimmingTime1)+","+EEPROM.readByte(EElightDimmingTime2)+","+EEPROM.readByte(EElightDimmingTime3)+","+EEPROM.readByte(EElightDimmingTime4)+","
      +EEPROM.readBit(EEautoManuLight1,0)+"," +EEPROM.readBit(EEautoManuLight2,0)+"," +EEPROM.readBit(EEautoManuLight3,0)+"," +EEPROM.readBit(EEautoManuLight4,0)+","
      +EEPROM.readBit(EEmanuelLightOnOff1,0)+","+EEPROM.readBit(EEmanuelLightOnOff2,0)+","+EEPROM.readBit(EEmanuelLightOnOff3,0)+","+EEPROM.readBit(EEmanuelLightOnOff4,0)+","
      +EEPROM.readByte(EElight1PwmOffset)+","+EEPROM.readByte(EElight2PwmOffset)+","+EEPROM.readByte(EElight3PwmOffset)+","+EEPROM.readByte(EElight4PwmOffset)+","

      +EEPROM.readBit(EEstatusFood1,0)+","+EEPROM.readBit(EEstatusFood2,0)+","
      +EEPROM.readInt(EEstartFood1)+","+EEPROM.readInt(EEstartFood2)+","
      +EEPROM.readByte(EEfastingDayFood1)+","+EEPROM.readByte(EEfastingDayFood2)+","
      +food1LockTime+","+food2LockTime+","
      +EEPROM.readByte(EEtempoFood1)+","+EEPROM.readByte(EEtempoFood2)+","
      +EEPROM.readBit(EEautoManuFood1,0)+","+EEPROM.readBit(EEautoManuFood2,0)+","
      +EEPROM.readBit(EEmanuelFoodOnOff1,0)+","+EEPROM.readBit(EEmanuelFoodOnOff2,0)+","

      +co2NumbBubble+","+phStr+","
      +phSetPointStr+","+alarmMiniPhStr+","+alarmMaxiPhStr;   

    whatDataSent = 0;

#ifdef DEBUG_WIFI_SERVER    
    Serial.println(F("-> Envois des donnees pour affichage sur le serveur: "));
    Serial.println(data);
    Serial.println();
#endif    
  }

  // Envois les valeurs a enregistrer dans MYSQL
  else if (whatDataSent == 2)
  {
    data = "do=data&func=3&date="
      +dateTimeMysql()
      +"&temp1="+tempAquaTankStr+"&temp2="+tempAquaTankSoilStr+"&temp3="+tempFillingTankStr+"&temp4="+tempAmbientStr
      +"&light1="+light1PowerStr+"&light2="+light2PowerStr+"&light3="+light3PowerStr+"&light4="+light4PowerStr
      +"&food1="+EEPROM.readBit(EEstatusGraphFood1,0)+"&food2="+EEPROM.readBit(EEstatusGraphFood2,0)
      +"&co2="+co2NumbBubble+"&ph="+phStr;

    whatDataSent = 0;

    if( (EEPROM.readBit(EEstatusGraphFood1,0) == 1) || (EEPROM.readBit(EEstatusGraphFood2,0) == 1) )
      foodGraphDataSent();

#ifdef DEBUG_WIFI_SERVER    
    Serial.println(F("-> Envois des donnees dans la base de donnees MYSQL: "));
    Serial.println(data);
    Serial.println();
#endif

  }



#ifdef DEBUG_WIFI_SERVER    
    Serial.print(F("-> Connection au serveur: "));
    Serial.print(ipServer);
    Serial.print(F(":"));
    Serial.println(portHttpServer);
#endif

  
  if (client.connect(ipServer, portHttpServer)) 
  {
    client.println( "POST /mapagetrucmuche.php HTTP/1.1" );
    client.println( "Host: " + String(ipServer)  );
    client.println( "Content-Type: application/x-www-form-urlencoded" );
    client.println( "User-Agent: DuduInoWifi" );
    client.println( "Connection: close" );
    client.print( "Content-Length: " );
    client.println( data.length() );
    client.println();
    client.print( data );
    client.println();
    
#ifdef DEBUG_WIFI_SERVER  
    Serial.println(F("| S U C C E S de la connection au serveur"));
#endif

  }  
#ifdef DEBUG_WIFI_SERVER  
  else 
  {
    Serial.println(F("| E C H E C de la connection au serveur"));
  } 
#endif

  client.stop();

#ifdef DEBUG_WIFI_SERVER
  Serial.println(F("| Connection terminee"));
  Serial.println();
#endif

}

Vu le code je suis presque sûr que "data" est de type String.

Tu devrais envoyer les données directement quand tu les lit de l'EEPROM au lieu de tout mettre en RAM avant l'envoi.
Les String en Arduino c'est des nids à bug aléatoires, c'est complément planté en interne.
Ça ne m'étonnerai pas que tu ais des bug par moment avec des valeurs qui ne veulent rien dire dans tes logs serveurs :wink:

Sinon comme ça je ne vois pas de problème de tempo dans ton code.

Data doit être une chaine de caractere pour creer mon GET, je vois pas trop comment tu veux faire.
Mais si je peux modifier ça je suis preneur.

On est bien d'accord, mon problème ne proviens pas d'une tempo, la led bleu de la carte wifi, qui signifie envois de données, clignote pendant 6 secondes, c'est que pour moi la chaine de caractere est lourde à envoyé?!

dudux2:
On est bien d'accord, mon problème ne proviens pas d'une tempo, la led bleu de la carte wifi, qui signifie envois de données, clignote pendant 6 secondes, c'est que pour moi la chaine de caractere est lourde à envoyé?!

Vu la tête du data = ..., ça ne m'étonne pas vraiment que le code traîne des pieds pour envoyer une String aussi longue.

Pour envoyer par morceau sans avoir besoin de String :

client.print("do=data&data=");
client.print(displayRtc()); // Une fonction "display" qui retourne une String ? C'est vraiment tordu comme truc ...
client.print(",");
// ...

Merci!

Oui j'avoue que j'aurais mieux fait de me couché ce matin là, rtcTime() aurait été plus parlant j'avoue...

Je test et rapporte le résulat, en tout cas ça me plait bien, ta solution.

Heu... Et pour:

client.print( "Content-Length: " );
client.println( data.length() );

dudux2:
Heu... Et pour:

client.print( "Content-Length: " );

client.println( data.length() );

Simple : ne transmet pas l'entête de taille.
Le double retour ligne termine la requête.

Merci!

Bon pour commancer si je met en commentaire (avec mon ancien code):

client.print( "Content-Length: " );
client.println( data.length() );

ça ne fonctionne plus, j'ai la tête fatigué ce soir, je regarde de plus prêt demain.

Tu fermes bien ta connexion après avoir envoyé les données ?

Si ça ne marche pas même en fermant la connexion c’est surement que ton serveur en face s’attend obligatoirement à avoir une requête au format HTTP/1.1 avec le content-length qui va bien.

Dans ce cas tu peut envoyer une taille fixe si ta chaîne fait toujours la même taille (c’est le plus simple), sinon tu peut regarder du côté des transfert en mode “chunk”.
http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.4

Une autre solution selon moi serait de tout simplement faire un POST avec un contenu de corps vide (Content-length 0) est de passer ta chaîne en paramètre de l’URI (comme avec un GET).