Tutoriel de programmation multi-tâches

Ce tutoriel à but éducatif met en œuvre des fonctionnalités évoluées qui apportent des techniques de programmation intéressantes tout en simplifiant l’écriture.

Les caractéristiques du projet :

– Construction d’un véhicule à deux roues piloté par une interface web.

– Équipé d’une sonde ultrasonique.

– Le système de fichier LittleFS.

– Un serveur web de type asynchrone.

– Un gestionnaire de tâches asynchrone qui permet l’exécution des tâches en parallèle.

– Exemple de script java.

Le principal attrait de ce projet réside dans la programmation. La conception technique est très simple.

Composants et montage technique

Le montage ne nécessite que peu de composants. Le contrôleur ESP32 peut être sélectionné dans la gamme de produits à base d’ESP32 ou ESP8266.

L’ensemble des fichiers est disponible ici.

Programmation – partie 1 : le système de fichiers

Lorsqu’un programme comporte des pages web la mémoire disponible réservée pour le code est insuffisante. On utilisera un système de fichier comme LittleFS pour copier la page web en mémoire flash indépendamment du programme. Le programme fera alors appel au fichiers.

– Montage du système de fichier LittleFS dans la mémoire Flash de l’ESP32 et copie des fichiers index.html et style.css

Le fichier index.html contient notre page web et le style associé style.css. Ils sont stockés dans le sous-répertoire « data » du programme.

La création du système de fichier se fait depuis la page d’Arduino IDE en utilisant le raccourci Ctrl+maj+P saisir « upload » et choisir le ligne contenant LittleFS. Au préalable il faudra connecté l’ESP32 (carte et port). Arduino formate la mémoire flash, configure le système de fichier et charge les deux fichiers.

Cette opération sera à refaire uniquement si le contenu le la page web change.

– Accès au système de fichiers par le programme :

La déclaration et l’utilisation sont simples. La bibliothèque à installer est « LittleFS_ESP32 lorol»

==== dans le programme

(partie déclaration)

#include <LittleFS.h> // file system library

(partie setup)

// init file system

LittleFS.begin() // start access to the file system

..

server.on(“/”, HTTP_GET, [](AsyncWebServerRequest *request) {

request->send(LittleFS, “/index.html”, String(), false, processor);});

====

Programmation – partie 2 : le serveur web

Le mode de fonctionnement est asynchrone. Il permet à d’autres tâches de s’exécuter sans bloquer l’exécution du code principal.

La page web est constituée de boutons ainsi que d’une barre de progression avec indication de la vitesse. En fonction du bouton une action sur les moteurs est effectuée : direction et vitesse.

====

(Programme déclaration)

#include <ESPAsyncWebServer.h>

AsyncWebServer server(80); // Creating an asynchronous server on port 80

(Programme setup)

// Starting the web server

server.begin();

..

// when web page is called (initial call)

server.on(“/”, HTTP_GET, [](AsyncWebServerRequest *request) {

request->send(LittleFS, “/index.html”, String(), false, processor);

}); // location of the web page in the file system

…

// when buttom « fast » is pressed

