Vue lecture

MicroPython: Cellule de charge et limite d'utlisation

Bonjour à tous,

Dans le projet Steam Belgian Knife (sbk.education), il y a l'utilisation d'une cellule de charge comme capteur de pesée ou de capteur force.
La cellule de charge est l'élément principale d'une balance électronique.

L'une des application envisagées est la mesure de la poussée d'une fusée à eau (sur un banc d'essai).
Cela ne sera malheureusement pas possible et nous verrons pourquoi

A propos de la cellule de charge

La cellule de charge est un élément mécanique prévu pour tolérer une déformation en fonction de la force qui y est appliquée.
Cette force résulte soit de la pesée d'un objet, soit d'un effort appliqué directement sur la cellule de charge (au bon endroit et dans la bonne direction).

La cellule de charge est composé d'un pont de Wheatstone, pont constitué de 4 résistances dont l'une d'entre elles est solidaire de la cellule de charge.
Lorsqu'une force déforme la cellule de charge, la résistance est également déformée et sa valeur change sensiblement.
Cela modifie l'équilibre du point de Wheatstone et modifie la tension de sortie d'un ordre de grandeur de l'ordre de quelques millivolts.

Cellule de charge

Les différences de tensions est tellement faible qu'il faut faut employer un amplificateur. Le plus connu est le hx711, un amplificateur 24 bits qui prend en charge l'alimentation et la mesure d'une cellule de charge.

HX711 avec MicroPython

Le HX711 dispose d'une bibliothèque Arduino mais comme vous le savez c'est avant tout l'utilisation avec MicroPython qui nous intéresse.

Pour commencer, voici comment brancher le capteur sur un Raspberry-Pi Pico.

Source: esp8266-upy/hx711

La bibliothèque hx711 et sa documentation (en cours de constitution) est disponible sur le dépôt esp8266-upy/hx711 .

Une fois le fichier hx711.py copié dans sur la carte MicroPython, il est possible d'exécuter l'un des programmes de test.

La tare

Les gauches de contraintes et cellules de charges n'ont pas vraiment de "point Zero".
Ces capteurs sont plus ou moins contraint au repos... et passent dans un autre état de contrainte lorsqu'une masse/force est appliquée.

Il faut donc effectuer une tare qui lit l'état du capteur au repos et mémorise la valeur comme point Zero.
Les autres mesures se feront donc par rapport à ce point Zéro. 

C'est exactement que fait une balance électronique lorsqu'elle est activée! Sa première opération consiste à réaliser une série de mesures pour déterminer le "point zéro" de repos (elle "tare").
C'est pour cela que l'affichage du "0" n'est pas immédiat sur une balance électronique.

Dans la bibliothèque la méthode HX711.tare() permet de réaliser cette opération.

test.py : mesure brute

ce simple programme de test qui affiche la valeur lue sur la cellule de charge.

from hx711_gpio import HX711
from machine import Pin
import time

pin_OUT = Pin(12, Pin.IN, pull=Pin.PULL_DOWN)
pin_SCK = Pin(13, Pin.OUT)

hx711 = HX711(pin_SCK, pin_OUT, gain=128)

hx711.tare()
while True:
	print( "---------------------------------" )
	# Raw value of load cell. Not scaled, no offset compensation
	print( "read: ", hx711.read() )
	print( "get_value: ", hx711.get_value() )
	time.sleep_ms( 500 )

Ce script retourne des "valeurs brutes".
Après avoir étalonné mes masses de test, j'ai effectué un relevé des "valeurs brutes" retournée par la fonction get_value().

Remarque: je me serais attendu à une erreur plus petite sur le poids de 1 Kg.

Si l'on reporte les valeurs dans un graphique, nous pouvons voir qu'il y a une belle relation proportionnelle.

En appliquant la règle de trois, entre les masse et get_value(), ma cellule de charge de 5Kg présente un rapport d'échelle de 404.4715 (le facteur d'échelle est calculée pour une mesure en grammes).

test_unit.py : mesure en gramme

