Dans la série d'articles actuelle, je m'adresse à mes collègues du groupe physique. Les prochains épisodes porteront sur un dynamomètre sans ressort hélicoïdal, qui utilise bien sûr un capteur élastique. Cependant, l'élasticité de ce dernier est à peine visible. Mais cet aspect visuel à peine perceptible ne réduit en rien la résolution, il la favorise plutôt. Je vous dévoilerai comment cela est possible dans les nouveaux épisodes de la série.
MicroPython sur ESP32, ESP8266 et Raspberry Pi Pico
aujourd'hui
Un dynamomètre sous MicroPython – Partie 1
1. Dans la première partie, nous nous intéressons au principe de mesure et à la structure du matériel.
2. Dans la deuxième partie, nous ajoutons un grand écran sur l'ordinateur portable, qui est contrôlé via USB.
3. Dans la partie 3, nous remplaçons le câble de données USB par une transmission radio.
4. La partie 4 comprend une unité d'affichage avec 8 panneaux LED, qui est également connectée via WLAN.
5. Une tablette Android servant d'unité d'affichage est présentée dans la partie 5.
Le capteur de force
Il y a quelque temps, j'ai déjà utilisé ailleurs un composant dont un autre élément de la même famille est à nouveau utilisé aujourd'hui. balance . Dans les deux cas, il s'agit en fin de compte de mesurer des forces. Cela signifie que même lors de la détermination de la masse à l'aide d'une balance, il s'agissait de mesurer une force, à savoir la force gravitationnelle Fg. Celle-ci est liée à la masse m des poids par le facteur local g = 9,81 N/kg : Fg = g • m. Il était ainsi possible de calibrer la balance à l'aide de poids. La figure 1 montre un tel fléau. Le côté droit de la balance est solidement vissé au sol, tandis que le plateau est fixé à gauche.

illustration 1: Cellule de pesage vue de côté
Dans le cas présent, il s'agit de mesurer directement les forces. Cela est possible grâce à la déformation élastique d'un fléau de balance en aluminium sur lequel sont fixées des jauges de contrainte. Ces composants sont constitués de boucles conductrices extrêmement fines qui, en fonction de leur emplacement, sont étirées ou comprimées par la flexion des parties amincies du fléau, modifiant ainsi leur résistance électrique.

illustration 2: Jauges de contrainte schématiques
L'étirement rend les conducteurs plus longs et plus fins, tandis que le raccourcissement produit l'effet inverse. La longueur et la section transversale du conducteur sont toutes deux prises en compte dans le calcul de la résistance électrique d'un conducteur. L'allongement et la réduction de la section transversale entraînent tous deux une augmentation de la valeur de résistance. ρ est la résistance spécifique, une constante du matériau.

illustration 3: Formule de résistance
Afin que même les plus infimes variations de la valeur de résistance donnent un résultat de mesure reproductible avec une haute résolution, les bandes de mesure sont regroupées en un circuit en pont dont la tension de sortie est transmise à un amplificateur de précision. La tension de sortie de celui-ci doit ensuite être numérisée pour être traitée dans un microcontrôleur.

illustration 4: Jauges de contrainte sur le HX711
Le module HX711 comprend les deux composants et permet en outre de choisir le gain, 128 fois ou 64 fois à l'entrée différentielle A, ainsi que 32 fois à l'entrée B. La transmission du signal 24 bitsADC-Werts (ADC = Analog Digital Converter) vers le microcontrôleur s'effectue via la Données-Conduite qui, par 24 impulsions à Horloge est synchronisé. Jusqu'à trois impulsions supplémentaires influencent le réglage du gain du PGA (amplificateur à gain programmable) pour la mesure suivante. La balance à fléau utilisée ici peut supporter une charge maximale de 5 kg, ce qui correspond à une force maximale d'environ 50 N. Avec l'entrée A et un gain de 128, nous obtenons une résolution de 1 mN, ce qui correspond à une masse d'environ 0,1 gramme. Comme il s'agit déjà d'un point incertain, nous nous contentons de 10 mN comme plus petite grandeur de mesure et obtenons en contrepartie un affichage stable des valeurs mesurées. 0,01 N est en effet bien plus que ce que l'on peut obtenir avec des dynamomètres à ressort hélicoïdal.

