[RESOLU] Arduino + Ethernet : réception GET aléatoire

Bonjour,

J’ai repris un sketch de récupération de téléinfo et d’envoi vers une page php sur un serveur distant par Arduino et une carte Ethernet (les 2 sont “officiels”).

Pour essai, le GET est envoyé à travers l’Url toutes les 20 secondes mais il s’avère que le serveur distant (chez OVH) ne le voit que de façon aléatoire, par exemple : 10:39:07 ; 10:46:59 ; 11:05:54.

A la lecture des forums, j’ai bien compris qu’il y a un problème de synchro entre l’Arduino et le serveur mais je ne sais pas comment faire pour régler les délais, mes essais n’améliorent pas la situation.

J’ai simplifié au maximum le sketch ci-dessous pour conserver le même résultat. Qu’en pensez-vous ?

Cordialement.

#include <SPI.h>
#include <Ethernet.h>
#include <MsTimer2.h>

//--------------------------------------------------------------------
// ElecVisu - Récupération Téléinfo
//--------------------------------------------------------------------

// please modify the following two lines. mac and ip have to be unique
// in your local area network. You can not have the same numbers in
// two devices:
byte mac = { 0x90, 0xA2, 0xDA, 0x0F, 0x70, 0xEB };

unsigned int delay_spool = 20;
unsigned int val_delay = 0;

EthernetClient client;

// Delay spool ---------------------------------------------------
void time_spool() {
val_delay++;
}

// Initialisation carte Arduino ----------------------------------
void setup()
{
int i;

Serial.begin(1200);
Serial.println(delay_spool);

// Initialisation carte TcpIp ------------
Serial.print("Init Tcp… ");
while (Ethernet.begin(mac) == 0) {
Serial.println(“Failed to configure DHCP, retry…”);
delay(200);
}
delay(1000);
Serial.println(“done”);

// Initalise tempo spool a 1s ------------
MsTimer2::set(1000, time_spool); // 1s par period
if (delay_spool != 0) MsTimer2::start();

}

// Main --------------------------------------------------------------------------
void loop()
{

// Appel page maj sur serveur web ----------
if (val_delay > delay_spool) {
val_delay = 0;

if (client.connect(“mon_site”,80)) {
client.println(“GET /teleinfo/maj.php?OPTARIF=BASE&BASE=15032000&HCHC=0&HCHP=0&PTEC=TH…&IINST=2&PAPP=510 HTTP/1.1”);
client.println(“Host: mon_site”);
client.println();

char c = client.read();
client.stop();

Serial.println(“GET /teleinfo/maj.php?OPTARIF=BASE&BASE=15031056&HCHC=0&HCHP=0&PTEC=TH…&IINST=2&PAPP=510 HTTP/1.1”);
Serial.println(“Host:mon_site”);
Serial.println();

}
else {
Serial.println(“cnx failed”);
}
}
Ethernet.maintain();
}

bonjour, réfères toi à http://playground.arduino.cc/Main/MsTimer2 sauf erreur de ma part, c'est toutes les 1s (1000) que tu envoie une requete +1 ms à chaque boucle

val_delay++;

donc tu te fais jeter par le server pour attaque DDOS si ca se trouve

20s => 20000

infobarquee:
sauf erreur de ma part, c’est toutes les 1s (1000) que tu envoie une requete +1 ms à chaque boucle

val_delay++;

Merci pour avoir regardé.

Je ne suis pas l’auteur de ces lignes dont certaines fonctions sont utilisées par ailleurs dans le sketch ce qui explique la forme.

MsTimer est réglé à 1 sec pour que la variable val_delay soit incrémentée de 1. Lorsque cette dernière dépasse la valeur de delay_spool (ici c’est 20) alors on se connecte au serveur et on envoie le GET.
Pour moi la connexion a donc lieu toutes les 20 secondes.

Finalement, j’ai rajouté un délai d’une seconde entre la lecture du caractère entrant et la déconnexion du serveur et ça fonctionne : la base de données est mise à jour toutes les 20 secondes comme demandé.

char c = client.read();
delay(1000);
client.stop();

sauf que tu travaille en millisecondes donc 20s => 20 000 et non 20 ;) donc toutes les 20 ms la condition est valide et donc GET en marche, ca fait beaucoup, non? donc DDOS perceptible par le server et suivant le nb de connexion max, tu te fais jarter ;)

delay_spool = 20;
*****
******
if (val_delay > delay_spool) {

ne pas confondre milliseconde et seconde :)

Je comprends ce que tu veux dire mais la variable val_delay est un compteur comme dans une boucle. Chaque fois que MsTimer2 dépasse 1000 millisecondes, la fonction time_spool est appelée et la variable val_delay est incrémentée de 1. Lorsqu'elle atteint 20, le GET est envoyé.

// Delay spool ---------------------------------------------------
void time_spool() {
  val_delay++;
}

Tout fonctionne depuis que j'ai ajouté 1 seconde avant de couper la connexion.

J'ai remis le réglage d'origine à 240 sec, et la base est mise à jour toutes les 4 minutes : 20:47:38 ; 20:51:39 ; 20:55:40 ; 20:59:41 ; 21:03:43 ; 21:07:44

J'ai ajouté 1 sec au pif, je n'ai pas d'explication ...

Tu te connectes à un serveur, tu lui parles puis tu coupes la communication tout de suite, après avoir essayé de lire 1 octet, que tu n’as d’ailleurs probablement même pas reçu: normal que le serveur laisse tomber, il n’a pas commencé à te répondre que tu raccroches…
Quand on parle à quelqu’un, le dialogue se passe beaucoup mieux si on écoute les réponses :smiley:

Tu devrais remplacer

    char c = client.read();
        client.stop();

par quelque que chose comme ça:

 while (client.connected())
{
  if (client.available())
    char c = client.read();
}
    client.stop();

en gros, tant qu’on est connecté au serveur, s’il y a un octet à lire, on le lit.

ps: le delay(1000) que tu as ajouté laisse au serveur 1 seconde de temps de réaction, dans ton réseau local ça passe apparement, mais le jour où le réseau est surchargé ou que tu passes par une autre connexion… boum, et tu ne comprendra pas pourquoi ça ne marche plus, puisque “chez moi, y’a tout qui marche, le réseau ici est pourri et cassé, bouhhhh” :slight_smile:

Bonjour,

J'ai remplacé mon délai arbitraire par ce code :

while(client.connected()) { if(client.available()){ char c = client.read(); // Serial.print(c); } } client.stop();

Merci donc cbrandt !

Cordialement. Henri