ACTIVITE ARDUINO/PYTHON : Utilisation d’un capteur de force avec Arduino, tracé de graphe dans Python

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 :

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.

Tracé sans/avec masse de 100 g

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

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *