lundi 26 avril 2021

Utilisation d'un écran tactile TFT SPI 240 X 320 (ILI9341) avec la STM32 Blue Pill

Dans ce tuto, nous branchons à une carte STM32F103C "Blue Pill" un écran tactile TFT SPI de 240 X 320 pixels (2,4") munie d'un contrôleur ILI9341. La Blue Pill sera programmée avec l'IDE Arduino en utilisant le core officiel STM32.


Il existe un grand nombre de petits afficheurs couleurs qui se ressemblent beaucoup mais qui ne sont pas identiques: certains utilisent une interface parallèle plutôt que SPI, d'autre comportent une autre puce que la ILI9341, la résolution peut être différente et plusieurs écrans ne sont pas tactiles...

Si vous utilisez un afficheur différent de celui que j'ai utilisé, vous trouverez peut-être, malgré tout, des informations utiles dans cet article, puisque la bibliothèque TFT_eSPI supporte un grand nombre de modèle différents.  Mais vous devrez certainement effectuer certaines modifications...


Connexions de l'écran à la Blue Pill

Mon écran comporte un total de 18 connecteurs; toutefois, je n'ai pas utilisé les 4 connecteurs qui servent au lecteur de carte SD (visible du côté gauche sur la photo ci-dessous).


J'ai connecté l'écran à la Blue Pill de la façon suivante:

  • Broche VCC de l'écran - Sortie 3,3 V de la Blue Pill
  • Broche GND de l'écran - Broche G de la Blue Pill
  • Broche CS de l'écran - Broche A0 de la Blue Pill
  • Broche RESET de l'écran - Broche Broche A2 de la Blue Pill
  • Broche DC/RS de l'écran - Broche A1 de la Blue Pill
  • Broche SDI (MOSI) de l'écran - Broche A7 de la Blue Pill
  • Broche SCK de l'écran - Broche A5 de la Blue Pill
  • Broche LED de l'écran - Sortie 3,3 V de la Blue Pill
  • Broche SDO (MISO) de l'écran - Broche A6 de la Blue Pill
  • Broche T_CLK de l'écran - Broche A5 de la Blue Pill
  • Broche T_CS de l'écran - Broche A4 de la Blue Pill
  • Broche T_DIN de l'écran - Broche A7 de la Blue Pill
  • Broche T_DO de l'écran - Broche A6 de la Blue Pill
  • Broche T_IRQ de l'écran - pas connectée

Installation de la bibliothèque TFT_eSPI

Il est nécessaire d'installer la bibliothèque TFT_eSPI de Bodmer . La façon la plus simple consiste à utiliser le gestionnaire de bibliothèques de l'IDE Arduino.



Configuration de la bibliothèque (fichier User_Setup_Select.h)

Une particularité de bibliothèque TFT_eSPI, c'est qu'il faut la configurer en fonction du type d'écran et du microcontrôleur que vous utilisez.  Pour ce faire, vous devez ouvrir le fichier "User_Setup_Select.h", qui se trouve dans le dossier où vous avez installé la bibliothèque (Sketchbook - libraries - TFT_eSPI)


Dans le fichier User_Setup_Select.h, commentez la ligne numéro 22 (pour la désactiver), et dé-commentez la ligne 62:  
"#include <User_Setups/Setup32_ILI9341_STM32F103.h>".


Ce mode de configuration fait en sorte qu'un même sketch fonctionnera sans problème avec plusieurs écrans différents et plusieurs microcontrôleurs différents, à la condition que la bonne ligne du fichier User_Setup_Select.h soit activée.

Exemple de sketch #1: des boutons et des formes géométriques

J'avais écrit ce premier sketch pour l'utiliser avec un ESP8266, mais il fonctionne parfaitement avec la Blue Pill sans la moindre modification. Deux boutons apparaissent à l'écran: lorsqu'on touche au bouton de gauche, un rectangle est affichée, et lorsqu'on touche au bouton de droite, un cercle est affiché. Ce programme minimaliste vous aidera à comprendre comment utiliser des boutons, et comment tracer les formes géométriques de base.




-
-


Exemple de sketch #2: un bouton coulissant

Un bouton coulissant ("slider") peut s'avérer utile pour faire varier une valeur numérique de façon continue. Cette valeur pourrait être récupérée pour varier la luminosité d'une LED, modifier la position angulaire d'un servomoteur ou d'un moteur pas à pas, modifier la vitesse de rotation d'un moteur, etc. Il s'agit de toucher l'écran pour déplacer le bouton le long d'une droite horizontale.


-
-

À lire également:



Yves Pelletier (TwitterFacebook)

samedi 24 avril 2021

Contrôler un servomoteur avec le Raspberry Pi Pico (MicroPython)

Il n'est pas très difficile de contrôler un servomoteur au moyen du Raspberry Pi Pico programmé en MicroPython.


Un petit servomoteur se contrôle au moyen d'un signal modulé en largeur d'impulsion (PWM) de 50 Hz de fréquence. La position du servomoteur dépend de la durée des impulsions, qu'on fait typiquement varier entre 1 ms et 2 ms.

Connexions du servomoteur au Rasperry Pi Pico

Ces servomoteurs sont conçus pour fonctionner à une tension de 5 V.  Pour faire mes tests, puisqu'il n'y avait qu'un seul petit servomoteur, j'ai utilisé la broche VBUS du Pico comme sortie 5 V. Il est toutefois préférable d'alimenter le servomoteur avec une alimentation distincte.

N'importe quelle broche GPIO du Pico peut générer un signal PWM. Le script ci-dessous suppose que le servomoteur est contrôlé par la broche GP 15.

  • Fil brun du servomoteur: broche GND du Pico
  • Fil rouge du servomoteur: broche VBUS du Pico (ou autre alimentation 5 V)
  • Fil jaune du servomoteur: broche GP 15 du Pico


Exemple de script en MicroPython

Le script ci-dessous fait tourner le servomoteur dans un sens, puis dans l'autre. Par expérimentation, vous devriez pouvoir déterminer les valeur exactes à utiliser comme paramètre à duty_u16() pour que votre servomoteur atteigne les positions extrêmes de son mouvement.  En principe, ça devrait aller d'environ 3000 à 6500, mais ça peut varier un peu d'un servomoteur à l'autre.

Plutôt que duty_u16(), j'aurais pu utiliser la méthode duty_ns(). Mais puisque la durée d'une impulsion de 1,5 milliseconde correspond à 1500000 nanosecondes, les valeurs numériques à utiliser m'ont semblé peu pratiques.

-


-

À lire également


Yves Pelletier 
(TwitterFacebook)

mercredi 21 avril 2021

Bricoler un robot dessinateur BrachioGraph

Le BrachioGraph est un robot dessinateur (plotter, table traçante) qui a été spécialement conçu pour être fabriqué à très faible coût, sans outils et avec très peu de matériel: un Raspberry Pi, trois servomoteurs, deux bâtonnets, une pince à linge et un peu de colle ou de ruban adhésif suffisent à sa réalisation.


Assemblage du robot

C'est la partie la plus simple: on fixe deux palonniers de servomoteur sur un bâtonnet de bois, à 8 cm l'un de l'autre. Sur un deuxième bâtonnet, on fixe un servomoteur et une pince à linge, qui servira à tenir le crayon (on mesure encore une fois 8 cm entre la position du crayon et le moyeu du servomoteur). Vous trouverez une marche à suivre très claire et beaucoup plus détaillée sur la page officielle BrachioGaph par Daniele Procida.


Il en résulte un bras robotisé constitué de deux segments, chacun d'entre pouvant tourner dans un plan horizontal. Le 3e servomoteur sert à soulever le crayon lorsqu'on doit le déplacer sans faire de marque sur la feuille de papier.


Branchements des servomoteurs au Raspberry Pi

Les trois servomoteurs sont alimentées par une des sorties 5 V du Raspberry Pi. 

  • Le servomoteur "épaule" (celui qui demeure immobile) est branché à la broche GPIO 14.
  • Le servomoteur "coude" (qui fait le lien entre les deux bâtonnets) est branché à la broche GPIO 15.
  • Le servomoteur qui soulève le crayon est branché à la broche GPIO 18.

Installation des logiciels dans le Raspberry Pi

Il y a beaucoup de trucs à installer mais, encore une fois, tout est expliqué sur la page de BrachioGraph:

On colle tout ça dans le terminal:

sudo apt install -y python3-venv pigpiod libjbig0 libjpeg-dev liblcms2-2 libopenjp2-7 libtiff5 libwebp6 libwebpdemux2 libwebpmux3 libzstd1 libatlas3-base libgfortran5 git

Et ensuite:

python3 -m venv env
source env/bin/activate

On clone la bibliothèque BrachioGraph:

git clone https://github.com/evildmp/BrachioGraph.git

On entre dans le nouveau répertoire "BrachioGraph":

cd BrachioGraph
pip install -r requirements.txt


Mise à l'essai

Pour démarrer le brachiograph, il faut démarrer le démon pigpiod ainsi qu'un environnement python:

sudo pigpiod
source env/bin/activate
python
from brachiograph import BrachioGraph
bg = BrachioGraph()


À partir de là, on peut écrire des commandes en Python, ligne par ligne (mais à la longue, considérant toutes les commandes de calibrations nécessaires, c'est plus simple d'exécuter un script en python: le site brachio.me présente des exemples de scripts).

L'instruction "bg.box()" ordonne au BrachioGraph de tracer un rectangle. Voici le premier "rectangle" que j'ai obtenu...


Calibration

Il est assez normal d'obtenir ce genre de résultat très approximatif lors de vos premiers essais: le BrachioGraph a besoin d'être calibré pour fonctionner correctement.

Par exemple, le logiciel suppose que vos servomoteurs tournent de 1° chaque fois que la durée des impulsions pwm varie de 10 µs, mais en fait ça varie d'un servomoteur à l'autre.

En faisant quelques tests (qui pourraient être refaits avec une bien meilleure précision), j'ai constaté que:

  • Mon premier servomoteur tournait de 1° pour une variation d'environ 8 µs
  • Mon deuxième servomoteur tournait de 1° pour une variation d'environ 12 µs
  • Mon troisième servomoteur (celui qui était responsable de soulever le crayon) avait rendu l'âme!

J'ai modifié ces paramètres de façon logicielle en écrivant:

bg.servo_1_degree_ms = -8
bg.servo_2_degree_ms = 12

Suite à ces modification, le rectangle tracé par le Brachiograph, sans être parfait, s'était un peu amélioré  (je n'avais pas encore remplacé le 3e servomoteur, d'où le gribouillis indésirable à droite du rectangle).


Il serait possible d'améliorer encore la calibration de mon traceur: 

  • en mesurant avec une meilleure précision le nombre de microsecondes correspondant à une rotation de 1°
  • en tenant compte de la non-linéarité de mes servomoteurs
  • en compensant l'hystérésis
  • en minimisant le mouvement du crayon lorsqu'il est soulevé. 

Évidemment, tout ça est expliqué en détails sur la page de BrachioGraph. Je n'ai rien fait de tout ça, parce que ma patience est somme toute assez limitée...

Reproduire l'illustration d'un fichier .jpeg

On peut s'amuser un certain temps à tracer des formes simples en utilisant des commandes comme "bg.drive_xy()", mais là où ça devient vraiment rigolo, c'est quand on utilise le BrachioGraph pour reproduire une image.

Pour ce faire, il faut d'abord convertir l'image en un fichier .json qui décrit toutes les lignes qui devront être tracées par le BrachioGraph.

(voici un extrait d'un fichier json:)


Le répertoire "BrachioGraph" créé sur votre Raspberry Pi contient les programmes nécessaires à cette conversion, mais j'ai préféré utiliser le site "brachio.me" de Rob Bricheno: vous y téléchargez votre fichier (jpeg, png ou autre), et il le transforme en un fichier json prêt à l'emploi.

Vous pouvez alors copier ce fichier json dans le répertoire BrachioGraph du Raspberry Pi, puis le faire tracer par la commande: 

bg.plot_file("nom_du_fichier.json")


Résultat: à la fois impressionnant...et un peu brouillon

Sur figure ci-dessous, de gauche à droite: le fichier original (format jpeg), la version vectorisée par le site brachio.me et, finalement, la copie réalisée, avec une certaine dose d'impressionnisme, par mon BraccioGraph. Il faudrait que j'améliore la calibration (surtout à gauche), mais c'est assez amusant, malgré tout.


Pour terminer, une vidéo montrant mon BrachioGraph au travail, pendant le début de l'illustration (environ 5 minutes sont nécessaires pour réaliser l'illustration complète).


Ressources:
À lire également

Avec du matériel similaire, vous pouvez fabriquer un robot quadrupède.


Yves Pelletier (TwitterFacebook)

mercredi 14 avril 2021

Écran OLED SH1106 et Pico

Dans cet article, je programme le Raspberry Pi Pico en MicroPython afin d'afficher des images et du texte sur un petit écran OLED I2C de 128X64 pixels (contrôleur SH1106).


Connexions

Quatre connections sont suffisantes pour brancher l'écran OLED au Pico:

  • Broche GND de l'écran: une des broches GND du Pico
  • Broche VCC de l'écran: sortie 3,3 V du Pico
  • Broche SCL de l'écran: broche GP9 du Pico
  • Broche SDA de l'écran: broche GP8 du Pico

Installation du driver SH1106

Nous utiliserons ce driver spécialement conçu pour contrôler le SH1106 en MicroPython. Le fichier sh1106.py doit être copié dans le Pico pour que nos scripts fonctionnent. 

Comment s'y prendre? Vous ouvrez le fichier sh1106.py avec Thonny, et vous choisissez "Enregistrer une copie..." dans le menu "Fichier".


... et vous choisissez "appareil MicroPython".


Écrire du texte

Pour afficher du texte à l'écran, on utilise la méthode text. Par exemple, l'expression "oled.text("Bonjour", 10, 15)" affichera le mot "Bonjour". Le début du mot se trouvera à la position horizontale 10 pixels et à la position verticale 15 pixels.



Dessiner des formes géométriques simples

Il est possible de dessiner quelques formes géométriques de base:
  • hline pour tracer une droite horizontale
  • vline pour tracer une droite verticale
  • line pour tracer une droite
  • rect pour tracer un rectangle
  • pixel pour régler un seul pixel
  • fill pour remplir tout l'écran en noir ou en blanc
Pour toutes ces méthodes, le dernier argument est la couleur: 0 pour noir et 1 pour blanc.

Exemple de script

Le script ci-dessous affiche d'abord une charmante comptine...



...puis un rectangle, un cercle et quelques droites.


-
-


Afficher une image bitmap

Pour des images plus complexes, il est possible d'afficher un bitmap. La solution la plus efficace, à mon avis, consiste à enregistrer l'image dans un fichier .pbm et à copier ce fichier dans le Pico.



Création du fichier pbm

Pour transformer une photographie ou une illustration en format pbm, j'ai utilisé le logiciel GIMP.


Tout d'abord, on sélectionne le menu Image / Mode / Couleurs Indexées.

Dans la boîte de dialogue, on choisit "Utiliser un palette noir et blanc (1-bit)":


À cette étape, il n'y a plus de couleurs, ni de niveaux de gris:


Ensuite, on choisit le menu Image / Échelle et taille de l'image...

Dans la boîte de dialogue, on s'assure que les dimensions de l'image ne sont pas supérieures à celle de l'écran (dans mon cas, c'est un maximum de 128 pixels de largeur et de 64 pixels de hauteur).



