dimanche 20 octobre 2019

Texte et Arduino (1): la classe String



Deux façon possibles de procéder

Lorsque vous désirez traiter des informations sous forme de texte avec votre Arduino (demander le nom de l'utilisateur, afficher une information textuelle sur un écran ou le moniteur série, etc.), deux options s'offrent à vous: les tableaux de caractère classiques du langage C, et les objets de type String.

Les tableaux de caractères du langage C

Les tableaux de caractères terminés par "NULL" font partie intégrante du langage C depuis sa création, au début des années 1970. Ils sont souvent un peu nébuleux pour les néophytes qui abordent la programmation de l'Arduino sans avoir de connaissance préalable en langage C. Les fonctions conçues pour gérer les tableaux de caractères portent souvent des noms peu intuitifs.  Pour les connaître,  il faut consulter des sources documentaires sur le langage C car le site officiel Arduino insiste plutôt sur la classe String. Le programmeur doit également prendre soin de ne pas écrire au-delà des limites du tableau (comme, par exemple, tenter d'écrire un treizième caractère dans un tableau conçu pour en contenir douze).

Ces tableaux de caractères pourront toutefois être utilisés dans n'importe quel programme en langage C (pas seulement Arduino).

Les objets de type String

Les concepteurs du langage Arduino ont créé la classe String pour faciliter la tâche des programmeurs débutants. La syntaxe est souvent plus intuitive, les fonctions portent un nom qui permet de deviner plus facilement à quoi elles servent,  elles sont énumérées sur le site de référence officiel du langage Arduino et un tas d'exemples sont fournis avec l'IDE Arduino.



Malheureusement, cette facilité d'utilisation est accompagnée d'un inconvénient: pendant que votre programme s'exécute, les fonctions de la classe String ont tendance à causer un fractionnement de la mémoire disponible. Conséquence: avec le temps, votre programme risque de devenir instable et de planter. C'est pour cette raison que, dans les forums de discussion, vous verrez souvent des intervenants qui menacent de vous excommunier à la moindre allusion à la classe String.

Alors on fait quoi?

Si c'est très important que votre programme fonctionne sans faille pendant une longue période de temps (exemple: il gère l'alimentation en oxygène de votre scaphandre), évitez à tout prix l'utilisation de la classe String!

Par contre, si vous fabriquez par pur plaisir un gadget dont la fiabilité n'est pas essentielle (une machine qui affiche des obscénités lorsqu'on appuie sur un bouton, par exemple) et que vous détestez vous compliquer la vie, pourquoi vous priver de la classe String?

Bref, les programmeurs sérieux utilisent les tableaux de caractère à terminaison nulle, et les autres font ce qu'ils veulent.

Dans le présent article, je vais explorer l'utilisation de la classe String. Dans un prochain article, à paraître très bientôt, j'aborderai l'utilisation des tableaux de caractères à terminaison nulle.

Sketch de démonstration

Le sketch ci-dessous utilise la plupart des fonctions décrites dans le reste de cet article. Il vous demande d'écrire un message dans le moniteur série, et il fait ensuite l'analyse de ce message.

-
-

Voici un exemple de ce qu'affiche le moniteur série après que j'aie écrit le message "Arduino, le meilleur ami des makers":



N.B.: Dans la suite de cet article, les hyperliens mènent vers la documentation complète de chaque fonction.

Création d'une variable de type String (consructeur)

