dimanche 28 février 2021

Contrôler un diaporama Powerpoint avec Arduino Leonardo

L'Arduino Leonardo est pratiquement identique à l'Arduino Uno, à une exception près: grâce à son microcontrôleur Atmega32u4, un ordinateur le reconnaît comme un périphérique USB. 

Dans cet article, je m'intéresse à la possibilité de contrôler un diaporama Powerpoint grâce à un Arduino Leonardo (j'ai également obtenu d'excellents résultats avec le logiciel gratuit Libre Office Impress). 

Le Leonardo peut ainsi servir de base à une boîte de contrôle munie de boutons actionnés par un conférencier ou par les visiteurs d'une exposition.  On peut aussi programmer le Leonardo de façon à afficher automatiquement une diapositive qui correspond à valeur mesurée par un capteur, etc.

Pour tous les exemples qui suivent, le Leonardo est branché à un port USB d'un ordinateur sur lequel un diaporama Powerpoint est en cours.

Passer à la diapo suivante

Une façon de passer à la diapo suivante, lorsque vous utilisez le clavier d'un ordinateur, consiste à appuyer sur la touche "flèche droite du clavier".  En appuyant sur la touche "flèche gauche" du clavier, vous reculez à la diapo précédente. Grâce à la bibliothèque Keyboard qui fait partie intégrante de l'IDE Arduino, il est facile de transformer le Leonardo en un mini-clavier muni de deux boutons: un bouton permettant de passer à la prochaine diapo, et un bouton permettant de revenir à la diapo précédente.

-

/*
Leonardo_powerpoint_1
Contrôle d'une présentation powerpoint avec un Arduino Leonardo
Un bouton pour passer à la diapo suivante, un bouton
pour revenir à la diapo précédente.
Plus d'infos:
https://electroniqueamateur.blogspot.com/2021/02/controler-un-diaporama-powerpoint-avec.html
*/
#include "Keyboard.h"
#define prochaineDiapo 8 // bouton "prochaine diapo" branché à broche 8 du Leonardo
#define diapoPrecedente 9 // bouton "diapo précédente" branché à broche 9 du Leonardo
void setup() {
pinMode(prochaineDiapo, INPUT);
pinMode(diapoPrecedente, INPUT);
Keyboard.begin();
}
void loop() {
if (digitalRead(prochaineDiapo)) {
Keyboard.write(KEY_RIGHT_ARROW);
delay(100); // anti rebond
}
if (digitalRead(diapoPrecedente)) {
Keyboard.write(KEY_LEFT_ARROW);
delay(100); // anti rebond
}
}

-

Déplacer le pointeur à l'écran

Il peut être utile de déplacer le pointeur de souris à l'écran, soit pour montrer à l'assistance un endroit précis sur la diapo, ou encore pour cliquer sur un élément interactif de la présentation. Cette fois, nous transformons le Leonardo en une souris munie de 5 boutons: 4 boutons qui servent respectivement à déplacement le pointeur vers la gauche, vers la droite, vers le haut et vers le bas, et un cinquième bouton  qui a le même effet qu'un clic de souris.



-

/*
Leonardo_powerpoint_2
Contrôle d'une présentation powerponit avec un
Arduino Leonardo
4 boutons pour déplacer le pointeur à l'écran et
un bouton pour un clic de souris.
Pour plus d'infos:
https://electroniqueamateur.blogspot.com/2021/02/controler-un-diaporama-powerpoint-avec.html
*/
#include "Mouse.h"
// connexion des boutons
#define gauche 3
#define droite 4
#define haut 5
#define bas 6
#define clic 7
void setup() {
pinMode(gauche, INPUT);
pinMode(droite, INPUT);
pinMode(haut, INPUT);
pinMode(bas, INPUT);
pinMode(clic, INPUT);
}
void loop() {
if (digitalRead(gauche)) {
Mouse.move(-1, 0, 0);
delay(5);
}
if (digitalRead(droite)) {
Mouse.move(1, 0, 0);
delay(5);
}
if (digitalRead(haut)) {
Mouse.move(0, -1, 0);
delay(5);
}
if (digitalRead(bas)) {
Mouse.move(0, 1, 0);
delay(5);
}
if (digitalRead(clic)) {
Mouse.click();
delay(100); // anti-rebond
}
}

-

Accéder à une diapo spécifique

C'est relativement peu connu, mais si vous désirez afficher, par exemple la 43e diapo, vous pouvez le faire en appuyant successivement sur les touches "4", "3", puis "Entrée" du clavier. Puisque le Leonardo peut être programmé pour imiter cette succession de touches, un diaporama powerpoint devient une façon facile de présenter, sur grand écran et en haute résolution, une séquence vidéo qui dépend du bouton enfoncé par le visiteur d'une exposition, ou une image qui dépend de la valeur mesurée par un capteur.