illustration 5: Réglage du gain via des impulsions d'horloge supplémentaires
L'interface logicielle vers le HX711 est la classe HX711 du module MicroPython hx711.py. Nous y reviendrons plus tard.
matériel informatique
Les modèles ESP8266 et ESP32 disposant d'au moins quatre GPIO libres peuvent être utilisés comme contrôleurs. La valeur mesurée s'affiche d'abord sur un écran OLED. Bien sûr, un autre modèle peut également servir de cellule de pesée. Elles sont disponibles à partir de 100 g jusqu'à 100 kg et plus.
Pour des raisons d'espace, j'ai opté dans ce projet pour un D1 Mini NodeMcu avec module WiFi ESP8266-12F décidé. L'alimentation électrique du système électronique de mesure est assurée pour l'instant par le port USB.
Le circuit pour l'ESP8266 D1 Mini

illustration 6: Dynamomètre - Circuit
Le logiciel
Pour le flashage et la programmation de l'ESP32 :
Thonny ou
Création de jeux de caractères personnalisés
zeichensatz.rar Environnement de travail pour créer vos propres jeux de caractères
Pour afficher les signaux de bus
SALEAE – Logiciel d'analyse logique (64 bits) pour Windows 8, 10, 11
Firmware utilisé pour l'ESP32 :
Firmware utilisé pour l'ESP8266 :
Firmware utilisé pour le Raspberry Pi Pico (W) :
RPI_PICO_W-20240602-v1.23.0.uf2
Les programmes MicroPython pour le projet :
ssd1306.py Pilote matériel pour l'écran OLED
oled.py API pour l'écran OLED
géomètre_30.py Grand jeu de caractères pour l'affichage des chiffres
hx711.py API pour l'AX711
newtonmeter.py Le programme d'exploitation
MicroPython - Langage - Modules et programmes
Pour installer Thonny, vous trouverez ici un instructions détaillées (version anglaise). Il contient également une description de la manière dont la Micropython-Firmware (état au 25/01/2024) sur la puce ESP brûlé sera. Pour savoir comment mettre en service le Raspberry Pi Pico, consultez ici.
MicroPython est un langage interprété. La principale différence avec l'IDE Arduino, où vous flashez toujours et exclusivement des programmes complets, est que vous ne devez flasher le micrologiciel MicroPython qu'une seule fois au début sur l'ESP32 pour que le contrôleur comprenne les instructions MicroPython. Vous pouvez utiliser Thonny, µPyCraft ou esptool.py à cette fin. Pour Thonny, j'ai documenté le processus ici décrit.
Une fois le micrologiciel flashé, vous pouvez facilement communiquer avec votre contrôleur, tester des commandes individuelles et voir immédiatement la réponse sans avoir à compiler et transférer tout un programme au préalable. C'est exactement ce qui me dérange dans l'IDE Arduino. On gagne énormément de temps lorsqu'on peut tester au préalable la syntaxe et le matériel, mais aussi essayer et affiner des fonctions et des parties entières du programme via la ligne de commande, avant de créer un programme à partir de là. À cette fin, j'aime créer régulièrement de petits programmes de test. Ils regroupent des commandes récurrentes sous forme de macros. Ces fragments de programme permettent parfois de développer des applications complètes.
démarrage automatique
Si vous souhaitez que le programme démarre automatiquement à la mise sous tension du contrôleur, copiez le texte du programme dans un nouveau fichier vierge. Enregistrez ce fichier sous le nom main.py dans l'espace de travail et téléchargez-le sur la puce ESP. Le programme démarrera automatiquement lors de la prochaine réinitialisation ou mise sous tension.
Tester les programmes
Les programmes sont lancés manuellement à partir de la fenêtre d'édition actuelle dans l'IDE Thonny à l'aide de la touche F5. Cela est plus rapide que de cliquer avec la souris sur le bouton Démarrer ou via le menu. CoursSeuls les modules utilisés dans le programme doivent se trouver dans la mémoire Flash de l'ESP32.
Encore une fois Arduino IDE entre-temps ?
Si vous souhaitez réutiliser ultérieurement le contrôleur avec l'IDE Arduino, il vous suffit de flasher le programme comme d'habitude. Cependant, l'ESP32/ESP8266 aura alors oublié qu'il a déjà utilisé MicroPython. À l'inverse, toute puce Espressif contenant un programme compilé à partir de l'IDE Arduino ou le micrologiciel AT ou LUA ou ... peut être facilement équipée du micrologiciel MicroPython. La procédure est toujours la même, comme ici décrit.
Structure du dispositif de mesure
Pour suspendre le fléau de 12 mm x 12 mm x 75 mm, nous avons besoin de deux autres profilés en aluminium aux mêmes dimensions, ainsi que de deux tôles en aluminium de 21 mm x 12 mm x 2,5 mm servant d'entretoises. Deux rails en U en aluminium sont nécessaires pour accueillir les cartes sur lesquelles sont enfichés le contrôleur et le HX711. Voici le schéma des pièces, également disponible sous forme de Document PDF téléchargé . Il contient la disposition des circuits imprimés et leur plan d'assemblage.
J'ai acheté les profilés en aluminium dans un magasin de bricolage. Des filetages M3 doivent être découpés dans le profilé supérieur pour la fixation des rails en U. La fixation des platines dans les rails en U s'effectue également à l'aide de filetages M3 et d'entretoises en plexiglas (12 mm x 10 mm x 2 mm). Des filetages de 3 mm sur les côtés extérieurs des rails en U servent à la fixation d'un cache optionnel.

