Compteur de passages


Ce premier programme va afficher toujours la même page. Mais à chaque affichage de cette page, la valeur d'un compteur va augmenter.

Pour téléverser ce programme sur la carte Arduino, il faut d'abord mettre dans un répertoire les 3 fichiers suivants :
Sur la carte SD, on mettra les fichiers passages.htm et err404.htm

Le fichier HTML utilisé

Le fichier HTML contenant la page web à afficher est simple :
    <!DOCTYPE html>
    <html>
    <head>
        <title>Arduino Web Page</title>
    </head>
    <body>
        <h1>Bonjour depuis l'Arduino  !</h1>
        Une page web depuis le serveur Arduino<br>
        Passage XXXNUM
    </body>
    </html>
En affichant directement le fichier HTML avec un navigateur web, on obtiendrait ce résultat :



Le but du programme Arduino est de fournir cette page au navigateur, mais en remplaçant la chaine de caractères XXXNUM par un nombre qui augmente de 1 à chaque nouvel affichage de la page.

Le programme Arduino

Comme tous les programmes Arduino, celui-ci possède une fonction setup () qui initialise le matériel, à savoir la carte Ethernet et le lecteur de carte SD.

On supposera que l'adresse MAC et l'adresse IP de la carte Ethernet ont été configurées conformément à ce qui est dit dans la page Généralités



Intéressons-nous à ce que fait la fonction loop ()

Tout d'abord, on teste si un navigateur web demande une page :
    client = serveur.available ();
Si c'est le cas, on récupère dans la variable client un identifiant qui permettra de communiquer avec le navigateur web s'il a demandé une page.

Dans, ce cas, on récupère le message envoyé par le navigateur.
Cela se fait avec la fonction lire_trame_client (...) qui peut accepter un nombre variable de paramètres dont tous, sauf le premier, sont optionnels.

Dans le cas de ce premier programme, on affichera toujours la même page web. Il n'est donc pas nécessaire de décoder ce que le navigateur web a demandé. On se contentera donc de lire le message envoyé par le navigateur web sans rien conserver. Cela se fait en utilisant la fonction lire_trame_client (...) avec un seul paramètre :
    lire_trame_client (client);
Ensuite, c'est au tour du serveur de répondre qu'il a reçu la demande du navigateur web.
    envoie_entete_reponse (client);
Le fonctionnement de cette fonction est simplifié par rapport à ce qui se passe dans un vrai serveur web : On envoie systématiquement le code de retour 200 (page demandée disponible) et c'est plus tard que les cas particuliers seront traités.

Après l'entête de la réponse, il faut envoyer le contenu du fichier HTML que le navigateur affichera. A une modification près, il est mémorisé sur la carte SD.

Le fichier HTML qu'on veut envoyer a pour nom passages.htm. Il est déjà mémorisé dans une variable de la fonction loop () :
    char fic_html [] = "passages.htm";
Pour accéder à ce fichier, on utilise une fonction d'ouverture :
    descfic = SD.open (fic_html, FILE_READ);
C'est le mode d'accès aux fichiers commun à de nombreux langages de programmation : on commence par "ouvrir" le fichier en appelant une fonction qui reçoit comme paramètre le nom du fichier concerné et le mode d'accès au fichier choisi (ici, accès en lecture), et cette fonction, si elle s'est bien déroulée, retourne dans une variable ici descfic) un descripteur de fichier qu'on utilisera par la suite.

Si la fonction SD.open (...) a pu accéder au fichier demandé, aucun problème. Dans le cas contraire, on essaie d'utiliser le fichier de remplacement err404.htm
    if (! descfic)
        descfic = SD.open (F("err404.htm"), FILE_READ);
Supposons qu'on ait pu accéder à l'un des deux fichiers, comme notre site doit afficher le nombre de passages sur la même page, on utilise une variable compteur qui est déclarée au tout début du programme avec 0 comme valeur initiale.
    int compteur = 0;
On va rajouter 1 à cette variable :
    compteur ++;
On aurait pu écrire de manière plus classique mais moins condensée :
    compteur = compteur + 1;
compteur est une variable numérique. Nous avons besoin de transformer la valeur qu'elle contient en une série de chiffres. C'est ce que fait l'instruction issue du langage C :
    sprintf (valconv, "%d", compteur);
valconv est un tableau de caractères qui a été déclaré un peu avant :
    char valconv [10];
Ainsi déclaré, il peut être vide ou contenir un nombre de 1 à 9 chiffres (ou tout autre texte jusqu'à 9 caractères). Dans la pratiques, 5 cases dans le tableau auraient été largement suffisantes pour mettre des valeurs jusqu'à 9999.

Pour l'instant, on n'a toujours pas envoyé au navigateur web le fichier HTML. Mais tout est prêt pour le faire en seulement 2 instructions.
    coprep_chaine (descfic, client, "XXXNUM", valconv);
Comme on s'est contenté d'ouvrir le fichier HTML sans le lire, on est positionné au début de ce fichier.

La fonction coprep_chaine (...) commence par lire le fichier HTML ligne par ligne et envoyer son contenu au navigateur web.
A un certain moment, on arrive à la ligne :
        Passage XXXNUM
La fonction coprep_chaine (...) recopie également cette ligne là, mais en remplaçant XXXNUM par le chiffre ou la série de chiffres mémorisée dans la variable valconv qui correspond à la valeur du compteur de passages.

Après ce traitement, il reste des lignes du fichier HTML à envoyer au navigateur web, et ces lignes n'ont pas besoin d'être modifiées. L'envoi de la fin du fichier HTML se fait en une instruction :
    copie_jusque_fin (descfic, client);
On n'a plus besoin du fichier HTML. Donc, pour faire le choses proprement, on va dire à la carte Arduino qu'elle peut oublier ce qu'on lui a demandé de faire au moment de l'ouverture du fichier, et ainsi libérer de la mémoire.
    descfic.close ();
Remarque : Si c'est le fichier err404.htm qui a été ouvert faute d'avoir trouvé l'autre, l'instruction coprep_chaine (...) ne trouvera pas la chaine de caractères XXXNUM cherchée et va envoyer au navigateur web le fichier HTML en entier. Après quoi, l'instruction copie_jusque_fin (...) n'a plus rien à faire. Même dans ce cas, le fichier HTML a été envoyé correctement au navigateur web.

Il reste le cas où aucun des deux fichiers n'a pu être ouvert précédemment. Ce problème peut avoir de nombreuses causes :
Tous ces cas, sont résumés par un message d'erreur générique envoyé au navigateur web :
    else
        client.println (F("Probleme probable d'acces a la carte SD"));
Et comme ce message n'est pas envoyé à l'intérieur d'un fichier HTML, pour éviter les "problÚmes d'affichage des caractÚres accentués", il n'en comporte pas.

Après un petit délai pour le transfert des données, on coupe la connexion avec le navigateur client :
    client.stop ();
Et la carte Arduino attendra une nouvelle demande d'affichage de la page pour recommencer le même travail.