On crée une variable de type String en précédant le nom de la variable par le mot "String", comme aux lignes 8, 9 et 10 du sketch de démonstration (n'oubliez pas le "S" majuscule au début du mot).

Ce qui est chouette avec un objet de type String, c'est qu'il n'est pas nécessaire de définir sa taille au moment de sa création: pourvu que la mémoire nécessaire soit disponible, votre variable pourra tout aussi bien contenir un texte constitué d'un seul caractère qu'un long paragraphe de plusieurs lignes­.

Réception d'un String par le moniteur série

À la ligne 20 du sketch de démonstration, Serial.readString() permet de placer dans une variable de type String le texte reçu par liaison série. L'utilisation de cette fonction est toujours suivie d'un délai d'attente perceptible, car elle prend fin lorsqu'aucun nouveau caractère n'a été reçu depuis un certain temps.

Remarquez que si vous avez réglé le moniteur série pour qu'il ajoute automatiquement une fin de ligne ou un retour de chariot à la fin de chaque message, ces caractères supplémentaires feront partie du String, à moins que vous n'utilisiez la fonction trim(), qui enlève tous les espaces inutiles situés au début et à la fin d'un String (ligne 22 du sketch).

Affectation d'un String

Pour placer du texte dans une variable de type String, vous utilisez l'opérateur "=", comme pour tout autre type de variable (voir la ligne 25, par exemple).

Concaténation de deux Strings

La concaténation consiste à mettre deux Strings bout à bout. Vous pouvez utiliser la fonction concat() (ligne 26) ou l'opérateur "+" (ligne 30).

Comparaison de deux Strings

Pour vérifier si deux Strings sont identiques, vous pouvez utiliser l'opérateur "=="  (ligne 48) ou la fonction equals() (ligne 56).

Il existe également des fonctions plus spécialisées: equalsIgnoreCase() (ligne 63) compare les deux Strings sans tenir compte de la case ("Arduino" et "ARDUINO" seront donc considérés comme équivalents).

compareTo() (ligne 86) est encore un petit peu plus sophistiquée, et peut être utilisée pour trier des Strings en fonction du numéro ASCII des caractères qu'ils contiennent. On peut également trier deux Strings de façon similaire au moyen des opérateurs ">" ou "<".

Connaître le nombre de caractères d'un String

La fonction length() (ligne 30) permet de déterminer le nombre de caractères à l'intérieur du String.

Analyse caractère par caractère

On peut accéder à un caractère en particulier au moyen de la fonction charAt() (ligne 34) ou de l'opérateur [] (ligne 36). Le premier caractère porte le numéro 0.

Pour modifier un caractère en particulier, on peut utiliser setCharAt() (ligne 98).

On peut également éliminer un caractère ou plusieurs caractères grâce la fonction remove().

On peut utiliser replace() (ligne 94) pour remplacer toutes les occurrences d'un caractère par un autre caractère.

Isoler une partie d'un String

substring() (ligne 76) retourne un String constitué d'une partie d'un autre String.

Recherche à l'intérieur d'un String

indexOf() (ligne 40) et lastIndexOf() (ligne 42) permettent de trouver la position d'un caractère ou d'un String à l'intérieur d'un autre String. La valeur retournée est -1 si la recherche s'est révélée infructueuse.  Par défaut, la recherche débute au tout début ou à la toute fin du String. On peut ajouter un deuxième paramètre facultatif pour commencer la recherche à un autre caractère.

startsWith()  et endsWith() (ligne 70) permettent de vérifier si un String commence ou se termine par les caractères d'un autre String.

On peut utiliser replace() (ligne 94) pour remplacer toutes les occurrences d'un String par un autre String.

Tout réécrire en minuscules ou en majuscules

Deux fonctions permettent de réécrire le contenu du String afin qu'il ne contienne que des majuscules, ou que des minuscules: toLowerCase() et  toUpperCase() (lignes 78 et 82). Dans les deux cas, le contenu du String est immédiatement remplacé par le nouveau texte.

Conversion d'un nombre en String

Lorsque vous désirez afficher une valeur numérique mesurée par un capteur, il peut être utile de convertir un nombre en String. La conversion de type s'effectue avec la même syntaxe que pour les autres types de variable en langage C:  String(nombre). Si le nombre à convertir est de type "float" ou "double", un deuxième paramètre (facultatif) permet de déterminer le nombre de décimales à conserver (lignes 103 et 106 du sketch de démonstration).

Conversion d'un String en nombre

Un String qui débute par un nombre peut être converti en variable de type double, float ou int grâce aux fonctions toDouble()toFloat() et toInt() (ligne 111). Le String doit débuter par un nombre, mais ce nombre peut être suivi de caractères non-numériques, qui seront simplement ignorés lors de la conversion. La valeur retournée est zéro lorsque la conversion échoue.

Prochain article: les chaînes de caractères classiques du langage C (terminées par NULL).

Yves Pelletier   (TwitterFacebook)

mardi 1 octobre 2019

Bluetooth (série) avec l'ESP32


Une des nombreuses caractéristiques épatantes de l'ESP32, c'est qu'il peut communiquer en Bluetooth. Dans cet article, voyons un peu comment il est possible d'utiliser la bibliothèque BluetoothSerial pour établir une communication entre l'ESP32 et un smart phone.

Si vous savez comment utiliser la classe Serial pour établir une communication série de type UART, il n'est pas exagéré d'affirmer que vous savez déjà comment utiliser la bibliothèque BluetoothSerial: les méthodes begin, read, write, print, println et available sont disponibles et accomplissent la même fonction que dans leur équivalent série.

Réglages du smart phone ou de la tablette

Il existe de nombreuses applications Android permettant la communication bluetooth. Pour cette expérience, j'ai utilisé Serial Bluetooth Terminal par Kai Morich. Une autre option consiste à utiliser l'application réalisée dans cet article au moyen de MIT App Inventor.

Si vous n'avez pas l'habitude d'effectuer l'appairage d'un périphérique bluetooth, vous pouvez vous référer à la partie intitulée "Couplage avec un appareil hôte" de cet article.

Envoi d'informations de l'ESP32 vers le smart phone

Le sketch ci-dessous envoie un nombre croissant par bluetooth. C'est une façon simple et rapide de vérifier que la communication fonctionne correctement.


-
-

Contrôle de l'ESP32 par le smart phone

Dans ce deuxième exemple, deux LEDs reliées à l'ESP32 sont contrôlées à partir du smart phone.
  • La commande 'a' allume la première LED
  • La commande 'b' allume la deuxième LED
  • La commande 'c' allume les deux LEDs
  • La commande 'd' éteint les deux LEDs
  • La commande 'e' modifie l'état des deux LEDs


Une des LEDs est branchée à la broche GPIO 4, alors que l'autre est branchée à GPIO 5.


-
-

Articles similaires

Grâce au module HC-06, nous avons eu l'occasion d'utiliser Bluetooth avec Arduino, Raspberry Pi, STM32 Nucleo, MPLAB Xpress (PIC) et MSP430 Launchpad. Nous avons aussi utilisé MIT App Inventor 2 pour programmer une appli Android qui communique en Bluetooth.

En ce qui concerne l'ESP32, de nombreux autres articles sont disponibles ici.

Yves Pelletier   (TwitterFacebook)

vendredi 27 septembre 2019

Accéléromètre/gyro MPU-6050 et Arduino


Amusons-nous un peu avec un accéléromètre MPU-6050 et un Arduino Uno.

Le MPU-6050 est une centrale inertielle qui combine un accéléromètre et un gyromètre, ce qui permet de mesurer son accélération ou son inclinaison.

Connexions à l'Arduino

Le module MPU-6050 communique en I2C, et les connexions seront donc:
  • VCC du MPU-6050: 5 V de l'Arduino*
  • GND du MPU-6050: GND de l'Arduino
  • SCL du MPU-6050: A5 de l'Arduino
  • SDA du MPU-6050: A4 de l'Arduino
*: mon module comporte un régulateur de tension, sinon je l'aurais plutôt branché à 3,3 V.

Je n'ai pas utilisé les autres broches du module MPU-6050 (XDA, XCL, AD0 et INT).


Installation de la bibliothèque

J'ai eu peu de succès avec la bibliothèque de Jeff Rowberg, malgré son excellente réputation: j'obtenais de fréquents "FIFO overflows", et le sketch s'arrêtait de façon intempestive au bout de quelques secondes.

J'ai donc choisi d'utiliser la bibliothèque MPU6050_tockn, également disponible par l'entremise du gestionnaire de bibliothèques de l'IDE Arduino.

Les deux exemples fournis avec la bibliothèque, "GetAllData" et "GetAngle" permettent de vérifier rapidement le fonctionnement correct de l'accéléromètre et d'explorer les données disponibles.


Au démarrage du programme, il faut laisser le MPU-6050 immobile pendant la procédure de calibration.  Différents paramètres sont ensuite affichés dans le moniteur série à chaque seconde.


Une alarme qui retentit quand on bouge le dispositif

Lorsque le MPU-6050 est parfaitement immobile, l'accélération mesurée est de 1 g selon l'axe vertical (c'est causé par la force de gravité). Le sketch ci-dessous active un buzzer piézoélectrique aussitôt que l'accélération mesurée selon n'importe lequel des 3 axes devient supérieure à 1 g.

(N.B.: il s'agit d'un buzzer actif, muni d'un oscillateur interne, qui émet un son aussitôt qu'il est alimenté; il est évidemment possible de modifier le sketch afin d'utiliser un buzzer passif).




Quelques secondes après le démarrage du programme, le buzzer émet un bip pour indiquer que la calibration de l'accéléromètre est terminée.



Une alarme qui retentit quand le dispositif est en chute libre

Si leMPU-6050 est en chute libre, l'accélération mesurée devient nulle. Une minuscule modification au sketch précédent permet d'obtenir un dispositif qui émet un son pendant qu'il tombe.




Une ligne qui demeure obstinément horizontale

Finalement, je me suis amusé à afficher sur un écran OLED SH1106 une ligne qui demeure obstinément horizontale même lorsqu'on incline l'écran.



L'écran et le MPU-6050 partagent la liaison I2C. Par contre, l'écran OLED est alimenté avec 3,3 V.




Articles similaires

Il y a quelques années, j'avais fait quelques expériences avec un accéléromètre MMA7455: secouons cet accéléromètre!,  une boîte qui crie quand elle tombe et mesure d'un angle d'inclinaison.

Yves Pelletier   (TwitterFacebook)


mercredi 18 septembre 2019

Autopsie d'un message UART


On peut probablement passer des années à utiliser l'UART de l'Arduino de façon routinière sans savoir exactement ce qui se passe sous le capot. Dans ce billet, je m'amuse à observer le contenu d'un message UART.

Tout comme SPI et I2C, l'UART est un mode de communication série, ce qui signifie que les données sont acheminées l'une à la suite de l'autre sur une même broche du microcontrôleur.

La transmission UART implique 2 broches en plus de la masse (GND): TX pour la transmission, et RX pour la réception.  Sur un Arduino Uno, la broche numéro 0 reçoit les données (RX) alors que la broche numéro 1 est émettrice (TX). Le TX d'un des appareils impliqués dans la communication est toujours relié au RX de l'autre appareil.

Avec Arduino, vous utilisez l'UART chaque fois que vous faites appel à la classe Serial: Serial.print, Serial.println, Serial.read, etc. Typiquement, on l'utilise pour la communication entre un microcontrôleur et un ordinateur, ou entre plusieurs microcontrôleurs. Le protocole MIDI, beaucoup utilisé en musique, est une liaison UART à 31250 bauds.

Le sigle UART signifie "Universal Asynchronous Receiver Transmitter": le protocole permet donc d'émettre et de recevoir des données de façon asynchrone.  "Asynchrone" signifie qu'il n'existe pas de signal d'horloge commun partagé par l'émetteur et le récepteur, d'où la nécessité de régler l'émetteur et le récepteur à une même vitesse de transmission. Par exemple, lorsque votre sketch Arduino commence par Serial.begin(9600), vous réglez la vitesse de l'UART à 9600 bauds du côté Arduino, ce qui vous oblige à régler le moniteur série, du côté ordinateur, à 9600 bauds également.

Pour observer des messages UART, j'ai branché un analyseur logique à la broche TX d'un Arduino Uno, et j'ai visualisé les résultats sur le logiciel Sigrok PulseView.


Le sketch ne surprendra personne: je règle la vitesse de la communication à 9600 bauds, et j'envoie le message A, suivi d'un court délai pour m'aider à mieux distinguer l'émission de deux messages distincts.


Voici ce que me présente l'analyseur logique lors de l'émission de ce message:



Pendant qu'aucun message n'est transmis, la broche TX est au niveau logique haut. Un message UART commence toujours par un bit de départ (start) de niveau logique bas afin d'annoncer le début d'un message.

Le bit de départ est suivi d'une succession de 8 bits qui constituent le message proprement dit. Dans ce cas, ces 8 bits sont 1, 0, 0, 0, 0, 0, 1, et 0. Puisque le message débute par le bit de poids faible et se termine par le bit de poids fort, le résultat correspond au nombre binaire 01000001, ou 65 en décimal, soit le code ASCII de la lettre "A".

Le message se termine par un bit de fin (stop) de niveau logique haut. La broche demeure ensuite au niveau logique haut jusqu'à l'émission du prochain message.

Vous pouvez constater qu'il n'y a aucune frontière visible entre l'émission de deux bits consécutifs identiques; c'est la raison pour laquelle il est important que l'émetteur et le récepteur soient réglés à la même vitesse. Avec une transmission à 9600 bauds, chaque bit dure environ 100 µs (1/9600).


Si je double la vitesse de transmission pour qu'elle soit de 19200 bauds, la durée de chaque bit sera plutôt de 1/19200, donc environ 50 µs:


Si j'envoie un message constitué de plusieurs caractères, chacun des caractères est accompagné par son bit de départ et son bit de fin. Ici, j'ai envoyé le message "OK":


Cette fois, le message est constitué d'un bit de départ, de 8 bits correspondant au nombre binaire 01001111 (ou 79 en décimal, le code ASCII pour le caractère O), d'un bit de fin, d'un deuxième bit de départ, de 8 bits correspondant au nombre binaire 01001011 (ou 75 en décimal, correspondant au code ASCII pour le caractère "K"), et d'un dernier bit de fin.

Modifier les paramètres par défaut

Par défaut, la communication UART de l'Arduino est réglée à 8 bits de données, pas de parité et un bit "stop", mais il est possible de modifier ces paramètres en ajoutant un deuxième paramètre à la fonction Serial.begin().

Quelques exemples:

  • Serial.begin(9600, SERIAL_5N1) règle la vitesse de transmission à 9600 bauds, avec 5 bits de données, pas de parité, et un bit stop.
  • Serial.begin(4800, SERIAL_7N2) règle la vitesse de transmission à 4800 bauds, avec 7 bits de données, pas de parité, et 2 bits stop.
  • Serial.begin(19200, SERIAL_8E1) règle la vitesse de transmission à 19200 bauds, avec 8 bits de données, parité paire ("even")  et un bit stop.
  • Serial.begin(115200, SERIAL_8O2) règle la vitesse de transmission à 115200 bauds, avec 8 bits de données, parité impaire ("odd"), et 2 bits stop.
(Voir cette page pour tous les cas possibles.)

Parité

Le bit de parité est un bit optionnel qui peut être ajouté entre les bits de données et le bit stop afin de vérifier sommairement que l'intégrité du message a été correctement transmise. La parité peut être paire ou impaire.

Le sketch ci-dessous envoie le symbole "a" avec un bit de parité paire:


Voici le résultat:

Le bit start est suivi du nombre binaire 01100001 (ou 97 qui est le code ASCII pour "a"), du bit de parité (1), puis du bit stop.

Lorsque la parité est paire, le bit de parité prend la valeur nécessaire pour que le nombre total de bits qui sont au niveau logique haut soit paire. Dans cet exemple, si vous comptez le nombre de "1" dans le message "01100001", vous obtenez 3, qui est un chiffre impair. Puisque nous avons réglé la parité pour qu'elle soit paire, le bit de parité a pris la valeur "1" afin que le total 3 + 1 donne un résultat pair.

Voici un deuxième exemple, toujours avec une parité paire, sauf que le message est maintenant la lettre "c":


Cette fois, le bit de parité est au niveau logique bas, car le message correspondant à la lettre "c" est 01100011, qui comporte 4 bits au niveau logique haut. Ce nombre étant déjà paire, on lui additionne un bit de parité ayant la valeur "0" afin que le total demeure paire.

Comme vous pouvez le deviner, ce sera le contraire si j'envoie les mêmes messages avec un bit de parité impaire:


Si le message est "a", le bit de parité est au niveau logique bas, afin que le total des bits de niveau haut soit impair: 1 + 1 + 1 + 0 = 3:

Si le message est "c", le bit de parité est au niveau logique haut, afin que le total des bits de niveau haut soit impair:  1 + 1 + 1 + 1 + 1 = 5:


Yves Pelletier   (TwitterFacebook)

samedi 14 septembre 2019

Jouer une mélodie avec l'ESP32


La façon la plus simple de jouer une mélodie avec un Arduino, ou même avec un ESP8266, est d'utiliser la fonction "tone", qui permet de produire sur une broche un signal carré de la fréquence de notre choix.

La fonction "tone", toutefois, ne fonctionne pas avec l'ESP32.

Le billet d'aujourd'hui consistera donc à jouer une mélodie simple au moyen de l'ESP32, malgré l'absence de la fonction "tone". Pour ce faire, nous produirons un signal PWM dont nous ferons varier la fréquence. Si vous ne vous y connaissez pas trop en production d'un signal PWM avec l'ESP32, la lecture de ce précédent article pourrait vous être utile.



Circuit

Presque toutes les broches de l'ESP32 peuvent servir à produire un signal PẀM, nous avons donc l'embarras du choix. J'ai choisi, tout à fait arbitrairement, la broche GPIO 4.

Pour transformer en onde sonore les impulsions électriques générées par cette broche, vous pouvez utiliser un buzzer piézoélectrique ou un haut-parleur.

Nous ne le répéterons jamais assez: contrairement au buzzer piézoélectrique (qui a une grande résistance), ce n'est pas une bonne idée de brancher un haut-parleur directement à la sortie d'un microcontrôleur, à cause de sa très faible résistance. On utilise plutôt un transistor comme intermédiaire.

Sketch

Dans le sketch ci-dessous, une mélodie est définie au moyen d'un tableau "melodie" qui contient la hauteur de chaque note (do, ré, mi...), le numéro de l'octave et la durée.

Au début du programme, la broche GPIO 4 est associée au canal PWM numéro 0 (ledcAttachPin).

Pendant l'exécution de la mélodie, la fréquence du canal PWM 0 est réglée à la valeur adéquate (ledcSetup) et on démarre un signal PWM dont le rapport cyclique est de 50% (ledcWrite).

Pour mieux séparer les notes les unes des autres, un très bref moment de silence est inséré à la fin de chaque note (le rapport cyclique est réglé à 0).



Résultat:

Pour finir, une courte vidéo de l'ESP32 en action...


Articles similaires

D'autres articles publiés dans ce blog expliquent comment jouer une mélodie avec un Arduino,  un STM32 Nucleo,  un  ATTiny85, ou un microcontrôleur PIC.

Vous pouvez également consulter la liste des billets impliquant l'ESP32.


Yves Pelletier   (TwitterFacebook)

jeudi 12 septembre 2019

Dans un blog près de chez vous...(6)



Ça faisait longtemps...

mercredi 11 septembre 2019

Écran OLED SH1106 I2C et ESP32 ou ESP8266


Aujourd'hui, explorons comment écrire et dessiner sur un petit écran OLED monochrome branché à une carte ESP32 ou ESP8266.

L'écran en question a une taille de 1,3 pouce (environ 3,5 cm X 1,8 cm) et une résolution de 128 X 64 pixels. Il est basé sur le contrôleur SH1106 et utilise le protocole I2C. L'image produite est blanche sur fond noir.

Cet billet pourrait possiblement vous être utile même si vous utilisez un écran différent de celui que j'ai utilisé, puisque la bibliothèque u8g2 est compatible avec un très grand nombre de modèles d'écrans monochromes.

Connexions de l'afficheur à l'ESP32

  • Broche GND de l'afficheur - Broche GND de l'ESP32
  • Broche VCC de l'afficheur - Broche 3V3 de l'ESP32
  • Broche SCL de l'afficheur - Broche GPIO 22 de l'ESP32
  • Broche SDA de l'afficheur - Broche GPIO 21 de l'ESP32

Connexions de l'afficheur à l'ESP8266

  • Broche GND de l'afficheur - Broche GND de l'ESP8266
  • Broche VCC de l'afficheur - Broche 3V3 de l'ESP8266
  • Broche SCL de l'afficheur - Broche GPIO 5 de l'ESP8266
  • Broche SDA de l'afficheur - Broche GPIO 4 de l'ESP8266

Installation de la bibliothèque u8g2

Nous utiliserons la bibliothèque u8g2, qui peut facilement être installée depuis le gestionnaire de bibliothèques de l'IDE Arduino.

Essai des exemples fournis avec la bibliothèque


Évidemment, plusieurs exemples sont fournis avec la bibliothèque. Cependant, puisque la bibliothèque supporte plusieurs modèles d'écrans différents, chaque fichier d'exemple débute par une longue liste de constructeurs: il faut décommenter la ligne qui correspond au modèle d'écran que vous utilisez (dans mon cas: SH1106 128X64  I2C).


Écriture de texte à l'écran

Plusieurs dizaines de polices de caractères peuvent être utilisées pour écrire du texte à l'écran (voir la liste complète). Si vous désirez utiliser des caractères accentués, il est important de choisir une police dont le nom se termine par "f", ce qui indique que la police inclut tous les caractères nécessaires. De plus, la fonction "enableUTF8Print()" doit être appelée au démarrage du programme.


  • enableUTF8Print: pour permettre l'utilisation de caractères accentués
  • setFont: pour choisir une police de caractère
  • setCursor: pour choisir l'endroit sur l'écran où on désire écrire du texte
  • print: écriture du texte à la position du curseur

Dans un premier temps, le texte est écrit en mémoire (buffer). Il faut ensuite utiliser sendBuffer() pour transférer l'image à l'écran.



Dessiner des formes géométriques


Plusieurs fonctions facilitent le traçage de formes géométriques à l'écran:
  • drawPixel: pour dessiner un point
  • drawLine: pour dessiner une ligne droite
  • drawFrame: pour dessiner un contour de rectangle (vide)
  • drawBox: pour dessiner un rectangle plein
  • drawCircle: pour dessiner un contour circulaire (vide)
  • drawDisc: pour dessiner un cercle plein
  • drawTriangle: pour dessiner un triangle


Afficher un bitmap XBM



La fonction drawXBMP permet de tracer à l'écran une image bitmap de type XBM. J'ai obtenu de bons résultat en sauvegardant un petit dessin en format .xbm avec le logiciel Gimp, puis en ouvrant le fichier obtenu avec un éditeur de texte: j'en ai tiré le contenu de la variable "logoBitmap" dans le sketch de démonstration ci-dessous.


Un sketch

Pour finir, voici mon sketch complet,  qui fait apparaître des dessins et du texte à l'écran.




Articles similaires:

J'ai déjà utilisé le même écran OLED avec un Raspberry Pi et avec un Arduino.

Avec l'ESP32 et l'ESP8266, j'ai aussi utilisé ces afficheurs:  écran couleur SPI ST7735afficheur LCD 16 X 2afficheur 7 segments TM1638.

Vous pouvez également consulter la liste de tous mes articles concernant l'ESP8266 et l'ESP32.

Yves Pelletier   (TwitterFacebook)

samedi 7 septembre 2019

ESP32: utilisation du capteur à effet Hall intégré

Les concepteurs de l'ESP32 ont jugé utile de le munir d'un capteur à effet Hall intégré grâce auquel il est possible de détecter le champ magnétique d'un aimant placé à proximité du module.

Ce capteur se situe à l'intérieur de la partie de la carte qui est recouverte par un bouclier métallique, à peu près au centre du rectangle; il mesure la composante du champ magnétique orientée perpendiculairement à la carte.

L'exemple "HallSensor", accessible dans l'IDE Arduino par les menus "Fichier - Exemples - ESP32 - HallSensor" constitue une façon simple et rapide de vérifier le bon fonctionnement du capteur à effet Hall (au besoin, vous pouvez vous référer à ce précédent billet pour apprendre comment programmer l'ESP32 au moyen de l'IDE Arduino).


Prenez soin de ne pas brancher quoi que ce soit aux broches GPIO36 et GPIO39, car leur ADC est utilisé lors de l'utilisation du capteur à effet Hall.

En ce qui concerne la programmation dans l'IDE Arduino, la lecture du champ magnétique au moyen du capteur à effet Hall intégré se limite à l'utilisation de la fonction "hallRead()", qui retourne un entier.

Voici ce que j'ai obtenu en avec l'exemple "HallSensor", lorsqu'aucun aimant n'était placé à proximité du module ESP32: les valeurs affichées varient entre 32 et 40.


J'ai ensuite placé un petit aimant tout proche du centre du bouclier métallique du module ESP32 (j'avais collé l'aimant à l'extrémité d'un petit support en carton afin de faciliter les manipulations).


Les valeurs mesurées dépendent du pôle de l'aimant qui fait face au module ESP32. Pour un sens, les valeurs diminuent (elles peuvent même devenir négatives).



...alors qu'en plaçant l'aimant dans l'autre sens, les valeurs augmentent aux environs de 100.


D'après mes observations, il est difficile de mesurer quoi que ce soit si l'aimant est situé à plus de quelques millimètres du centre du bouclier métallique. Pour une mesure plus précise du champ magnétique, des capteurs externes me semblent plus appropriés (voir par exemple le HMC5883L ou le A1302).

Pour détecter la présence d'un aimant tout près de l'ESP32, par contre, il n'y a pas de doute: le module à effet Hall intégré fonctionne très bien.

Détecter l'ouverture d'une porte 

On pourrait penser à une application où l'ESP32 est fixé à un cadre de porte. Lorsque la porte est fermée, un aimant est appuyé contre l'ESP32, et cet aimant s'éloigne de l'ESP32 lorsqu'on ouvre la porte. Grâce aux mesures effectuées par le capteur à effet Hall intégré, l'ESP32 sait quand la porte est ouverte ou non. Et puisqu'il s'agit d'un ESP32, pourquoi ne pas afficher les résultats dans une page web?

C'est ce que fait le sketch ci-dessous: il s'agit d'un serveur web qui affiche la date et l'heure des 10 plus récentes ouvertures de la porte.



Au démarrage, du programme, le moniteur série nous indique l'adresse IP du serveur web.


En tapant cette adresse IP dans un navigateur, on accède à la page web qui indique la date et l'heure des plus récentes ouvertures de la porte.


Si vous désirez utiliser vous-mêmes le sketch, vous devez évidemment assigner aux constantes ssid et password les valeurs correspondant à votre réseau WiFi, mais également vérifier que la valeur de la constante Hallnormal correspond à ce qu'affiche votre capteur en absence de l'aimant, et régler la constante decalage afin que l'heure affichée corresponde bien au pays dans lequel vous vous trouvez,


Yves Pelletier   (TwitterFacebook)