illustration 7: Structure mécanique du dynamomètre

illustration 8: Unité de capteur vue de dessus

illustration 9: Dynamomètre en action
La figure 8 montre le montage de l'électronique. Deux cartes équipées de connecteurs femelles pour accueillir le microcontrôleur et le HX711 servent de support. Voici la disposition et le plan d'implantation. Trois connexions de câbles sont indiquées en vert.

illustration 10: Disposition des deux cartes
Pour un premier essai, j'ai mis en place un dispositif de test avec un NodeMCU Lua Lolin Module V3 ESP8266qui était à portée de main. J'ai connecté le fléau de la balance au circuit à l'aide de mes câbles de test.

illustration 11: configuration de test avec une carte ESP8266 Node MCU
Ces câbles de test peuvent être facilement fabriqués à partir d'un câble en silicone et un borne de test Fabriquer une longueur au choix. Une barrette à un pôle permet le raccordement sur la maquette. Un morceau de gaine thermorétractable contrairement à.
illustration 12: Pince de test pratique avec câble en silicone
Un grand jeu de caractères pour l'écran OLED
Les grands chiffres facilitent considérablement la lecture de la mesure. Au lieu des huit pixels habituels, nous utilisons 30 pixels comme hauteur de caractère. Le fichier géomètre_30.py contient les informations correspondantes.
Pour créer notre propre jeu de caractères pour l'écran OLED, nous avons besoin de quelques ingrédients.
1. Python pour Windows
2. freetype-py
Si Python n'est pas encore installé sur votre PC, vous devez le faire maintenant. Téléchargez le paquet actuel Python 3.13.3 et installez-le en exécutant le fichier python-3.13.3-amd64.exe dans le dossier de téléchargement et suivez les instructions de l'assistant.
freetype-py est un outil nécessaire à la conversion d'un jeu de caractères TTF sous Windows. Avec Python, un outil appelé pip3 installé. Nous l'utilisons pour freetype-py à installer.
Ouvrez l'invite de commande et saisissez la ligne suivante à l'invite.
pip3 install freetype-py
Voici comment créer votre propre jeu de caractères à partir de la bibliothèque TTF de Windows.
Télécharger l'archive zeichensatz.rar et décompressez le contenu dans un répertoire de votre choix. Pour éviter de taper trop de caractères, je recommande d'utiliser un répertoire avec un nom court dans le chemin racine du disque dur ou d'une clé USB. Dans mon cas, il s'agit de F:\polices.
Ouvrez une fenêtre Powershell dans ce répertoire à partir de l'Explorateur en maintenant la touche touche Maj un clic droit sur le répertoire. Cliquez ensuite avec le bouton gauche de la souris sur Ouvrir la fenêtre PowerShell ici.

