Récupérer une info dans une page web avec l’ethernet shield

Ce script permet de tester de manière régulière une page et vérifier une information dans son code, préparé à cette fin. Pas de parsing html complexe ici.

Ce script est une version modifiée du code de Tom Igoe pour récupérer des tweets, pour permettre une utilisation plus large.

Pour préparer le terrain, j’ai fabriqué une page php qui lit et update une valeur dans un fichier txt avec du php. Si ceci vous échappe, vous pouvez déposer un simple fichier html ou même un fichier texte sur un serveur.

1. Préparer un code PHP/HTML

<?php
// on ouvre en lecture - ecriture
if(!$fichier = fopen("compteur.txt", "r+")) {
               echo "<div style='color:red'>lecture du fichier impossible</div>";
} else {
$lehtml="";
// Tant quon est pas à la fin
while (!feof($fichier)) {
$buffer = fgets($fichier, 4096);
$lehtml .=$buffer;
}

     
}
       $lehtml = (int) $lehtml;
       $lehtml++;
       echo "<info>".$lehtml."</info>";
       
       fseek($fichier, 0); // On remet le curseur de lecture/ecriture au début du fichier
       fputs($fichier, $lehtml);

// fermeture du fichier - important
fclose ($fichier);
?>

La page contiendra juste <info>1</info> et s’incrémente de 1 à chaque rechargement.

2. récupérer l’adresse de votre fichier

Grâce au site http://web-sniffer.net/, vous pouvez connaitre les information nécessaire à paramétrer le script arduino.
Entrez l’url web de votre fichier et la page conformera le nom du serveur et le GET.

Coder arduino

Voici un code de base pour récupérer la page proprement.
- l’adresse ip du shield doit être placée dans le début du code. Le shield tente une connection automatique (en dhcp) mais on placera par sécurité une addresse manuelle, en fonction du réseau local. Ici "IPAddress ip(192,168,1,20) ;" (attention, les chiffres sont séparés par des virgules.
- L’adresse du fichier à rapatrier est séparée en deux : le nom de domaine lui-même, (ici www.codedrops.net), et la requête (grosso modo ce qui suit l’adresse), est ici "/sandbox/writefile/update.php". Le protocole est HTTP/1.1 (c’est souvent le cas mais vérifiez avec web-sniffer.net) . Le host à la ligne suivante est parfois obligatoire, c’est aussi une forme de politesse, ici www.codedrops.net.

/*  
lire un fichier net avec une info
basé sur le script de tweet de Tom Igoe

* Ethernet shield attached to pins 10, 11, 12, 13

This code is in the public domain.

*/
#include <SPI.h>
#include <Ethernet.h>

// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = { 0x00, 0xAA, 0xBB, 0xCC, 0xDE, 0x01 };
IPAddress ip(192,168,1,20);

// initialize the library instance:
EthernetClient client;

const unsigned long requestInterval = 60000;  // delay between requests

char serverName[] = "www.codedrops.net";

boolean requested;                   // whether you've made a request since connecting
unsigned long lastAttemptTime = 0;   // last time you connected to the server, in milliseconds

String currentLine = "";            // string to hold the text from server
String message = "";                  // string to hold the message
boolean lecture = false;       // if you're currently reading the message

void setup() {
 // reserve space for the strings:
 currentLine.reserve(256);
 message.reserve(150);

 // Open serial communications and wait for port to open:
 Serial.begin(9600);
 while (!Serial) {
   ; // wait for serial port to connect. Needed for Leonardo only
 }

 // attempt a DHCP connection:
 Serial.println("Attempting to get an IP address using DHCP:");
 if (!Ethernet.begin(mac)) {
   // if DHCP fails, start with a hard-coded address:
   Serial.println("failed to get an IP address using DHCP, trying manually");
   Ethernet.begin(mac, ip);
 }
 Serial.print("Mon adresse:");
 Serial.println(Ethernet.localIP());
 // premiere connection :
 connectToServer();
}

void loop(){
 if(message.length() > 0 && lecture==false){
   Serial.print("je viens de recevoir un message : ");
  Serial.println(message);
 message="";
 }
 
 if (client.connected()) {
   checke_page();
 }
 else if (millis() - lastAttemptTime > requestInterval) {
   // if you're not connected, and two minutes have passed since
   // your last connection, then attempt to connect again:
   connectToServer();
 }
}

void checke_page(){
 if (client.available()) {
   // read incoming bytes:
   char inChar = client.read();

   // add incoming byte to end of line:
   currentLine += inChar;

   // si on a un retour chariot, c'est que ce n'est pas encore le debut, on supprime:
   if (inChar == '\n') {
     currentLine = "";
   }

   // si on trouve le message <text>, c'est
   // que le message suit:
   if ( currentLine.endsWith("<info>")) {

     // debut du message, on vide la string message:
     lecture = true;
     message = "";
     inChar = client.read(); // lire le caractere suivant
   }
   // on lit caractere par caractere,
   // et les ajoute au message
   if (lecture) {
     if (inChar != '<') {
       message += inChar;
     }
     else {
       // isi vous avez un "<",
       // c'est la fin du message:
       lecture = false;
         
       // fermer la connexion au serveur:
       client.stop();
     }
   }
 }
}

void connectToServer() {
 // attempt to connect, and wait a millisecond:
 Serial.println("connecting to server...");
 if (client.connect(serverName, 80)) {
   Serial.println("making HTTP request...");
   // make HTTP GET request:
   client.println("GET /sandbox/writefile/update.php HTTP/1.1");
   client.println("Host: www.codedrops.net");
   client.println();
 }
 // remettre le compteur a zero pour la prochaine connexion:
 lastAttemptTime = millis();
}  

Une fois le message récupéré, on peut le traiter, le comparer et déclencher quelque chose...