Dans la séquence vidéo ci-dessous, un diaporama Powerpoint constitué de 11 diapos numérotées de 0 à 10 affiche une valeur contrôlée par un potentiomètre. Remplacez le potentiomètre par un télémètre à ultrasons ou un accéléromètre: les possibilités sont sans limites!


-

/* Leonardo_Powerpoint_3
Un potentiomètre permet de changer de diapo sur un powerpoint
Plus d'infos:
https://electroniqueamateur.blogspot.com/2021/02/controler-un-diaporama-powerpoint-avec.html
*/
#include "Keyboard.h"
#define nombre_de_diapos 11
int diapoActive;
void setup() {
}
void loop() {
int diapoCible;
diapoCible = analogRead(0) * nombre_de_diapos / 1023 + 1;
if ( diapoCible != diapoActive) { // il est temps de changer de diapo!
switch (diapoCible) {
case 1:
Keyboard.write('1');
Keyboard.write(KEY_RETURN);
break;
case 2:
Keyboard.write('2');
Keyboard.write(KEY_RETURN);
break;
case 3:
Keyboard.write('3');
Keyboard.write(KEY_RETURN);
break;
case 4:
Keyboard.write('4');
Keyboard.write(KEY_RETURN);
break;
case 5:
Keyboard.write('5');
Keyboard.write(KEY_RETURN);
break;
case 6:
Keyboard.write('6');
Keyboard.write(KEY_RETURN);
break;
case 7:
Keyboard.write('7');
Keyboard.write(KEY_RETURN);
break;
case 8:
Keyboard.write('8');
Keyboard.write(KEY_RETURN);
break;
case 9:
Keyboard.write('9');
Keyboard.write(KEY_RETURN);
break;
case 10:
Keyboard.write('1');
Keyboard.write('0');
Keyboard.write(KEY_RETURN);
break;
case 11:
Keyboard.write('1');
Keyboard.write('1');
Keyboard.write(KEY_RETURN);
break;
}
diapoActive = diapoCible;
}
delay(100);
}

-


À lire également:

D'autres projets impliquant l'Arduino Leonardo:


Yves Pelletier (TwitterFacebook)

vendredi 26 février 2021

Dans un blog près de chez vous (17)



 RitonDuino:


Framboise314:


MCHobby:



mercredi 24 février 2021

ESP8266 et ESP32: Contrôle d'une matrice de LEDs RGB

J'avais déjà fait l'essai de ma matrice constituée de 16 rangées de 16 LEDs RGB (contrôleur WS2812B) avec un Arduino Uno. Cette fois-ci, c'est avec un module ESP32 ainsi qu'avec un module ESP8266 que j'ai pu contrôler (à distance) les LEDs de la matrice.


Alimentation et niveau logique

Il faudra choisir pour la matrice de LEDs une alimentation capable de fournir un courant de quelques ampères, particulièrement si vous prévoyez allumer ses 256 LEDs en même temps.

La fiche technique du WS2812B indique que son alimentation doit se situer entre 3,5 V et 5,3 V, et que son VIH (la plus petite tension considérée comme un niveau logique haut) est égal à 70% de la tension d'alimentation. 

Nous pouvons en conclure que:

  • Si nous alimentons le WS2812B avec une tension de 3,3 V, son fonctionnement correct n'est pas garanti, puisqu'il s'agit d'une tension plus faible que le minimum recommandé.
  • Si le WS2812B est alimenté à 5 V, un signal logique d'au moins 3,5 V est requis, en principe, pour garantir son fonctionnement; le signal de 3,3 V issu d'un ESP8266 ou d'un ESP32 pourrait donc être insuffisant.  Dans ce cas, un convertisseur de niveau logique pourrait être nécessaire pour élever à 5 V le signal généré par le microcontrôleur. 

Une autre solution consiste à diminuer un peu la tension d'alimentation de la matrice (si la tension d'alimentation du WS2812B est de 4,7 V ou moins, un niveau logique de 3,3 V se situe dans les normes recommandées par le fabricant).

Pour ma part, tout a fonctionné sans problème en utilisant directement le signal de 3,3 V généré par la broche GPIO 5 du module ESP, même quand la tension d'alimentation de la matrice était de 5 V.

Connexions