illustration 13: Ouvrir la fenêtre Powershell
À l'invite, entrez la ligne suivante et appuyez sur Entrer.
.\makecharset.bat geometer 30 « 0123456789,-+N » « F:\fonts\quellen\ »

illustration 14: Le jeu de caractères est prêt.
Le répertoire contient désormais un fichier géomètre_30.py avec les données pixel du nouvel extrait de jeu de caractères. Seuls les caractères en « 0123456789,-+N », ce qui permet d'économiser de l'espace mémoire. Vous pouvez télécharger d'autres jeux de caractères à partir du policesRépertoire Windows dans le répertoire sources Copiez-le et convertissez-le comme indiqué ci-dessus. Veuillez noter que le nom du fichier doit être indiqué sans l'extension .TTF.
Nous copions maintenant le jeu de caractères généré dans le répertoire de travail de notre nouveau projet MicroPython.
Premiers tests
La LED de signalisation
Nous pouvons alors commencer à effectuer quelques premiers tests. Pour cela, nous pouvons utiliser le circuit de test de la figure 11, auquel la balance est connectée comme indiqué dans le schéma de la figure 6.
Comme LED de signalisation, j'ai utilisé une LED Neopixel provenant d'une bande LED qui restait de la construction de l'horloge Abacus. Cela présente l'avantage de pouvoir afficher n'importe quelle couleur à l'aide d'une seule LED via un câble de commande.
illustration 15: LED Neopixel
Parce que le NodeMCU Lua Lolin Module V3 ESP8266 Comme le broche Vin ne fournit pas les 5 V de l'USB, j'ai connecté le +5 V de la bande à la sortie 3,3 V de la carte contrôleur, ce qui fonctionne sans problème avec une LED. Le ESP8266 D1 Minique nous installons dans le capteur de force fournit effectivement les 5 V de l'USB à la broche 5 V. Din nous nous joignons à D4 = GPIO2 activé.
Ci-dessous, les entrées dans REPL gras formaté, dépenses italique.
>>> from neopixel import NeoPixel
L'objet Neopixel se compose d'une LED sur GPIO2.
>>> led=Pin(2, Pin.OUT, value=0) # D4
>>> np=NeoPixel(led,1)
Nous définissons certaines couleurs…
>>> rouge=(4,0,0)
>>> bleu=(0,0,4)
>>> jaune=(16,8,0)
>>> off=(0,0,0)
Et vérifions leur efficacité.
>>> np[0]=rouge
>>> np.write()
>>> np[0]=off
>>> np.write()
Nous regroupons le choix des couleurs et l'écriture vers la LED dans la fonction signal() ensemble.
>>> def signal(col) :
np[0]=col
np.write()
>>> signal(jaune)
>>> signal(off)
Mesure des forces
Pour l'utilisation du HX711 Existe-t-il une classe dans le module hx711.py habite. Si l'on commence hx711.py dans une fenêtre d'édition Thonny, le bloc if à la fin du listing crée un objet HX711 avec l'identificateur hx.
if __name__ == "__main__" :
from machine import Pin
hx=HX711(broche(14),broche(12,broche.IN)) # D5, D6
Nous pouvons ainsi faire nos premiers pas avec le capteur de force. Nous récupérons une valeur mesurée, telle que déterminée par le HX711, via la ligne série. Conformément à son câblage, nous obtenons 10 valeurs par seconde (taux de connexion = GND).
>>> %Run -c $EDITOR_CONTENT
HX711 prêt sur le canal A avec un gain de 128
>>> hx.getRaw()
-502747
Cette valeur est obtenue pour le fléau non chargé. Dans notre cas, le point de référence n'est pas le support inférieur du fléau, mais le crochet situé dans la partie supérieure. Lorsque l'unité de mesure est suspendue, les pièces profilées montées sous le fléau font également partie des éléments qui exercent une charge sur le capteur. Nous devons tenir compte de cette valeur comme tare pour les mesures ultérieures. Nous déterminons la valeur de tare à partir de plusieurs mesures en calculant la moyenne. Nous indiquons le nombre de mesures lors de l'appel, ici 2.
>>> hx.tara(2)
-502631