server.on(“/fas”, HTTP_GET, [](AsyncWebServerRequest *request) {

motAspeed += 10;

motBspeed += 10;

request->send(LittleFS, “/index.html”, String(), false, processor);};

====

Modification d’informations dans la page web par la fonction « processor ».

=====

(Programme déclaration)

// Replacement function for dynamic content

String processor(const String& var) {

motorcontrol();

if (var == “SPEEDEMO“) {

int val = max(motAspeed, motBspeed);

String section;

section = “<label>”;

section += “Speed L = ” + String(motBspeed) + ” Speed R = ” + String(motAspeed) + ” “;

section += “<progress value= ” + String(val) + ” ” + “max=\”100\”> 10% </progress>”;

section += “</label>”;

return section;

}

return String();

}

====

Cette fonction permet l’intégration d’une section de code pour modifier la page web. On ajoute ainsi du code html.

La section est localisée par la nom «%SPEEDEMO % » dans la page web. Elle est localisée par la fonction qui procède à l’intégration de code html dans la page. Cette intégration se fait à chaque rechargement de la page web.

Programmation – partie 3 : gestionnaire de tâches asynchrone

Ce gestionnaire multi-tâches permet en plus du serveur web de gérer des tâches en parallèle sans liens les unes avec les autres.

Une de ces tâches est le contrôle de la distance utilisant l’interface SR-SH04. La tâche se réveille toutes les secondes et mesure la distance entre le véhicule et un obstacle potentiel. Si la distance mesurée est inférieure à 20cm une action d’évitement est opérée. Le véhicule recule et change de direction automatiquement.

Parallèlement la tâche ‘serveur web’ reste à l’écoute des actions des boutons de la page web. On peut manipuler le comportement du véhicule sans contrainte. Si par contre le véhicule se rapproche de trop près d’un obstacle il est dévié.

Les instructions du programme :

====

(Programme déclaration)

#include <AsyncTask.h>

AsyncTask asyncTask;

(Programme setup)

// Starting schedule asynchronous task

asyncTask.repeat(taskOne, 1000);

(Programme fonctions)

// Asynchrone tasks

void taskOne() { autocontrol();}

// This function monitors the distance and, if necessary, causes the vehicle to back up and change direction.

void autocontrol() {

distance();

if (cm >= 20) {

} else if (cm < 20) {

motAdir = 1; motBdir = 1;

motorcontrol();

delay(2000);

motBdir = 0;

motorcontrol();

delay(1000);

motAdir = 0; motBdir = 0;

motorcontrol(); } }

====

Pour programmer d’autres tâches il suffit de les déclarer par :

asyncTask.repeat(f, t); où « f » désigne la fonction à lancer et « t » intervalle entre deux exécution en millisecondes.

Le programme est découpé en fichiers afin de simplifier la lecture et la compréhension.

Programme principal : esp-web-littleFS-final.ino

Routes pour actions : routes.ino

Actions sur les moteurs : motor-functions.ino

Sonde ultrasonique : ultrasonic.ino

Programme extension ludique

Pour donner une autre dimension au projet une deuxième page web a été ajoutée. Elle est affichée avec le bouton « pr1 ». Cette page fait appel à un script java qui utilise une fonction de la bibliothèque graphique Google.

Le script java est intégré de la manière suivante :

server.on(“/script.js“, HTTP_GET, [](AsyncWebServerRequest *request) {

request->send(LittleFS, “/script.js“, “text/js”); });

Le déclencheur « pr1 » indique la page à utiliser ainsi que le traitement avant affichage de la page « processor1 »

server.on(“/pr1“, HTTP_GET, [](AsyncWebServerRequest *request) {

request->send(LittleFS, “/speed.html”, String(), false, processor1); });

Le traitement avant affichage remplace la variable «%SEEDSELECTION % dans la page par les valeurs des variables à utiliser. On injecte ainsi du code java.

// Replacement function for dynamic content

String processor1(const String& var) {

if (var == “SPEEDSECTION”) {

String section = “var valA = ” + String(motAspeed) + “; var valB = ” + String(motBspeed);

return section;

}

return String();

}

Le bouton « return » sur la page permet de revenir à la page principale.

server.on(“/ret”, HTTP_GET, [](AsyncWebServerRequest *request) {

request->send(LittleFS, “/index.html”, String(), false, processor); });

Conclusion 

Ce projet ne comporte pas beaucoup de composants et le montage est simple à réaliser.

Il permet de découvrir la gestion multitâches et le serveur asynchrone.

Avec LittleFS les pages web (.html), les script java (.js) et les feuilles de style (.css) sont stockées dans le système de fichier installé sur le contrôleur.

Un exemple de script java complète l’exercice.

Les références ci-dessous permettent d’exploiter ces fonctions de manière plus approfondies. Enjoy it !

Références :

LittleFS_ESP32 :

https://randomnerdtutorials.com/esp32-write-data-littlefs-arduino/

https://randomnerdtutorials.com/esp32-web-server-littlefs/

AsyncTask :

https://www.luisllamas.es/libreria-arduino-asynctask/

https://yiweimao.github.io/blog/async_microcontroller/

https://github.com/luisllamasbinaburo/Arduino-AsyncTask/blob/master/examples/AlternateTask/AlternateTask.ino

Async web server :

https://randomnerdtutorials.com/esp32-async-web-server-espasyncwebserver-library/