Lorsque le facteur d'échelle est identifié (ex: 404.4715), il est possible d'obtenir la valeur de la mesure directement en grammes si e facteur d'échelle à été calculé pour une cellule de 5000 grammes (un gamme de valeur de 0 à 5000). 

Dans l'exemple ci-dessous, set_scale() est utilisé pour mentionner le facteur d'échelle.
A partir de ce instant, la valeur retournée par get_unit() sera la masse (en grammes).

from hx711_gpio import HX711
from machine import Pin
import time

pin_OUT = Pin(12, Pin.IN, pull=Pin.PULL_DOWN)
pin_SCK = Pin(13, Pin.OUT)

hx711 = HX711(pin_SCK, pin_OUT, gain=128)

hx711.tare()
hx711.set_scale( 404.4715 ) # 5000gr Gauge with 128 bit gain. Output unit will be in grams
while True:
	print( "get_units: %s gr" % hx711.get_units() )
	time.sleep_ms( 500 )

La constante de temps!

Avez-vous déjà remarqué qu'une balance réagit relativement vite mais qu'il faut  quelques secondes pour que la mesure soit stabilisée (surtout sur les balances de précision).

Ce même comportement s'applique aussi aux cellules de charges de cet article. La valeur augmente rapidement mais requière un certain laps de temps avant de se stabiliser près de la valeur finale.

J'ai ajouté un script plot_value.py qui attend la présence d'une masse pour effectuer une rafale de mesures toutes les 200ms jusqu'au retrait de la masse. En reportant les données dans un tableur, puis un graphique de l'évolution de la mesure en fonction du temps.

Source: esp8266-upy/hx711 - Cliquer pour agrandir

La forme de la courbe ressemble furieusement à la courbe de tension d'un circuit RC.

En inspectant celle-ci, nous pouvons constater:

  1. Qu'il faut environ 4 secondes pour obtenir la valeur finale.
  2. Que la section droite de la courbe présente une courbure à partir 2/3 de la valeur finale (très intéressant!).

Suivez la démonstration suivante

A partir de la valeur finale connue (400000), on calcule la valeur à 66% (soit 266666).
Le report de cette valeur de 266666 sur le tracé coupe la courbe de lecture là où celle-ci décolle de la tangente (ligne verte).

Encore mieux, il faut à peine 1077ms pour atteindre 66% de la valeur finale.

Ces 1077ms (ou 1.077 sec) est la constante de temps, temps minimal qu'il faut attendre pour avoir une idée raisonnable de la valeur finale.

Lecture rapide

En faisant une mesure à 1.077sec après que la mesure décolle du Zéro, nous obtenons une valeur indicative qu'il faut multiplier par 1.66 pour estimer le poids/force finale. 

Il suffit d'attendre 3 secondes de plus pour lire la valeur finale et éventuellement corriger la valeur finale.

Incompatibilité avec la mesure de poussée

Rappelez vous, en début d'article, nous parlions d'un banc d'essai pour mesurer la poussée d'une fusée à eau.

Il faut savoir que la majorité de la poussée se produit durant les premiers 1/500 de seconde du lancement (cf. Planète Sciences > Fusée à eau, un superbe document).

Avec une constante de temps de 1.077 sec pour l'obtention d'une mesure approximative... durant le lancement d'une fusée à eau il sera impossible d'effectuer plus d'une mesure avec la cellule de charge!

Il faudra se tourner vers un dynamomètre dont le temps de réponse est de l'ordre de la milliseconde pour effectuer des mesures pertinentes avec une fusée à eau.

Note: pour une fusée à combustible solide, la poussée dure plusieurs secondes (une dizaine), de sorte que la constante de temps à un impact moins important sur la mesure (mais quand même pas négligeable). La cellule de force sera appropriée dans ce cas.

Conclusion

La cellule de charge est un excellent outil permettant de mesurer force statique ou une masse.

Ce capteur ne conviendra pas pour la mesure de force dynamique (comprenez: qui change rapidement).

Note: il me faudra aussi poursuivre la documentation du pilote HX711 qui reste très embryonnaire.
Note 2: la documentation du pilote HX711 est maintenant complétée.

Ressources

❌