illustration 16: Enregistrer la tare
Ensuite, il faut calibrer le capteur. Cela signifie que la valeur brute mesurée pour une force donnée, corrigée de la valeur de tare, doit être convertie en une valeur de force en newtons. Nous fixons donc solidement le fléau ou suspendons notre unité de mesure, démarrons hx711.py et appelons hx.tara(2) . La valeur de tare est ainsi enregistrée dans l'attribut hx.tare enregistrées et renvoyées.
Nous devons maintenant déterminer le facteur d'étalonnage pour la conversion en newtons. La méthode suivante permet d'y parvenir hx.calibrateF(), auquel nous transmettons la masse de 102 g. Dans le champ gravitationnel terrestre, cette masse subit, selon le lieu de mesure, une force pondérale d'environ 1 newton.

illustration 17: Calibrer à 1 N avec une masse de 102 g.
Cette valeur est également utilisée comme attribut hx.fcal de l'objet HX711. Nous pouvons désormais mesurer directement les forces en utilisant la méthode hx.kraft(n). Le paramètre n indique le nombre de mesures à effectuer pour calculer la moyenne. Chaque mesure individuelle dure environ 100 ms.
>>> hx.calibrateF(102)
44098.7
>>> hx.kraft(2)
1.00366
Nous pouvons consulter le facteur d'étalonnage à tout moment et, si nécessaire, le réajuster manuellement. Pour simplifier la procédure, il est recommandé d'enregistrer le facteur d'étalonnage trouvé dans la classe HX711 pour l'attribut de classe KFactorForce . Nous pourrions également enregistrer cette valeur dans un fichier que nous lirions à chaque démarrage.
>>> hx.fcalFacteur(44098,1)
>>> hx.kraft(2)
1.00045
>>> hx.kraft(2)
1.00288
Nous constatons qu'un résultat exploitable ne peut être indiqué qu'avec deux décimales, car la troisième décimale est déjà très incertaine. Mais cela suffit, car aucun dynamomètre classique à ressort hélicoïdal ne peut atteindre une précision de 0,01 N. À l'avenir, nous ajusterons donc nos résultats de mesure pour les afficher sur six positions avec deux décimales et les aligner à droite (>) avec un « N » comme désignation.
>>> « {:>6.2f} N ».format(hx.force(2))
' 1,00 N'
Caractères plus grands sur l'écran OLED
Le module géomètre_30.py a la structure suivante. Après un en-tête dans lequel sont indiqués les caractères contenus, la hauteur et la largeur maximale des caractères, la liste contient numéro tupledont le premier composant indique la largeur actuelle du caractère. Vient ensuite le motif pixel du caractère sous la forme octets-Objets en représentation binaire. À propos de la position du caractère dans la chaîne chars nous avons accès à l'entrée dans numéro. Il est possible de générer ses propres caractères en créant manuellement le motif binaire et en insérant un caractère pointeur dans chars Enregistrer.
Le module doit être téléchargé dans la mémoire flash du contrôleur afin de pouvoir être utilisé.
>>> importer geometer_30 en tant que cs
Une fois importé de cette manière, le module peut être utilisé avec le préfixe géomètre_30 très court avec le préfixe cs aborder.
chars="0123456789,-"
height=31
width=29
number=[
(17, # Caractères : 0
0b00000000000000000,
0b00000000000000000,
0b00000000000000000,
0b00000011111000000,
0b00001111111110000,
0b00011111111111000,
0b00011111111111000,
0b00111110001111100,
0b00111110001111100,
0b01111100000111110,
0b01111100000111110,
0b01111100000111110,
0b01111100000111110,
0b01111100000111110,
0b01111100000111110,
0b01111100000111110,
0b01111100000111110,
0b01111100000111110,
0b00111110001111100,
0b00111110001111100,
0b00011111111111000,
0b00011111111111000,
0b00001111111110000,
0b00000011111000000,
0b00000000000000000,
0b00000000000000000,
0b00000000000000000,
0b00000000000000000,
0b00000000000000000,
0b00000000000000000,
0b00000000000000000,
),
Pour afficher le motif, il suffit maintenant de placer un pixel à l'écran à chaque emplacement où se trouve un 1 dans le motif, à partir de la position de départ (= coin supérieur gauche de la matrice de caractères). C'est ce que fait la fonction putNumber(). Le numéro du motif dans la liste est obtenu grâce à la ligne suivante. z est le signe à représenter, la méthode index() détermine la position dans chars.
>>> n=cs.chars.index(z)
def putNumber(n,xpos,ypos,show=True) :
largeur=cs.number[n][0]
pour chaque ligne dans la plage (1, cs.height) :
for col in range(largeur-1,-1,-1) :
c=cs.number[n][row] & 1<
d.setPixel(xpos+largeur+3-col,ypos+row,c,False)
if show :
d.show()
return xpos+largeur+2
Nous récupérons la largeur du caractère et parcourons le motif ligne par ligne et colonne par colonne. Nous lisons le code couleur c, 0 ou 1, et définissons de manière masquée (False) le pixel sur la couleur d'arrière-plan ou de premier plan, 0 ou 1. Deux pixels sont prévus comme espacement entre les caractères. La fonction renvoie la position x du caractère suivant, de sorte que les caractères peuvent être affichés en mode proportionnel.
Pour les prochains tests, les fichiers oled.py et ssh1306.py être téléchargées dans la mémoire flash du contrôleur.
>>> importer geometer_30 en tant que cs
>>> from machine import Pin,freq,SoftI2C
>>> from oled import OLED
>>> importer geometer_30 en tant que cs
>>> def putNumber(n,xpos,ypos,show=True) :
largeur=cs.number[n][0]
pour chaque ligne dans la plage (1, cs.height) :
for col in range(largeur-1,-1,-1) :
c=cs.number[n][row] & 1<
d.setPixel(xpos+largeur+3-col,ypos+row,c,False)
if show :
d.show()
return xpos+largeur+2
>>> n=cs.chars.index("5")
>>> n
5
>>> n=cs.chars.index("N")
>>> n
13
>>> d.clearAll(False)
>>> pos=putNumber(5,0,0, False)
>>> pos=putNumber(13,pos,0, True)
Nous disposons désormais de toutes les conditions nécessaires à la programmation de notre dynamomètre. La mise en œuvre sera abordée dans le prochain article.
Restez à l'écoute ! À bientôt !







2 commentaires
Claus
Hallo,
toller Artikel, musste ich gleich aufbauen.
Wenn ich die Firmware flashe und alle Dateien vom Abschnitt “Die MicroPython-Programme zum Projekt” auf den ESP schreibe bekomme ich nach Programmstart die Fehlermeldung:
this is the constructor of OLED class
Size:128×32
HX711 bereit auf Kanal A mit Gain 128
HX711 initialisiert nicht
Wenn ich hingegen das Script hx711.py vom Bereich “Messung von Kräften” starte (die Zeile “from timeout import TimeOutMs” musste ich auskommentieren, da das Modul nicht gefunden wurde) bekomme ich sinnvolle Messwerte, die sich deutlich ändern, wenn ich das Gewicht ändere.
Was mache ich falsch?
DAVY
Bonjour!
Article clair, explicite, et remarquable parmi les autres: On a: Principe physique + Hard + Soft +Expérimentation !! Et chacun tour à tour explicités ! Belle pédagogie.
Félicitations et merci pour le partage.
En attendant impatiemment la suite ….