La définition de l'image a beaucoup diminué, mais elle correspond à celle de notre écran OLED:


Les parties qu'on voit en noir sur l'image d'origine apparaîtront en blanc sur l'écran OLED, et vice-versa. Si on veut éviter ça, on choisit le menu Couleurs / Inverser.


Il ne reste plus qu'à enregistrer le résultat en format pbm: menu Fichier / Exporter sous ... et on choisit un nom de fichier qui se termine par l'extension ".pbm".

Il faut choisir "Raw" et non ASCII.




Copie du fichier pbm dans le Pico

Pour transférer le fichier dans le Pico, on peut utiliser Thonny.

On s'assure que "Fichiers" est coché dans le menu "Affichages":


Du côté gauche de la fenêtre de Thonny, on peut voir, en haut, la liste des fichiers enregistrés dans le Pico ("appareil MicroPython") et, en bas, les fichiers qui se trouvent dans l'ordinateur. Lorsqu'on a localisé notre fichier .pbm, on fait un clic avec le bouton droit de la souris, et on choisit "Téléversement vers /": le fichier est transféré dans le Pico.



Script en MicroPython pour afficher le contenu du fichier pbm

Voici le script qui affichera sur l'écran OLED l'image stockée dans le fichier pbm (on suppose que ce fichier s'intitule "image.pbm".

-
-


Sources

Cet article sur le blog de Martin Fitzpatrick m'a été particulièrement utile pour l'affichage d'une image bitmap.


À lire également



Yves Pelletier (TwitterFacebook)

lundi 12 avril 2021

Assemblage d'un bras robotique miniature de type MeArm v0.4

MeArm est le nom d'un bras robotique miniature open source dont la première version à été mise au point en 2014. Je me suis procuré un kit similaire à la version 0.4 du MeArm. Si vous avez accès à l'équipement nécessaire, vous pouvez fabriquer les pièces vous-mêmes grâce aux fichiers fournis sur Thingiverse (mais alors vous préférerez peut-être réaliser une version plus récente: ils en sont à la version 3.0).


Je vous montre immédiatement une vidéo de mon bras robotique, une fois monté, en train d'effectuer ses exercices physiques quotidiens:

Le bras est actionné par 4 petits servomoteurs: un d'entre eux fait tourner la base rotative, un autre  sert à ouvrir et fermer la pince...

...un des deux servomoteurs latéraux ("l'épaule"), contrôle la partie antérieure du bras...


... alors que l'autre servomoteur latéral ("le coude"), contrôle l'inclinaison de la partie supérieur du bras.


Assemblage du bras

Au départ, les pièces en acrylique sont disposées sur 4 plaquettes de 14,5 cm X 9,5 cm. C'est le moment idéal d'énoncer notre traditionnelle remarque "Mais...ça semblait beaucoup plus grand sur les photos!". 

(Une fois terminé, le bras semble un peu plus petit que sur les photos, mais plus grand qu'on aurait pu le croire en regardant les pièces détachées)


On détache chacune des 37 pièces, et on prend soin de retirer le papier adhésif protecteur.


Il y a aussi des vis...



Aucune directive d'assemblage n'accompagnait mon kit, mais le vendeur avait proposé un lien vers les instructions officielles de la version 0.4 de MeArm sur le site Instructables. L'assemblage du bras robotique y est extrêmement bien documenté: les instructions sont claires et détaillées, les photographies sont nombreuses. Seul bémol: les pièces qui figurent sur ce guide d'assemblage sont très similaires aux miennes, mais pas rigoureusement identiques, ce qui m'a rendu un peu nerveux au début: je n'étais jamais certain à 100% de faire la bonne chose en utilisant le bon morceau...

Ainsi, j'avais remarqué avec inquiétude que le kit officiel comportait 4 collets servant à fixer un servomoteur, alors que le mien n'en comportait que 3. En cours de route, j'ai constaté qu'il s'agissait d'une pièce de rechange, car plusieurs personnes en cassent un en serrant un vis trop fortement. Pas besoin du 4e collet, alors...

J'avais aussi une petite pièce qui ne ressemblait à rien de ce que je pouvais voir dans les instructions, mais son emplacement est devenu évident vers la fin du montage.

Pas de panique, donc. Il s'agit de ne pas être trop pressé, et d'accepter d'avoir à démonter certaines parties lorsqu'on constate qu'on a placé quelque chose à l'envers (ça m'est arrivé quelques fois). Plusieurs pièces comportent des coches situées d'une façon qui vous oblige à les installer dans le bon sens (ou à constater qu'on a commis une erreur lors d'une étape précédente).

Assemblage de la base rotative (étapes 2, 3, 4 et 5 des instructions):




Le côté gauche (étapes 6, 7 8 et 9 des instructions):




Le côté droit (étapes 10 et 11 des instructions):




Jonction des deux côtés et ajout de la travée centrale (étapes 12, 13 et 14):







Installation sur la base et ajout des avant-bras (étapes 16 et 17):




Assemblage de la pince... (étapes 18 et 19) ... (dans l'excitation du moment, j'ai complètement oublié de prendre quelques photos!)


Et le bras est terminé!


En cours de route, j'ai cassé le coin d'une pièce supportant la pince (la vis devait s'insérer dans le sens contraire à ce qu'indiquaient les instructions...). J'ai pu réparer ma gaffe grâce à un peu de colle. J'ai aussi remplacé deux vis d'articulations qui n'étaient plus retenues par leur pièce de plastique (probablement parce qu'elles avaient été un peu trop souvent dévissées/revissées).

Contrôle des servomoteurs

Puisque mon kit ne comportait aucune carte de contrôle, j'avais l'entière liberté de choisir ce qui me convenait le mieux. J'ai opté pour un Arduino Uno associé à un module PCA9685. J'avais d'abord essayé de brancher les servomoteurs directement à l'Arduino, sans le module PCA9685, mais le comportement du bras devenait erratique lorsque les 4 servomoteurs étaient branchés en même temps.


Le projet MeArm met à notre disposition une bibliothèque de cinématique inverse: il s'agit d'indiquer les coordonnées de la position finale désirée, et la bibliothèque calcule la position angulaire que doit prendre chacun des 4 servomoteurs: cette bibliothèque est offerte en version Arduino, Arduino avec module PCA9685, Raspberry Pi, Beaglebone Black et Espruino.

Avant de passer à ces bibliothèques, je recommanderais de faire quelques tests pour vérifier le bon fonctionnement de chacun des 4 servomoteurs, en démarrant à leur position centrale et en les faisant tourner avec précaution de façon à connaître les limites de leur mouvement.

Les servomoteurs ne semblent pas très loin de leur moment de force maximal: j'ai obtenu des meilleurs résultats en les alimentant avec une tension de 6 V, et en ajoutant un peu de lubrifiant sur les articulations du bras.

À lire aussi:


Yves Pelletier (TwitterFacebook)