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 :
- la carte micro SD n'a pas été mise dans l'emplacement prévu sur
le module éthernet ou est mal enfoncée
- la carte micro SD a été formatée dans un format plus moderne que
FAT16 ou FAT32 et ce format n'est pas compatible avec les logiciels
Arduino
- Les 2 fichiers sont absents ou installés dans un répertoire de la
carte micro SD plutôt qu'à sa racine.
- Aucun des 2 fichier n'a le bon nom.
- Il y a eu un problème pour initialiser le contrôleur de carte SD.
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.