Le verso de la matrice comporte 8 fils, mais ils ne sont pas tous nécessaires (ils servent entre autre à brancher plusieurs matrices ensemble, afin d'obtenir un panneau géant).

  • Un des fils rouges marqués "5 V" est branché à la borne positive de l'alimentation de la matrice de LEDs (cette alimentation doit être capable de générer quelques ampères).
  • Le fil noir (marqué GND) est branché à la borne négative de l'alimentation de la matrice de LEDs.
  • Un des fils blancs (marqués GND) est branché à la masse (sortie GND) du module ESP32 ou ESP8266.
  • Le fil vert marqué DIN est branché à la broche GPIO 5 du module ESP32 ou ESP8266 (ça peut aussi être une autre broche, si vous modifiez le sketch ci-dessous en conséquence).


Installation des bibliothèques

J'ai conservé les deux mêmes bibliothèques que j'avais utilisées lors de l'utilisation avec l'Arduino Uno: la bibliothèque FastLED de Daniel Garcia (disponible par le gestionnaire de bibliothèques de l'IDE Arduino) et la bibliothèque LED Matrix par Jorgen - Viking God.

Sketch

Les deux sketches que j'avais rédigés lors de l'essai de la matrice de LEDs avec l'Arduino Uno fonctionnent très bien avec les modules ESP, à la condition de modifier le numéro de la broche GPIO utilisée (5 plutôt que 3).

Dans le sketch ci-dessous, j'ai choisi d'utiliser les fonctionnalités WiFi des modules ESP8266 / ESP32: une page web générée par le module ESP permet d'allumer n'importe quelle LED de la matrice avec la couleur désirée (on choisit "Noir" pour éteindre la LED).

Pour atteindre cette page web, on utilise l'adresse IP affichée sur le moniteur série de l'IDE Arduino lors du démarrage du programme.

-

/**********************************************************************
ESP_matrice_RGB
Contrôle par une page web d'une matrice RGB 16 X 16.
ESP8266 ou ESP32
Pour plus d'infos:
https://electroniqueamateur.blogspot.com/2021/02/esp8266-et-esp32-controle-dune-matrice.html
***********************************************************************/
// inclusion des bibliothèques utiles
// pour la communication WiFi:
#if defined ARDUINO_ARCH_ESP8266 // s'il s'agit d'un ESP8266
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#elif defined ARDUINO_ARCH_ESP32 // s'il s'agit d'un ESP32
#include "WiFi.h"
#include <WebServer.h>
#endif
#include <WiFiClient.h>
// pour le contrôle de la matrice RGB:
#include <FastLED.h> //https://github.com/FastLED/FastLED
#include <LEDMatrix.h> //https://github.com/Jorgen-VikingGod/LEDMatrix
// modifiez ces deux constantes pour qu'elles contiennent les caractéristiques de
// votre réseau Wifi
#define ssid "**********" // le nom (SSID) de votre réseau WiFi
#define password "**********" // votre mot de passe WiFi
#if defined ARDUINO_ARCH_ESP8266 // s'il s'agit d'un ESP8266
ESP8266WebServer server(80);
#elif defined ARDUINO_ARCH_ESP32 // s'il s'agit d'un ESP32
WebServer server(80);
#endif
// numéro de la ligne, numéro de la colonne et couleur
String ligneStr = "0";
String colonneStr = "0";
String couleurStr = "Noir";
// informations concernant la matrice de LEDs
#define DATA_PIN 5 // GPIO 5 contrôlera la matrice
#define COLOR_ORDER GRB
#define CHIPSET WS2812B
#define MATRIX_WIDTH 16
#define MATRIX_HEIGHT 16
#define MATRIX_TYPE HORIZONTAL_ZIGZAG_MATRIX
#define MATRIX_SIZE (MATRIX_WIDTH*MATRIX_HEIGHT)
#define NUMPIXELS MATRIX_SIZE
cLEDMatrix<MATRIX_WIDTH, MATRIX_HEIGHT, MATRIX_TYPE> leds;
/* La fonction construitPage retourne un string qui contient toute notre page web */
String construitPage() {
String page = "<html lang=fr-FR><head>";
page += "<title>Matrice de LEDs RGB</title>";
page += "<style> body { background-color: #fffff; font-family: Arial, Helvetica, Sans-Serif; Color: #000088; }</style>";
page += "</head><body><h1>Matrice de LEDs RGB</h1>";
page += "<form action='/' method='POST'>";
page += "<p> Num&eacute;ro de la ligne: <SELECT name='ligne'> <OPTION>" + ligneStr + " <OPTION>0 <OPTION>1 <OPTION>2 <OPTION>3 <OPTION>4 ";
page += "<OPTION>5 <OPTION>6 <OPTION>7 <OPTION>8 <OPTION>9 <OPTION>10 <OPTION>11 ";
page += "<OPTION>12 <OPTION>13 <OPTION>14 <OPTION>15</SELECT></p>";
page += "<p> Num&eacute;ro de la colonne: <SELECT name='colonne'> <OPTION>" + colonneStr + " <OPTION>0 <OPTION>1 <OPTION>2 <OPTION>3 <OPTION>4 ";
page += "<OPTION>5 <OPTION>6 <OPTION>7 <OPTION>8 <OPTION>9 <OPTION>10 <OPTION>11 ";
page += "<OPTION>12 <OPTION>13 <OPTION>14 <OPTION>15</SELECT></p>";
page += "<p> Couleur: <SELECT name='couleur'> <OPTION>" + couleurStr + "<OPTION> Noir <OPTION>Blanc <OPTION>Bleu <OPTION>Jaune ";
page += "<OPTION>Rose <OPTION>Rouge <OPTION>Vert </SELECT></p>";
page += "<INPUT type='submit' value='Appliquer'><br><br>";
page += "</body></html>";
return page;
}
/* Interaction avec la page web (réception des données du formulaire) */
void gestionPage() {
if (server.hasArg("ligne")) {
// lecture des paramètres choisis dans le formulaire
ligneStr = server.arg(0);
colonneStr = server.arg(1);
couleurStr = server.arg(2);
// pour le débogage, affichage dans le moniteur série:
Serial.print("Commande recue. Ligne: ");
Serial.print(ligneStr);
Serial.print(" Colonne: ");
Serial.print(colonneStr);
Serial.print(" Couleur: ");
Serial.println(couleurStr);
gestionLEDs();
}
server.send ( 200, "text/html", construitPage() );
}
/* Contrôle des LEDS par les broches GPIO2, GPIO4 et GPIO5 */
void gestionLEDs() {
CRGB laCouleur = CRGB::Black;
// Traduction de la couleur choisie, pour qu'elle soit compréhensible par FastLED
if (couleurStr.equals("Noir")) {
laCouleur = CRGB::Black;
}
if (couleurStr.equals("Blanc")) {
laCouleur = CRGB::White;
}
if (couleurStr.equals("Bleu")) {
laCouleur = CRGB::Blue;
}
if (couleurStr.equals("Jaune")) {
laCouleur = CRGB::Yellow;
}
if (couleurStr.equals("Rose")) {
laCouleur = CRGB::Pink;
}
if (couleurStr.equals("Rouge")) {
laCouleur = CRGB::Red;
}
if (couleurStr.equals("Vert")) {
laCouleur = CRGB::Green;
}
// réglage de la LED en question:
leds.DrawPixel(ligneStr.toInt(), colonneStr.toInt(), laCouleur);
FastLED.show();
}
void setup() {
// initialisation de la matrice de LEDs
FastLED.addLeds<CHIPSET, DATA_PIN, COLOR_ORDER>(leds[0], leds.Size()).setCorrection(TypicalSMD5050);
FastLED.setCorrection(TypicalLEDStrip);
FastLED.setBrightness(50);
FastLED.clear(true); // on éteint toutes les LEDs
// pour affichage dans le moniteur série
Serial.begin ( 115200 );
Serial.println("");
WiFi.mode(WIFI_STA);
// initialisation de la communication WiFi
WiFi.begin ( ssid, password );
while ( WiFi.status() != WL_CONNECTED ) {
delay ( 500 ); Serial.print ( "." );
}
Serial.println ( "" );
Serial.print ( "Maintenant connecte a " );
Serial.println ( ssid );
Serial.print ( "Adresse IP: " );
Serial.println ( WiFi.localIP() );
// On indique le nom de la fonction qui gère l'interraction avec la page web
server.on ( "/", gestionPage );
server.begin();
Serial.println ( "Serveur HTTP en fonction" );
}
void loop() {
server.handleClient();
}

-

À lire également:


Yves Pelletier (TwitterFacebook)

dimanche 21 février 2021

ESP32/ESP8266: Écriture et lecture d'un fichier en mémoire flash

Il est possible d'enregistrer des fichiers dans la mémoire flash de l'ESP8266 et de l'ESP32. Par exemple, on peut utiliser la mémoire flash pour héberger les fichiers html d'un serveur web, ou encore pour enregistrer les données d'un data logger. Les fichiers sont préservés suite à un redémarrage, une coupure d'alimentation, ou le téléversement d'un nouveau programme.


SPIFFS ou LittleFS?

Pendant quelques années, le système de fichiers recommandé pour l'ESP8266 était SPIFFS, mais il n'est plus activement supporté par l'équipe de développement du core Arduino pour ESP8266, et il risque de disparaître totalement dans une future version. Il est plutôt recommandé d'utiliser le système de fichiers LittleFS, dont la bibliothèque est intégrée dans le core Arduino ESP8266.

Du côté de l'ESP32, la future disparition du format SPIFFS ne semble pas aussi explicite pour l'instant. Au moment où j'écris ces lignes, seule la bibliothèque SPIFFS est distribuée avec le core Arduino ESP32 (version 1.0.4) et il faut installer une bibliothèque supplémentaire pour utiliser LittleFS,  mais on indique que cette bibliothèque sera bientôt intégré au core ESP32 pour Arduino.

Un sketch rédigé pour le format SPIFFS ne nécessite que très peu de modifications pour fonctionner avec LittleFS. Cependant, si vous avez déjà enregistré des fichiers en format SPIFFS, ils seront effacés si vous exécutez ensuite un sketch qui utilise le format LittleFS.

J'ai utilisé Little FS sur les deux plateformes, car j'aime bien concevoir des programmes qui fonctionnent à la fois sur ESP8266 et sur ESP32.

LittleFS sur ESP8266

Il n'y a aucune bibliothèque à installer, puisqu'elle est déjà intégrée au core. Deux fichiers d'exemple sont fournis (Menu Fichier - Exemples - LittleFS(esp8266)).

LittleFS sur ESP32

Pour l'ESP32, j'ai installé la bibliothèque LITTLEFS par lorol en passant par le gestionnaire de bibliothèques de l'IDE Arduino.  (Attention, lecteur du futur: ce ne sera peut-être plus nécessaire au moment où tu liras ces lignes...)

Là encore, deux fichiers d'exemple sont fournis (Menu Fichier - Exemples - LittleFS_esp32).


Mon projet

Mon but était de rédiger un sketch fonctionnant aussi bien avec l'ESP8266 qu'avec l'ESP32. Trois boutons sont connectés au module: un premier bouton lit le contenu d'un fichier intitulé "document.txt", un deuxième bouton ajoute des données dans le fichier (un nombre entier qui augmente à chaque écriture", et le troisième bouton supprime le fichier.

Les boutons sont branchés de la façon suivante:

  • Bouton "Lecture du fichier": GPIO 4
  • Bouton "Écriture dans le fichier": GPIO 5
  • Bouton "Suppression du fichier": GPIO 15

Schéma des connexion sur module Wemos D1 mini:



Schéma des connexions sur module ESP32:


Le sketch

Il existe quelques différences de syntaxe entre la version ESP8266 et la version ESP32, ce qui m'a obligé à utiliser des directives au préprocesseur (#defined ARDUINO_ARCH_ESP32 et #defined ARDUINO_ARCH_ESP8266).

Par exemple, dans la version ESP8266, il faut écrire "LittleFS" alors que c'est "LITTLEFS" dans la version ESP32.

Pour l'ESP32, j'ai utilisé l'expression "LITTLEFS.begin(1)" pour qu'un répertoire en format LittleFS soit créé s'il n'en existe pas déjà un.  Mais pour obtenir le même comportement avec l'ESP8266, il faut simplement écrire "LittleFS.begin()".

De plus, la routine "listDir" qui fait la liste des fichiers est assez différentes pour les deux microcontrôleurs.

-

/*
Écriture/lecture d'un fichier (LITTLEFS) sur ESP8266 ou ESP32
Un bouton permet de lire le contenu d'un fichier.
Un autre bouton permet d'ajouter du contenu dans le fichier.
Un troisième bouton supprime le fichier
Plus d'infos:
https://electroniqueamateur.blogspot.com/2021/02/esp32esp8266-ecriture-et-lecture-dun.html
*/
#include "FS.h"
#if defined ARDUINO_ARCH_ESP32 // spécifique à l'ESP32
#define LittleFS LITTLEFS
#include <LITTLEFS.h>
#elif defined ARDUINO_ARCH_ESP8266 // spécifique à l'ESP8266
#include <LittleFS.h>
#endif
// connexion des boutons:
#define boutonLecture 4 // GPIO4
#define boutonEcriture 5 // GPIO5
#define boutonSupprimer 15 // GPIO15
int compteur = 0;
// lecture d'un fichier
void readFile(const char * path) {
Serial.printf("Lecture du fichier: %s ", path);
File file = LittleFS.open(path, "r");
if (!file || file.isDirectory()) {
Serial.println("...echec de la lecture...ce fichier existe-t-il?");
return;
}
Serial.println("reussie. Contenu:");
while (file.available()) {
Serial.write(file.read());
}
Serial.println();
}
// ajout d'information dans un fichier
// si le fichier n'existe pas déjà, il est créé.
void appendFile(const char * path, const char * message) {
Serial.printf("Ajout de donnees dans le fichier: %s ", path);
File file = LittleFS.open(path, "a");
if (!file) {
Serial.println(" :echec de l'ouverture du fichier!");
return;
}
if (file.print(message)) {
Serial.println("reussie.");
} else {
Serial.println(" :echec de l'ajout au fichier!");
}
Serial.println();
}
// Liste des fichiers présents
void listDir() {
Serial.println("Liste des fichiers:");
#if defined ARDUINO_ARCH_ESP32
File root = LITTLEFS.open("/", "r");
if (!root) {
Serial.println("- echec de l'ouverture du repertoire");
return;
}
File file = root.openNextFile();
while (file) {
Serial.print(" Nom: ");
Serial.print(file.name());
Serial.print("\tTaille: ");
Serial.println(file.size());
file = root.openNextFile();
}
#elif defined ARDUINO_ARCH_ESP8266
Dir dir = LittleFS.openDir ("");
while (dir.next ()) {
Serial.print(" Nom: ");
Serial.print (dir.fileName ());
Serial.print("\tTaille: ");
Serial.println (dir.fileSize ());
}
#endif
Serial.println();
}
void deleteFile(const char * path) {
Serial.printf("Suppression du fichier: %s ", path);
if (LittleFS.remove(path)) {
Serial.println(" reussie");
} else {
Serial.println(" : echec de la suppression!");
}
Serial.println();
}
void setup() {
Serial.begin(115200);
Serial.println();
pinMode(boutonLecture, INPUT);
pinMode(boutonEcriture, INPUT);
#if defined ARDUINO_ARCH_ESP32 // spécifique à l'ESP32
if (!LITTLEFS.begin(1)) {
Serial.println("Echec du montage LITTLEFS");
return;
}
#elif defined ARDUINO_ARCH_ESP8266 // spécifique à l'ESP8266
if (!LittleFS.begin()) {
Serial.println("Echec du montage LITTLEFS");
return;
}
#endif
listDir();
}
void loop() {
char nombre[6]; // chaîne de caractères pour la conversion de la valeur du compteur
if (digitalRead(boutonLecture)) {
readFile("/document.txt");
Serial.println("");
delay(300); // anti rebond
}
if (digitalRead(boutonEcriture)) {
Serial.print("Compteur = ");
Serial.println(compteur);
sprintf(nombre, " %i", compteur); // transformation du nombre en chaîne de caractères
appendFile("/document.txt", nombre);
compteur++;
delay(300); // anti rebond
}
if (digitalRead(boutonSupprimer)) {
deleteFile("/document.txt");
listDir();
delay(300); // anti rebond
}
}
-

On peut constater l'effet de l'appui sur un bouton en regardant l'affichage du moniteur série:


À lire également


Yves Pelletier (TwitterFacebook


dimanche 14 février 2021

Programmation OTA de l'ESP32 / ESP8266

La programmation OTA ("Over the air") consiste à programmer à distance, via le réseau WiFi, un ESP32 ou un ESP8266.

De cette façon, vous pouvez mettre à jour le sketch exécuté par un ESP32 ou un ESP8266 en laissant ce dernier à l'endroit où il se trouve, sans qu'il soit nécessaire de le brancher à votre ordinateur par un câble USB.


Nous effectuerons cette opération au moyen de l'IDE Arduino (il existe d'autres méthodes impliquant, par exemple, un navigateur web). L'IDE Arduino doit avoir été préalablement configuré pour la programmation de l'ESP32 ou de l'ESP8266

La documentation spécifie également que Python doit être installé sur l'ordinateur, mais ça n'implique aucunement que vous devrez programmer quoi que ce soit en Python;  je suppose que l'IDE utilise un script en Python pendant le processus.

Pour que le module ESP puisse être programmé à distance, il faut qu'il contienne déjà un sketch qui contient les routines qui gèrent l'OTA. L'exemple "BasicOTA" (qui se trouve dans le répertoire "ArduinoOTA") a été spécialement conçu à cette fin: commençons par le téléverser dans notre module ESP qui, à cette étape, doit obligatoirement être branché à l'ordinateur par un câble USB (n'oubliez pas d'écrire le ssid et le mot de passe aux endroits appropriés, au début du programme).

Maintenant que le sketch "BasicOTA" a été téléversé, il n'est plus nécessaire que votre module ESP soit branché à l'ordinateur par USB: il s'agit qu'il soit alimenté et à portée du même réseau Wifi que l'ordinateur que vous utilisez pour le programmer.

Si le module ESP est connecté au réseau Wifi, vous devriez voir un nouveau port série s'afficher dans l'IDE Arduino (le nom est plutôt long et contient l'adresse IP du module ESP). Il s'agit de choisir ce port pour reprogrammer le module.



Mais attention: si vous désirez pouvoir, dans l'avenir, programmer à nouveau votre module par OTA, le sketch que vous téléversez doit obligatoirement contenir les routines qui gèrent l'OTA. En d'autres mots, tout le contenu du sketch "BasicOTA" doit se trouver à l'intérieur du nouveau sketch.

Exemple de sketch: Blink modifiable par OTA

Par exemple, le sketch ci-dessous se contente de faire clignoter la LED embarquée du module ESP, mais il a la particularité de pouvoir être modifié par OTA. Il s'agit essentiellement du sketch "BasicOTA", auquel j'ai ajouté les instructions qui permettent à la LED de clignoter (les lignes 24, 28,  79 à 82).

Il s'agit d'un point de départ intéressant pour tester que tout fonctionne correctement. Vous pouvez, par exemple, modifier la fréquence de clignotement de la LED et constater immédiatement si le sketch a été mis à jour ou non. (Remarquez que le moniteur série de l'IDE Arduino n'est pas fonctionnel pour les ports série OTA).

Comme toujours dans les sketches qui nécessitent une connexion à un réseau Wifi, vous devrez remplacer les astérisques par le nom du réseau et le mot de passe approprié.

-

-

Exemple de sketch: Webserver modifiable par OTA

Voici un deuxième exemple de sketch modifiable par OTA; cette fois, l'ESP diffuse une page web (ici encore, vous pourrez vérifier que la mise à jour s'effectue bel et bien en apportant des modifications au contenu de la page web). Au départ, la page affiche la valeur retournée par millis() (ce qui n'est pas spécialement utile, mais je voulais quelque chose de simple avec une valeur qui change avec le temps).

-

/*
* Ce sketch fait en sorte que l'ESP32 ou l'ESP8266
* publie une page web, tout en étant modifiable
* par OTA.
*
* Plus d'infos:
* https://electroniqueamateur.blogspot.com/2021/02/programmation-ota-de-lesp32-esp8266.html
*/
#if defined ARDUINO_ARCH_ESP8266 // s'il s'agit d'un ESP8266
#include <ESP8266WiFi.h>
#include <ESP8266mDNS.h>
#include <ESP8266WebServer.h>
#elif defined ARDUINO_ARCH_ESP32 // s'il s'agit d'un ESP32
#include <WiFi.h>
#include <ESPmDNS.h>
#include <WebServer.h>
#endif
#include <WiFiUdp.h>
#include <ArduinoOTA.h>
#include <WiFiClient.h>
const char* ssid = "**********";
const char* password = "**********";
#if defined ARDUINO_ARCH_ESP8266 // s'il s'agit d'un ESP8266
ESP8266WebServer server(80);
#elif defined ARDUINO_ARCH_ESP32 // s'il s'agit d'un ESP32
WebServer server(80);
#endif
void handle_root() {
// C'est ici qu'on construit la page web:
server.send(200, "html", "<head> <title>ESP8266 / ESP32</title> <meta http-equiv=Refresh content=2></head> "
"<body> <H1>ESP8266 / ESP32</H1>"
"<p>Bonjour &agrave; tous! </p> <p>" + String(millis()) + "</p></body>");
delay(100);
}
void setup() {
// pour l'OTA
Serial.begin(115200);
Serial.println("Booting");
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
while (WiFi.waitForConnectResult() != WL_CONNECTED) {
Serial.println("Connection Failed! Rebooting...");
delay(5000);
ESP.restart();
}
server.on("/", handle_root);
server.begin();
ArduinoOTA.onStart([]() {
String type;
if (ArduinoOTA.getCommand() == U_FLASH) {
type = "sketch";
} else { // U_FS
type = "filesystem";
}
// NOTE: if updating FS this would be the place to unmount FS using FS.end()
Serial.println("Start updating " + type);
});
ArduinoOTA.onEnd([]() {
Serial.println("\nEnd");
});
ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
});
ArduinoOTA.onError([](ota_error_t error) {
Serial.printf("Error[%u]: ", error);
if (error == OTA_AUTH_ERROR) {
Serial.println("Auth Failed");
} else if (error == OTA_BEGIN_ERROR) {
Serial.println("Begin Failed");
} else if (error == OTA_CONNECT_ERROR) {
Serial.println("Connect Failed");
} else if (error == OTA_RECEIVE_ERROR) {
Serial.println("Receive Failed");
} else if (error == OTA_END_ERROR) {
Serial.println("End Failed");
}
});
ArduinoOTA.begin();
Serial.println("Ready");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
}
void loop() {
server.handleClient();
// pour l'OTA
ArduinoOTA.handle();
}

-

Pour atteindre cette page web avec un navigateur, vous utilisez l'adresse IP indiquée dans le nom du port série.


À lire également

Mes autres articles impliquant l'ESP32 ou l'ESP8266.

Yves Pelletier (TwitterFacebook


samedi 13 février 2021

Screenduino: un outil en ligne pour dessiner sur un LCD 2X16

Même si les afficheurs LCD 16 X 2 ont d'abord et avant tout été conçus pour afficher du texte, il est possible d'y afficher de petits dessins en créant nos propres polices de caractères. Bien entendu, on est loin de la flexibilité des écrans graphiques puisque nous sommes limités à un maximum de 4 caractères de 5 pixels de large et de 8 pixels de haut.  La bibliothèque LiquidCrystal de l'IDE Arduino permet la création de ces caractères sur mesure grâce à la fonction createChar().



Tusindfryd a mis au point Screenduino, un outil en ligne qui nous permet de créer plus facilement ces petites illustrations.  Il s'agit de cliquer sur les pixels que vous désirez noircir pour qu'un sketch Arduino prêt à l'emploi soit généré automatiquement. 

Par exemple, en traçant à l'écran le schéma représenté ci-dessus, Screenduino a généré automatiquement le sketch ci-dessous.

-

/*
Schéma d'un cicruit électrique sur un aficheur LCD 16 X 2
Généré avec le Custom Glyph Generator Screenduino de tusindfryd;
https://tusindfryd.github.io/screenduino/
*/
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2); // RS, E, D4, D5, D6, D7
void setup() {
lcd.begin(16, 2);
image();
}
void loop() {}
void image() {
lcd.clear();
byte image08[8] = {B10000, B10000, B10000, B10000, B11111, B10000, B10000, B10000};
byte image25[8] = {B00001, B00001, B00001, B11111, B00001, B00001, B00001, B00001};
byte image24[8] = {B00000, B11111, B00001, B00001, B00001, B11111, B00000, B00000};
byte image07[8] = {B00000, B00000, B00001, B00001, B11111, B10001, B10000, B10000};
byte image23[8] = {B10000, B10011, B10010, B11110, B00010, B00011, B00000, B00000};
byte image26[8] = {B10001, B10001, B10001, B11111, B10000, B10000, B10000, B10000};
byte image10[8] = {B00000, B00000, B00000, B00000, B11111, B00001, B00001, B00001};
byte image09[8] = {B00001, B00010, B00100, B01000, B10000, B00000, B00000, B00000};
lcd.createChar(0, image08);
lcd.createChar(1, image25);
lcd.createChar(2, image24);
lcd.createChar(3, image07);
lcd.createChar(4, image23);
lcd.createChar(5, image26);
lcd.createChar(6, image10);
lcd.createChar(7, image09);
lcd.setCursor(7, 0);
lcd.write(byte(0));
lcd.setCursor(8, 1);
lcd.write(byte(1));
lcd.setCursor(7, 1);
lcd.write(byte(2));
lcd.setCursor(6, 0);
lcd.write(byte(3));
lcd.setCursor(6, 1);
lcd.write(byte(4));
lcd.setCursor(9, 1);
lcd.write(byte(5));
lcd.setCursor(9, 0);
lcd.write(byte(6));
lcd.setCursor(8, 0);
lcd.write(byte(7));
}

-

L'afficheur était branché à un Arduino Uno de la façon suivante:

À lire également


Yves Pelletier (TwitterFacebook

dimanche 7 février 2021

IDE Arduino: modifier les paramètres du formatage automatique

C'est bien connu, l'option "Formatage automatique" disponible dans le menu "Outils" de l'IDE Arduino est bien utile pour améliorer la lisibilité d'un sketch.


Ce qui est peut-être un peu moins connu, c'est qu'il est possible de modifier certaines caractéristiques du formatage comme, par exemple, le nombre d'espaces utilisés à chaque indentation.

Les paramètres du formatage automatique se trouvent dans un fichier intitulé "formatter.conf", qui se trouve dans le répertoire "lib". 


Il est déconseillé de modifier directement ce fichier car, si vous le faites, vos modifications disparaîtront inévitablement lors d'une future mise à jour de l'IDE Arduino. Il est plutôt recommandé de placer une copie de ce fichier dans le même répertoire que le fichier "preferences.txt", et d'effectuer des modifications sur cette copie.

(Si vous ne connaissez pas l'emplacement du fichier "preferences.txt", vous pouvez le voir dans le bas de la fenêtre "Paramètres" dans l'IDE Arduino.)


Le fichier "formatter.conf" peut être ouvert avec n'importe quel éditeur de texte.


Modifier l'indentation

Par défaut, l'indentation est réglée à 2 espaces. Si vous préférez, par exemple, une indentation de 4 espaces, il s'agit de remplacer l'instruction "indent=spaces=2" par "indent=spaces=4". (L'IDE Arduino doit être redémarré pour que les modification prennent effet).

Disposition des accolades: attachées, ou détachées?

Si vous désirez que l'accolade d'ouverture soit toujours placée à la fin de la même ligne que la fonction à laquelle elle est rattachée, écrivez "style=attach" dans le fichier "formatter.conf":

Si vous préférez que l'accolade d'ouverture soit placée sur sa propre ligne, vous écrivez plutôt "style=break" dans le fichier "formatter.conf":

Sinon, le comportement par défaut consiste à ne pas modifier le style déjà utilisé. Par exemple, le sketch ci-dessous comporte un mélange des deux types de disposition,  et il sera laissé intact par le formatage automatique si vous n'avez pas apporté de modification au fichier "formatter.conf":

Séparer les blocs?

Avec l'instruction "break-blocks", les blocs if, for, while, etc. sont automatiquement précédés et suivis d'une ligne blanche:




Vous trouverez d'autres options de formatage sur la page d'Artistic Style.

À lire également

Retirer les cartes inutiles dans les menus de l'IDE Arduino

Yves Pelletier (TwitterFacebook