Objectif : Réaliser des tests de traction à l’aide d’un capteur de force (programme PCSI) à l’aide d’un microcontrôleur, avec acquisition en temps réel sur Python.
Remarque : Cet article s’inspire librement d’un protocole de TP d’ Allan PETRILLO, technicien de laboratoire du lycée Lakanal à Sceaux. un grand merci à lui !
Le capteur de force est constitué de :
- Une jauge de contrainte 5 kg CZL 635 (à peu près 10 euros) : https://www.gotronic.fr/art-capteur-de-force-5-kg-czl635-5-17599.htm
- Un amplificateur à pont de Wheatstone – convertisseur analogique/numérique SEN-13879 basé sur HX711 (librairies arduino adaptées, à peu près 10 euros aussi) : https://www.gotronic.fr/art-amplificateur-pour-capteur-de-force-sen-13879-25334.htm
Voici le montage à réaliser :
Pour éviter l’utilisation d’une breadboard supplémentaire, on utilise ici la sortie 3,3 V de l’Arduino pour VDD, ça ne semble pas poser de problème … Autre solution : utiliser une broche d’Arduino comme sortie 5 V (voir lignes commentées)
Comme première application, nous pourrions simplement « fabriquer » une balance avec mesure de masses (dispositif avec tige filetée et petit crochet adaptés à la jauge) :
Voici le code Arduino :
#include "HX711.h"
HX711 capteur;
int DAT = 3;
int CLK = 2;
long valeur;
float valeur2;
void setup() {
// pinMode(8,OUTPUT);
// digitalWrite(8,HIGH); // si on veut créer une alimentation 5V sur la broche 8 de la carte Arduino, pour la broche VDD de l'amplificateur
capteur.begin(DAT, CLK);
Serial.begin(9600);
while (!Serial) {
}
Serial.print("Capteur ");
Serial.println("HX711");
// tarage du capteur
Serial.println("Tarage du capteur");
Serial.println("Le capteur doit être fixé et ne pas être touché ou déplacé");
capteur.tare();
delay(1000);
}
void loop() {
valeur = capteur.get_value();
valeur2 = 0.00234*valeur -0.328 ;
Serial.print("Valeur mesurée (avec tare) : ");
Serial.print(valeur);
Serial.println ("\t");
Serial.println(valeur2);
delay(20);
}
Remarque
On pourrait étalonner la balance en réalisant des mesures avec une gamme de masses étalon.
A l’issue de ces résultats, il faudrait alors modifier la formule donnant la masse « réelle » :
valeur2 = 0.00234*valeur -0.328
Un code Python est aussi proposé ici pour récupérer les données et tracer une courbe.
Dans cet article , je ne rentrerai pas dans les détails pour les étapes de récupération de données. Pour cela, je vous invite à consulter l’article qui explique ces différentes étapes sur ce lien :
Récupération des données d’une carte Arduino avec Python
Voici le code Python pour récupérer les données et tracer le graphe en temps réel
#importation des modules
import serial
import serial.tools.list_ports # pour la communication avec le port série
import matplotlib.pyplot as plt # pour le tracé de graphe
from matplotlib import animation # pour la figure animée
import time # gestion du temps
#initialisation des listes
liste_temps_mesure =[] # liste pour stocker le temps"brut"
liste_temps=[] # liste pour stocker les valeurs de temps en partant de t=0
liste_masse = [] # liste pour stocker les valeurs de concentration
t_acquisition = 10.0
mmax= 500 # en g
mmin =-500
#pour le graphe en temps réel
def animate(i):
line1 = Data.readline()
print (line1)
# on retire les caractères d'espacement en début et fin de chaîne
listeDonnees = line1.strip()
# on sépare les informations reçues séparées par les espaces et on stocke ces informations dans une liste pour chacune de lignes
listeDonnees = line1.split()
print (listeDonnees)
if len(listeDonnees)== 1 : # parfois des lignes de données vides peuvent être envoyées, il faut les "écarter"
masse = float(listeDonnees[0].decode()) # après consulation des données, nous choisissons le 2ème élément de listeDonnees
tempsmes = time.time()
liste_temps_mesure.append(tempsmes) # temps mesuré "brut" stocké dans une liste
tempsreel = tempsmes - liste_temps_mesure[0] # pour faire partir le temps de 0 (cette valeur de temps sera stockée dans une autre liste : liste_temps)
while tempsreel <= t_acquisition:
liste_masse.append(masse)
print("m = %f"%(masse), " g") # affichage de la valeur de la concentration
liste_temps.append(tempsreel)
print("temps mesuré = %f"%(tempsmes), " s") # affichage de la valeur du temps absolu
print("temps réel= %f"%(tempsreel), " s") # affichage de la valeur du temps en partant de 0
line.set_data(liste_temps,liste_masse)
return line,
# Fonction pour la récupération des données série venant de la carte Arduino
def recup_port_Arduino() :
ports = list(serial.tools.list_ports.comports())
for p in ports:
if 'Arduino' in p.description :
mData = serial.Serial(p.device,9600)
print(mData.is_open) # Affiche et vérifie que le port est ouvert
print(mData.name) # Affiche le nom du port
return mData
Data =recup_port_Arduino() #récupération des données
# Création figure
fig=plt.figure()
line, = plt.plot([],[])
plt.xlim(0, t_acquisition)
plt.ylim(mmin,mmax)
plt.xlabel('temps en s')
plt.ylabel('masse en g')
plt.grid()
#Animation
ani = animation.FuncAnimation(fig, animate, frames=2000, interval=20,repeat=False)
plt.show()
plt.close(fig)
Data.close() # pour arrêter la lecture des données série
#Ecriture dans un fichier txt
lines=['t\tm\n'] #première ligne du fichier txt
for i in range (len (liste_masse)):
line = str(liste_temps[i]) +'\t'+ str(liste_masse[i])+'\n'
lines.append(line)
fichier = open('U:\Documents\\data_arduino.txt', 'w')
fichier.writelines(lines) #création d'un nouveau fichier texte
Attention
Attendre quelques secondes au début de l’acquisition pour que le capteur procède au tarage.
Lien Github avec les scripts :
https://github.com/jonasforlot/python-arduino/tree/main/Donn%C3%A9es%20s%C3%A9rie%20jauge
Il s’agit pour l’instant d’une application simple d’utilisation de ce capteur, l’article est susceptible d’évoluer avec des améliorations et des compléments : procédure d’étalonnage, tests de traction …