{"id":1419,"date":"2024-09-10T06:09:35","date_gmt":"2024-09-10T04:09:35","guid":{"rendered":"https:\/\/labopothier.com\/?p=1419"},"modified":"2025-09-26T08:54:07","modified_gmt":"2025-09-26T06:54:07","slug":"activite-arduino-python-recuperer-avec-python-les-donnees-dune-carte-arduino-avec-trace-de-graphes-exemple-avec-une-mesure-de-distance-par-ultrason","status":"publish","type":"post","link":"https:\/\/labopothier.com\/index.php\/2024\/09\/10\/activite-arduino-python-recuperer-avec-python-les-donnees-dune-carte-arduino-avec-trace-de-graphes-exemple-avec-une-mesure-de-distance-par-ultrason\/","title":{"rendered":"ACTIVITE ARDUINO\/PYTHON : R\u00e9cup\u00e9rer avec Python les donn\u00e9es d&rsquo;une carte Arduino (avec trac\u00e9 de graphes). Exemple avec une mesure de distance par ultrason."},"content":{"rendered":"\n<p><\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large\"><a href=\"https:\/\/www.youtube.com\/watch?v=_YB-D7cH9pI&amp;t=3s\"><img decoding=\"async\" src=\"https:\/\/labopothier.com\/wp-content\/uploads\/2021\/03\/Arduino-US-1024x576-1.jpg\" alt=\"\" class=\"wp-image-797\"\/><\/a><\/figure>\n\n\n\n<p><strong>Objectif de cette activit\u00e9 :<\/strong> R\u00e9cup\u00e9rer dans Python les donn\u00e9es du moniteur s\u00e9rie d&rsquo;un programme Arduino en utilisant simplement la biblioth\u00e8que <strong>serial<\/strong>. <\/p>\n\n\n\n<p><strong>Pr\u00e9-requis : <\/strong> \u00eatre familier avec le langage Python &#8230; et \u00e9ventuellement avoir des bases en programmation pour les microcontr\u00f4leurs Arduino (mais pas obligatoire car on peut partir d&rsquo;une carte Arduino d\u00e9j\u00e0 programm\u00e9e avec un code inconnu et s&rsquo;en sortir quand m\u00eame !)<\/p>\n\n\n\n<p>Pour l&rsquo;initiation au langage Python , je vous invite \u00e0 consulter cet article :<a href=\" https:\/\/labopothier.com\/index.php\/2020\/04\/21\/initiation-au-langage-python\"> Initiation au langage Python<\/a><\/p>\n\n\n\n<p>D\u00e9couverte des microcontr\u00f4leurs et du langage Arduino disponible dans cet article : <a href=\"https:\/\/labopothier.com\/index.php\/2020\/12\/02\/decouverte-des-microcontroleurs-et-du-langage-arduino\/\">D\u00e9couverte des microcontr\u00f4leurs et du langage Arduino<\/a><\/p>\n\n\n\n<p>V\u00e9rifier que la biblioth\u00e8que <strong>serial <\/strong>est install\u00e9e en \u00e9crivant dans le shell (interpr\u00e9teur)<strong> import pyserial<\/strong>. Si un message d&rsquo;erreur appara\u00eet, installer <strong>serial <\/strong>en \u00e9crivant dans le shell :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"python\" class=\"language-python\">pip install pyserial<\/code><\/pre>\n\n\n\n<p>Nous allons partir du montage suivant (vu d\u00e9j\u00e0 dans l&rsquo;activit\u00e9<a href=\" https:\/\/labopothier.com\/index.php\/2020\/04\/10\/activite-arduino-ultrason-radar-de-recul-avec-codes-arduino-et-codes-python-equivalent\/\"> Radar de recul<\/a>). <\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>Le trac\u00e9 d&rsquo;un graphique n&rsquo;a peut-\u00eatre pas grand int\u00e9r\u00eat avec ce montage mais le but de cet article est juste de montrer comment r\u00e9cup\u00e9rer les donn\u00e9es, nous verrons dans d&rsquo;autres articles des exemples plus pertinents : trac\u00e9 de caract\u00e9ristique d&rsquo;une photodiode avec r\u00e9gression lin\u00e9aire, r\u00e9cup\u00e9ration de donn\u00e9es pour d&rsquo;autres types d&rsquo;interfaces USB (par exemple acquisition temporelle d&rsquo;une masse avec une balance&#8230;)<\/p>\n<\/blockquote>\n\n\n\n<p><\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>MONTAGE ULTRASON AVEC CODE ARDUINO radar de recul  avec alertes LED couleurs diff\u00e9rentes selon distance<\/strong><\/h4>\n\n\n\n<p><strong>Rappel du montage<\/strong>: Faire clignoter des LED de couleurs diff\u00e9rentes (rouge, orange, verte) selon la position de l\u2019obstacle par rapport au capteur US. On utilise des r\u00e9sistances de protection de 220 \u03a9.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Zone verte : entre 30 cm et 50 cm<\/li>\n\n\n\n<li>Zone orange : entre 10 cm et 30 cm<\/li>\n\n\n\n<li>Zone rouge : moins de 10 cm<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"398\" src=\"https:\/\/labopothier.com\/wp-content\/uploads\/2020\/04\/radar2-1024x398-1.png\" alt=\"\" class=\"wp-image-987\" srcset=\"https:\/\/labopothier.com\/wp-content\/uploads\/2020\/04\/radar2-1024x398-1.png 1024w, https:\/\/labopothier.com\/wp-content\/uploads\/2020\/04\/radar2-1024x398-1-300x117.png 300w, https:\/\/labopothier.com\/wp-content\/uploads\/2020\/04\/radar2-1024x398-1-768x299.png 768w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p><strong>Bonus<\/strong> : on fait clignoter les LED plus rapidement quand l\u2019obstacle se rapproche !<\/p>\n\n\n\n<p>Voici le code <strong>Arduino <\/strong>t\u00e9l\u00e9vers\u00e9 dans la carte :<\/p>\n\n\n\n<pre title=\"Avec le langage Arduino\" class=\"wp-block-code\"><code lang=\"cpp\" class=\"language-cpp line-numbers\">\/* Constantes pour les broches *\/\nconst byte TRIGGER_PIN = 13; \/\/ Broche TRIGGER\nconst byte ECHO_PIN = 12;    \/\/ Broche ECHO\nconst byte LED_verte = 8; \/\/ broches pour les LED \nconst byte LED_orange = 9;\nconst byte LED_rouge = 10;\nunsigned long temps;\n\n\n \n\/* Constantes pour le timeout *\/\nconst unsigned long MEASURE_TIMEOUT = 25000UL; \/\/ 25ms = ~8m \u00e0 340m\/s, temps limite pour la mesure de distance\n\n\/* Vitesse du son dans l'air en mm\/us *\/\nconst float SOUND_SPEED = 340.0 \/ 1000;\n\n\/** Fonction setup() *\/\nvoid setup() {\n   \n  \/* Initialise le port s\u00e9rie *\/\n  Serial.begin(9600);\n   \n  \/* Initialise les broches *\/\n  pinMode(TRIGGER_PIN, OUTPUT);\n  digitalWrite(TRIGGER_PIN, LOW); \/\/ La broche TRIGGER doit \u00eatre \u00e0 LOW au repos\n  pinMode(ECHO_PIN, INPUT);\n  pinMode (LED_verte, OUTPUT); \/\/ On d\u00e9clare les broches des LED et buzzer comme sorties\n  pinMode (LED_orange, OUTPUT);\n  pinMode (LED_rouge, OUTPUT);\n\/\/  \n}\n \n\/** Fonction loop() *\/\nvoid loop() {\n  temps = millis();\n  \/* 1. Lance une mesure de distance en envoyant une impulsion HIGH de 10\u00b5s sur la broche TRIGGER *\/\n  digitalWrite(TRIGGER_PIN, HIGH);\n  delayMicroseconds(10);\n  digitalWrite(TRIGGER_PIN, LOW);\n  \n  \/* 2. Mesure le temps en us entre l'envoi de l'impulsion ultrasonique et son \u00e9cho (si il existe) *\/\n  long measure = pulseIn(ECHO_PIN, HIGH, MEASURE_TIMEOUT);\n  \/* REMARQUE. , si aucune mesure n'appara\u00eet, d\u00e9sactiver le timeout, en d\u00e9sactivant la ligne pr\u00e9c\u00e9dente et en activant celle ci :*\/\n   \/\/long measure = pulseIn(ECHO_PIN, HIGH); \n   \n  \/* 3. Calcul de la distance \u00e0 partir du temps mesur\u00e9 *\/\n  float distance_mm = measure \/ 2.0 * SOUND_SPEED;\n  \n \/\/ zone pour laquelle la LED verte clignote \nif ((distance_mm &lt; 500.0)and (distance_mm > 300.0)) {\ndigitalWrite (LED_verte, HIGH); \/\/la LED s'allume pendant 1 s et s'\u00e9teint pendant 0,5 s\ndelay(1000);\ndigitalWrite (LED_verte,LOW);\ndelay (500);\n }\n \n\/\/zone pour laquelle la LED orange clignote \nif ((distance_mm &lt; 300.0) and (distance_mm > 100.0)) { \/\/la LED s'allume pendant 0,5 s et s'\u00e9teint pendant 0,25 s\ndigitalWrite (LED_orange, HIGH); \ndelay(500);\ndigitalWrite (LED_orange,LOW);\ndelay (250);\n}\n\n\/\/zone pour laquelle la LED rouge clignote\n if (distance_mm &lt; 100.0) { \/\/la LED s'allume pendant 0,1 s et s'\u00e9teint pendant 0,05 s\ndigitalWrite (LED_rouge, HIGH); \ndelay(100);\ndigitalWrite (LED_rouge,LOW);\ndelay (50);\n\n }\n\n\/\/ sinon il ne se passe rien ... \nelse {\n  digitalWrite (LED_verte,LOW);\n  digitalWrite (LED_orange,LOW);\n  digitalWrite (LED_rouge,LOW);\n  delay (50);\n  \n}\n    \n  \n  \/* Affiche le temps en ms et les r\u00e9sultats en mm, on simplifie le code pour r\u00e9cup\u00e9rer seulement les valeurs*\/\n\/\/  Serial.print(\"temps en ms : \");\n  Serial.print(temps);\n  Serial.print(\"\\t\");\n\/\/  Serial.print(\"distance en mm : \");\n  Serial.println(distance_mm);\n\/\/  Serial.println(\" mm, \");\n\n\/\/   \n  \/* D\u00e9lai d'attente pour \u00e9viter d'afficher trop de r\u00e9sultats \u00e0 la seconde *\/\n  delay(50);\n}<\/code><\/pre>\n\n\n\n<p>Voil\u00e0 ce qui s&rsquo;affiche dans le moniteur s\u00e9rie d&rsquo;Arduino :<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p><strong>Remarque :<\/strong><\/p>\n\n\n\n<p> Il semblerait que depuis quelques temps, le TIMEOUT emp\u00eache la mesure de se faire. Dans ce cas il faudrait d\u00e9sactiver ce timeout en rempla\u00e7ant la ligne :<\/p>\n\n\n\n<p><code><code data-enlighter-language=\"generic\" class=\"EnlighterJSRAW\">  long measure = pulseIn(ECHO_PIN, HIGH, MEASURE_TIMEOUT);<\/code><\/code><\/p>\n\n\n\n<p>par :<\/p>\n\n\n\n<p><code data-enlighter-language=\"generic\" class=\"EnlighterJSRAW\">  long measure = pulseIn(ECHO_PIN, HIGH);<br><\/code><\/p>\n<\/blockquote>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"328\" src=\"https:\/\/labopothier.com\/wp-content\/uploads\/2024\/09\/Sans-titre-4-1024x328.png\" alt=\"\" class=\"wp-image-1764\" srcset=\"https:\/\/labopothier.com\/wp-content\/uploads\/2024\/09\/Sans-titre-4-1024x328.png 1024w, https:\/\/labopothier.com\/wp-content\/uploads\/2024\/09\/Sans-titre-4-300x96.png 300w, https:\/\/labopothier.com\/wp-content\/uploads\/2024\/09\/Sans-titre-4-768x246.png 768w, https:\/\/labopothier.com\/wp-content\/uploads\/2024\/09\/Sans-titre-4.png 1168w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>On souhaiterait r\u00e9cup\u00e9rer ces donn\u00e9es dans Python pour tracer un graphe, r\u00e9cup\u00e9rer ces valeurs dans un fichier txt, &#8230;<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Etape 1 : Acqusition temporelle<\/strong><\/h2>\n\n\n\n<p>Pour la communication avec la liaison s\u00e9rie de la carte Arduino (via le c\u00e2ble USB), il faut importer la biblioth\u00e8que <strong>serial <\/strong>en \u00e9crivant ces deux lignes :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"python\" class=\"language-python\">#Importation des modules\nimport serial\nimport serial.tools.list_ports   # pour la communication avec le port s\u00e9rie<\/code><\/pre>\n\n\n\n<p>On initialise la liste pour les mesures de distances :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"python\" class=\"language-python\">#initialisation des listes\nliste_temps=[] # liste pour stocker les valeurs de temps en s\nliste_distance = [] # liste pour stocker la distance en mm<\/code><\/pre>\n\n\n\n<p>On d\u00e9finit une fonction qui permet \u00e0 la fois :<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>de d\u00e9tecter <strong>automatiquement <\/strong>le port s\u00e9rie utilis\u00e9 par la carte Arduino <\/li>\n\n\n\n<li>de se <strong>connecter <\/strong>\u00e0 la carte<\/li>\n\n\n\n<li>de <strong>r\u00e9cup\u00e9rer <\/strong>les donn\u00e9es s\u00e9rie venant de la carte<\/li>\n<\/ul>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"python\" class=\"language-python\"># Fonction pour la r\u00e9cup\u00e9ration des donn\u00e9es s\u00e9rie venant du port USB\ndef recup_port_Arduino() :\n    ports = list(serial.tools.list_ports.comports())\n    for p in ports:\n        if 'Arduino' in p.description :\n        # if 'CDC' in p.description :    #pour les utilisateurs de mac\n            mData = serial.Serial(p.device,9600)\n    print(mData.is_open) # Affiche et v\u00e9rifie que le port est ouvert\n    print(mData.name) # Affiche le nom du port\n    return mData\n<\/code><\/pre>\n\n\n\n<p><strong>Remarque <\/strong>: cette fonction a \u00e9t\u00e9 \u00e9crite ici de la mani\u00e8re la plus basique possible, on pourrait rajouter des lignes de code suppl\u00e9mentaires pour g\u00e9rer les exceptions (pas de carte Arduino d\u00e9tect\u00e9, choisir entre plusieurs cartes Arduino connect\u00e9es en m\u00eame temps &#8230;)<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p><strong>Note pour les utilisateurs de MAC<\/strong><\/p>\n\n\n\n<p>Il semblerait que le mot \u00ab\u00a0Arduino\u00a0\u00bb n&rsquo;apparaisse pas dans les descriptions de port. Pour la reconnaissance de carte, remplacer la ligne <\/p>\n\n\n\n<p><strong>if  \u00ab\u00a0Arduino\u00a0\u00bb in p.descripton : <\/strong>     par     <strong>if \u00ab\u00a0CDC\u00a0\u00bbin p.description :<\/strong><\/p>\n\n\n\n<p><\/p>\n<\/blockquote>\n\n\n\n<p>Ensuite on fait appel \u00e0 cette fonction pour r\u00e9cup\u00e9rer les donn\u00e9es :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"python\" class=\"language-python\">Data = recup_port_Arduino()<\/code><\/pre>\n\n\n\n<p>Pour lire une ligne de donn\u00e9es, il faut utiliser la m\u00e9thode <strong>.readline()<\/strong> pour r\u00e9cup\u00e9rer chaque ligne sous forme de cha\u00eene de caract\u00e8res.<\/p>\n\n\n\n<p>La m\u00e9thode<strong> .strip()<\/strong> permettra de supprimer les caract\u00e8res d&rsquo;espacement et de tabulation en d\u00e9but et fin de cha\u00eene. <\/p>\n\n\n\n<p>On utilisera aussi la m\u00e9thode <strong>.split()<\/strong> pour s\u00e9parer les diff\u00e9rentes informations de la ligne pour les stocker dans une liste.<\/p>\n\n\n\n<p>On essaie pour l&rsquo;instant d&rsquo;afficher une seule ligne (en utilisant <strong>.readline()<\/strong>) et la liste correspondante (avec les m\u00e9thode <strong>.strip()<\/strong> et <strong>.split()<\/strong>) :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"python\" class=\"language-python\">line1 = Data.readline() \nprint (line1)\ndonnee=line1.strip().split()\nprint (donnee)<\/code><\/pre>\n\n\n\n<p>Le r\u00e9sultat se pr\u00e9sente de la fa\u00e7on suivante :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"python\" class=\"language-python\">b'0\\t64.60\\r\\n'\n[b'0', b'64.60']<\/code><\/pre>\n\n\n\n<p>La premi\u00e8re ligne est la cha\u00eene de caract\u00e8res r\u00e9cup\u00e9r\u00e9e, et la deuxi\u00e8me ligne est la liste que nous avons cr\u00e9\u00e9e avec les diff\u00e9rents \u00e9l\u00e9ments de cette cha\u00eene. Les informations qui nous int\u00e9ressent (valeurs de temps et de distance).  Le temps est donc est le premier \u00e9l\u00e9ment de la liste &#8230; donc d&rsquo;indice 0;  la distance est donc le 2\u00e8me \u00e9l\u00e9ment de la liste &#8230; donc d&rsquo;indice 1 &#8230; et oui rappelez-vous : l&rsquo;indice du premier \u00e9l\u00e9ment d&rsquo;une liste est <strong>0<\/strong> !<\/p>\n\n\n\n<p><\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p><strong><em>Mais que veulent dire tous ces b devant les chaines de caract\u00e8res ?<\/em><\/strong><\/p>\n\n\n\n<p>Ces donn\u00e9es ne sont pas vraiment des cha\u00eenes de caract\u00e8res mais des donn\u00e9es de type<strong> bytes<\/strong> (s\u00e9quences d&rsquo;octet). il faudra donc les d\u00e9coder (avec la m\u00e9thode<strong> .decode()<\/strong>) et \u00e9ventuellement les convertir en <strong>float <\/strong>si on a besoin de faire des calculs.<\/p>\n<\/blockquote>\n\n\n\n<p>On d\u00e9finit un temps d&rsquo;acquisition :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"python\" class=\"language-python\">t_acquisition = 5.0<\/code><\/pre>\n\n\n\n<p>On cr\u00e9e une boucle qui doit s&rsquo;arr\u00eater \u00e0 la fin du temps d&rsquo;acquisition :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"python\" class=\"language-python\">Data =recup_port_Arduino()\n\n# Acquition temporelle\ntemps=0\nwhile temps &lt;= t_acquisition:\n    line1 = Data.readline()\n    print (line1)\n    #on retire les caract\u00e8res d'espacement en d\u00e9but et fin de cha\u00eene\n    listeDonnees = line1.strip()\n    # on s\u00e9pare les informations re\u00e7ues s\u00e9par\u00e9es par les espaces et on stocke ces informations dans une liste pour chacune de lignes\n    listeDonnees = line1.split()\n    print (listeDonnees)\n\n    if len(listeDonnees)== 2: # parfois des lignes de donn\u00e9es vides peuvent \u00eatre envoy\u00e9es, il faut les \"\u00e9carter\"\n        temps = float(listeDonnees[0].decode())\/1000.0 # apr\u00e8s consultation des donn\u00e9es, nous choisissons le 1er \u00e9l\u00e9ment de listeDonnees, conversion en secondes\n        distance = float(listeDonnees[1].decode()) # apr\u00e8s consultation des donn\u00e9es, nous choisissons le 2\u00e8me \u00e9l\u00e9ment de listeDonnees\n        liste_temps.append(temps)\n        liste_distance.append(distance)\n        print(\"temps = %f\"%(temps), \" s\") # affichage de la valeur du temps en partant de 0\n        print(\"d = %f\"%(distance), \" mm\") # affichage de la valeur de la distance en mm\n\n\nData.close()<\/code><\/pre>\n\n\n\n<p>Quelques lignes de code suppl\u00e9mentaires pour enregistrer ces informations dans un fichier texte de format<strong> .txt<\/strong>. Cela peut \u00eatre utile pour l&rsquo;importation de ces donn\u00e9es dans des logiciels ou tableurs (Latis pro, Regressi, Excel, Libre Office ,&#8230;). Le chemin est d\u00e9fini par d\u00e9faut dans le dossier o\u00f9 se trouve le fichier python mais il est possible de d\u00e9finir d&rsquo;autres chemins:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"python\" class=\"language-python\"># Ecriture dans un fichier txt\nlines = ['t\\td\\n']  # premi\u00e8re ligne du fichier txt\nfor i in range(len(liste_temps)):\n    line = str(liste_temps[i]) +'\\t'+str(liste_distance[i]) + '\\n'\n    lines.append(line)\n\n# Utilisation de 'with open' pour assurer la fermeture du fichier\nwith open('data_arduino.txt', 'w', encoding='utf-8') as fichier:\n    fichier.writelines(lines)  # cr\u00e9ation d'un nouveau fichier texte<\/code><\/pre>\n\n\n\n<p><strong>Le code complet pour ce programme d&rsquo;acquisition temporelle :<\/strong><\/p>\n\n\n\n<pre title=\"R\u00e9cup\u00e9ration de donn\u00e9es s\u00e9rie d'une carte Arduino (mesure de distance avec module ultrason)\" class=\"wp-block-code\"><code lang=\"python\" class=\"language-python\">#Importation des modules\nimport serial\nimport serial.tools.list_ports   # pour la communication avec le port s\u00e9rie\n\n\n\n#initialisation des listes\nliste_temps=[] # liste pour stocker les valeurs de temps en s\nliste_distance = [] # liste pour stocker la distance en mm\n\nt_acquisition = 5.0\n\n\n# Fonction pour la r\u00e9cup\u00e9ration des donn\u00e9es s\u00e9rie venant du port USB\ndef recup_port_Arduino() :\n    ports = list(serial.tools.list_ports.comports())\n    for p in ports:\n        if 'Arduino' in p.description :\n        # if 'CDC' in p.description :    #pour les utilisateurs de mac\n            mData = serial.Serial(p.device,9600)\n    print(mData.is_open) # Affiche et v\u00e9rifie que le port est ouvert\n    print(mData.name) # Affiche le nom du port\n    return mData\n\nData =recup_port_Arduino()\n\n# Acquition temporelle\ntemps=0\nwhile temps &lt;= t_acquisition:\n    line1 = Data.readline()\n    print (line1)\n    #on retire les caract\u00e8res d'espacement en d\u00e9but et fin de cha\u00eene\n    listeDonnees = line1.strip()\n    # on s\u00e9pare les informations re\u00e7ues s\u00e9par\u00e9es par les espaces et on stocke ces informations dans une liste pour chacune de lignes\n    listeDonnees = line1.split()\n    print (listeDonnees)\n\n    if len(listeDonnees)== 2: # parfois des lignes de donn\u00e9es vides peuvent \u00eatre envoy\u00e9es, il faut les \"\u00e9carter\"\n        temps = float(listeDonnees[0].decode())\/1000.0 # apr\u00e8s consultation des donn\u00e9es, nous choisissons le 1er \u00e9l\u00e9ment de listeDonnees, conversion en secondes\n        distance = float(listeDonnees[1].decode()) # apr\u00e8s consultation des donn\u00e9es, nous choisissons le 2\u00e8me \u00e9l\u00e9ment de listeDonnees\n        liste_temps.append(temps)\n        liste_distance.append(distance)\n        print(\"temps = %f\"%(temps), \" s\") # affichage de la valeur du temps en partant de 0\n        print(\"d = %f\"%(distance), \" mm\") # affichage de la valeur de la distance en mm\n\n\nData.close()\n\n# Ecriture dans un fichier txt\nlines = ['t\\td\\n']  # premi\u00e8re ligne du fichier txt\nfor i in range(len(liste_temps)):\n    line = str(liste_temps[i]) +'\\t'+str(liste_distance[i]) + '\\n'\n    lines.append(line)\n\n# Utilisation de 'with open' pour assurer la fermeture du fichier\nwith open('data_arduino.txt', 'w', encoding='utf-8') as fichier:\n    fichier.writelines(lines)  # cr\u00e9ation d'un nouveau fichier texte\n\n<\/code><\/pre>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p><strong>Astuce  :  parfois un message d&rsquo;erreur appara\u00eet (probl\u00e8me de communication avec la carte, donn\u00e9es re\u00e7ues incompl\u00e8tes &#8230;), comment r\u00e9soudre ce probl\u00e8me ?<\/strong><\/p>\n\n\n\n<p>La plupart du temps, il suffit de red\u00e9marrer le shell (CTRL+K) et relancer ensuite le programme.<\/p>\n\n\n\n<p><\/p>\n<\/blockquote>\n\n\n\n<p><strong>Le code complet pour ce programme d&rsquo;acquisition temporelle :<\/strong><\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Etape 2 : trac\u00e9 de graphe (statique ou dynamique)<\/strong><\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Graphe statique (qui sera affich\u00e9 en fin d&rsquo;acquisition)<\/h3>\n\n\n\n<p>Pour tracer un graphe, il faut au pr\u00e9alable importer la biblioth\u00e8que matplotlib de la mani\u00e8re suivante :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"python\" class=\"language-python\">import matplotlib.pyplot as plt  # pour le trac\u00e9 de graphe<\/code><\/pre>\n\n\n\n<p>Il suffit de taper ces quelques lignes de code pour afficher le graphe avec les valeurs stock\u00e9es dans les listes :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"python\" class=\"language-python\">plt.title('d=f(t)') # titre du graphique\nplt.plot(liste_temps,liste_distance, color ='r', marker = 'o') # On affiche les points de coordonn\u00e9es (I,U) avec des points rouges\nplt.xlim (min(liste_temps),max(liste_temps))  #limtes pour les axes avec les valeurs extr\u00eames de I et de U\nplt.ylim(min(liste_distance),max(liste_distance))\nplt.xlabel('temps en s')\nplt.ylabel('distance en mm')\nplt.show()<\/code><\/pre>\n\n\n\n<p><strong>Le code complet pour le trac\u00e9 de graphe statique :<\/strong><\/p>\n\n\n\n<pre title=\"Trac\u00e9 de graphe statique (acquisition temporelle de mesures de distances avec une carte Arduino)\" class=\"wp-block-code\"><code lang=\"python\" class=\"language-python\">#importation des modules\nimport serial\nimport serial.tools.list_ports # pour la communication avec le port s\u00e9rie\nimport matplotlib.pyplot as plt  # pour le trac\u00e9 de graphe\nimport time # gestion du temps\n\n\n\n#initialisation des listes\nliste_temps=[] # liste pour stocker les valeurs de temps en partant de t=0\nliste_distance = [] # liste pour stocker la distance en mm\n\nt_acquisition = 5.0\n\n\n# Fonction pour la r\u00e9cup\u00e9ration des donn\u00e9es s\u00e9rie venant du port USB\ndef recup_port_Arduino() :\n    ports = list(serial.tools.list_ports.comports())\n    for p in ports:\n        if 'Arduino' in p.description :\n        # if 'CDC' in p.description :    #pour les utilisateurs de mac\n            mData = serial.Serial(p.device,9600)\n    print(mData.is_open) # Affiche et v\u00e9rifie que le port est ouvert\n    print(mData.name) # Affiche le nom du port\n    return mData\n\nData =recup_port_Arduino()\n\n# Acquisition\ntemps=0\nwhile temps &lt;= t_acquisition:\n    line1 = Data.readline()\n    print (line1)\n    #on retire les caract\u00e8res d'espacement en d\u00e9but et fin de cha\u00eene\n    listeDonnees = line1.strip()\n    # on s\u00e9pare les informations re\u00e7ues s\u00e9par\u00e9es par les espaces et on stocke ces informations dans une liste pour chacune de lignes\n    listeDonnees = line1.split()\n    print (listeDonnees)\n\n    if len(listeDonnees)== 2: # parfois des lignes de donn\u00e9es vides peuvent \u00eatre envoy\u00e9es, il faut les \"\u00e9carter\"\n        temps = float(listeDonnees[0].decode())\/1000.0 # apr\u00e8s consultation des donn\u00e9es, nous choisissons le 1er \u00e9l\u00e9ment de listeDonnees, conversion en secondes\n        distance = float(listeDonnees[1].decode()) # apr\u00e8s consultation des donn\u00e9es, nous choisissons le 2\u00e8me \u00e9l\u00e9ment de listeDonnees\n        liste_temps.append(temps)\n        liste_distance.append(distance)\n        print(\"temps = %f\"%(temps), \" s\") # affichage de la valeur du temps en partant de 0\n        print(\"d = %f\"%(distance), \" mm\") # affichage de la valeur de la distance en mm\n\n\nData.close()\n\nplt.title('d=f(t)') # titre du graphique\nplt.plot(liste_temps,liste_distance, color ='r', marker = 'o') # On affiche les points de coordonn\u00e9es (I,U) avec des points rouges\nplt.xlim (min(liste_temps),max(liste_temps))  #limtes pour les axes avec les valeurs extr\u00eames de I et de U\nplt.ylim(min(liste_distance),max(liste_distance))\nplt.xlabel('temps en s')\nplt.ylabel('distance en mm')\nplt.show()\n\n# Ecriture dans un fichier txt\nlines = ['t\\td\\n']  # premi\u00e8re ligne du fichier txt\nfor i in range(len(liste_temps)):\n    line = str(liste_temps[i]) +'\\t'+str(liste_distance[i]) + '\\n'\n    lines.append(line)\n\n# Utilisation de 'with open' pour assurer la fermeture du fichier\nwith open('data_arduino.txt', 'w', encoding='utf-8') as fichier:\n    fichier.writelines(lines)  # cr\u00e9ation d'un nouveau fichier texte\n\n<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"619\" height=\"533\" src=\"https:\/\/labopothier.com\/wp-content\/uploads\/2021\/02\/Sans-titre-1.png\" alt=\"\" class=\"wp-image-576\" srcset=\"https:\/\/labopothier.com\/wp-content\/uploads\/2021\/02\/Sans-titre-1.png 619w, https:\/\/labopothier.com\/wp-content\/uploads\/2021\/02\/Sans-titre-1-300x258.png 300w\" sizes=\"auto, (max-width: 619px) 100vw, 619px\" \/><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Trac\u00e9 de graphe en temps r\u00e9el (avec la fonction animate)<\/h3>\n\n\n\n<p>Pour tracer un graphe \u00ab\u00a0anim\u00e9\u00a0\u00bb en temps r\u00e9el, il faut importer les modules suivants :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"python\" class=\"language-python\">import matplotlib.pyplot as plt  # pour le trac\u00e9 de graphe\nfrom matplotlib import animation # pour la figure anim\u00e9e<\/code><\/pre>\n\n\n\n<p>On d\u00e9finit un temps d&rsquo;acquisition et une distance maximale pour l&rsquo;\u00e9chelle du graphe :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"python\" class=\"language-python\">t_acquisition = 6.0\ndistancemax= 500 # en mm<\/code><\/pre>\n\n\n\n<p>Nous allons inclure les instructions de la boucle dans une fonction nomm\u00e9e<strong> animate(i)<\/strong> :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"python\" class=\"language-python\">#pour le graphe en temps r\u00e9el\ndef animate(i):\n    line1 = Data.readline()\n    print (line1)\n    # on retire les caract\u00e8res d'espacement en d\u00e9but et fin de cha\u00eene\n    listeDonnees = line1.strip()\n    # on s\u00e9pare les informations re\u00e7ues s\u00e9par\u00e9es par les espaces et on stocke ces informations dans une liste pour chacune de lignes\n    listeDonnees = line1.split()\n    print (listeDonnees)\n\n\n    if len(listeDonnees)== 2 : # parfois des lignes de donn\u00e9es vides peuvent \u00eatre envoy\u00e9es, il faut les \"\u00e9carter\"\n        temps = float(listeDonnees[0].decode())\/1000.0 # apr\u00e8s consultation des donn\u00e9es, nous choisissons le 1er \u00e9l\u00e9ment de listeDonnees, conversion en secondes\n        distance = float(listeDonnees[1].decode()) # apr\u00e8s consultation des donn\u00e9es, nous choisissons le 2\u00e8me \u00e9l\u00e9ment de listeDonnees\n\n        while temps &lt;= t_acquisition:\n            liste_temps.append(temps)\n            liste_distance.append(distance)\n            print(\"temps = %f\"%(temps), \" s\") # affichage de la valeur du temps en partant de 0\n            print(\"d = %f\"%(distance), \" mm\") # affichage de la valeur de la distance en mm\n            line.set_data(liste_temps,liste_distance)\n            return line,\n<\/code><\/pre>\n\n\n\n<p>Puis on r\u00e9cup\u00e8re les donn\u00e9es et on fait afficher la figure anim\u00e9e avec<strong> animation.FuncAnimation<\/strong> :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"python\" class=\"language-python\">Data =recup_port_Arduino() #r\u00e9cup\u00e9ration des donn\u00e9es\n\n# Cr\u00e9ation figure\nfig=plt.figure()\nline, = plt.plot([],[])\nplt.xlim(0, t_acquisition)\nplt.ylim(0,distancemax)\nplt.xlabel('temps en s')\nplt.ylabel('distance en mm')\nplt.grid()\n\n\n#Animation\nani = animation.FuncAnimation(fig, animate, frames=200,  interval=20,repeat=False)\n\nplt.show()\n\nplt.close(fig)\nData.close() # pour arr\u00eater la lecture des donn\u00e9es s\u00e9rie<\/code><\/pre>\n\n\n\n<p><strong>Le code complet pour le trac\u00e9 de graphe  en temps r\u00e9el :<\/strong><\/p>\n\n\n\n<pre title=\"Trac\u00e9 de graphe en temps r\u00e9el (acquisition temporelle de mesures de distances avec une carte Arduino)\" class=\"wp-block-code\"><code lang=\"python\" class=\"language-python\">#importation des modules\nimport serial\nimport serial.tools.list_ports # pour la communication avec le port s\u00e9rie\nimport matplotlib.pyplot as plt  # pour le trac\u00e9 de graphe\nfrom matplotlib import animation # pour la figure anim\u00e9e\n\n\n#initialisation des listes\nliste_temps=[] # liste pour stocker les valeurs de temps en partant de t=0\nliste_distance = [] # liste pour stocker la distance en mm\n\nt_acquisition = 6.0\ndistancemax= 500 # en mm\n\n\n#pour le graphe en temps r\u00e9el\ndef animate(i):\n    line1 = Data.readline()\n    print (line1)\n    # on retire les caract\u00e8res d'espacement en d\u00e9but et fin de cha\u00eene\n    listeDonnees = line1.strip()\n    # on s\u00e9pare les informations re\u00e7ues s\u00e9par\u00e9es par les espaces et on stocke ces informations dans une liste pour chacune de lignes\n    listeDonnees = line1.split()\n    print (listeDonnees)\n\n\n    if len(listeDonnees)== 2 : # parfois des lignes de donn\u00e9es vides peuvent \u00eatre envoy\u00e9es, il faut les \"\u00e9carter\"\n        temps = float(listeDonnees[0].decode())\/1000.0 # apr\u00e8s consultation des donn\u00e9es, nous choisissons le 1er \u00e9l\u00e9ment de listeDonnees, conversion en secondes\n        distance = float(listeDonnees[1].decode()) # apr\u00e8s consultation des donn\u00e9es, nous choisissons le 2\u00e8me \u00e9l\u00e9ment de listeDonnees\n\n        while temps &lt;= t_acquisition:\n            liste_temps.append(temps)\n            liste_distance.append(distance)\n            print(\"temps = %f\"%(temps), \" s\") # affichage de la valeur du temps en partant de 0\n            print(\"d = %f\"%(distance), \" mm\") # affichage de la valeur de la distance en mm\n            line.set_data(liste_temps,liste_distance)\n            return line,\n\n\n\n\n\n\n# Fonction pour la r\u00e9cup\u00e9ration des donn\u00e9es s\u00e9rie venant de la carte Arduino\ndef recup_port_Arduino() :\n    ports = list(serial.tools.list_ports.comports())\n    for p in ports:\n        if 'Arduino' in p.description :\n        # if 'CDC' in p.description :    #pour les utilisateurs de mac\n            mData = serial.Serial(p.device,9600)\n    print(mData.is_open) # Affiche et v\u00e9rifie que le port est ouvert\n    print(mData.name) # Affiche le nom du port\n    return mData\n\n\n\n\n\n\nData =recup_port_Arduino() #r\u00e9cup\u00e9ration des donn\u00e9es\n\n# Cr\u00e9ation figure\nfig=plt.figure()\nline, = plt.plot([],[])\nplt.xlim(0, t_acquisition)\nplt.ylim(0,distancemax)\nplt.xlabel('temps en s')\nplt.ylabel('distance en mm')\nplt.grid()\n\n\n#Animation\nani = animation.FuncAnimation(fig, animate, frames=200,  interval=20,repeat=False)\n\nplt.show()\n\nplt.close(fig)\nData.close()\n\nplt.title('d=f(t)') # titre du graphique\nplt.plot(liste_temps,liste_distance, color ='r', marker = 'o') # On affiche les points de coordonn\u00e9es (I,U) avec des points rouges\nplt.xlim (min(liste_temps),max(liste_temps))  #limtes pour les axes avec les valeurs extr\u00eames de I et de U\nplt.ylim(min(liste_distance),max(liste_distance))\nplt.xlabel('temps en s')\nplt.ylabel('distance en mm')\nplt.show()\n\n\n# Ecriture dans un fichier txt\nlines = ['t\\td\\n']  # premi\u00e8re ligne du fichier txt\nfor i in range(len(liste_temps)):\n    line = str(liste_temps[i]) +'\\t'+str(liste_distance[i]) + '\\n'\n    lines.append(line)\n\n# Utilisation de 'with open' pour assurer la fermeture du fichier\nwith open('data_arduino.txt', 'w', encoding='utf-8') as fichier:\n    fichier.writelines(lines)  # cr\u00e9ation d'un nouveau fichier texte\n\n<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"622\" height=\"535\" src=\"https:\/\/labopothier.com\/wp-content\/uploads\/2021\/02\/Sans-titre-3.png\" alt=\"\" class=\"wp-image-578\" srcset=\"https:\/\/labopothier.com\/wp-content\/uploads\/2021\/02\/Sans-titre-3.png 622w, https:\/\/labopothier.com\/wp-content\/uploads\/2021\/02\/Sans-titre-3-300x258.png 300w\" sizes=\"auto, (max-width: 622px) 100vw, 622px\" \/><\/figure>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>Un grand merci \u00e0 Lionel Grillet, professeur de SI, pour son aide pr\u00e9cieuse gr\u00e2ce \u00e0 ses connaissances pointues en langage Python !<\/p>\n<\/blockquote>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Objectif de cette activit\u00e9 : R\u00e9cup\u00e9rer dans Python les donn\u00e9es du moniteur s\u00e9rie d&rsquo;un programme Arduino en utilisant simplement la biblioth\u00e8que serial. Pr\u00e9-requis : \u00eatre familier avec le langage Python &#8230; et \u00e9ventuellement avoir des bases en programmation pour les microcontr\u00f4leurs Arduino (mais pas obligatoire car on peut partir d&rsquo;une carte Arduino d\u00e9j\u00e0 programm\u00e9e avec [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":985,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"site-sidebar-layout":"default","site-content-layout":"default","ast-site-content-layout":"default","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"","footer-sml-layout":"","theme-transparent-header-meta":"default","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"set","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"footnotes":""},"categories":[7,11],"tags":[],"class_list":["post-1419","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-microcontroleurs-et-python","category-recuperer-les-donnees-dune-carte-arduino-avec-python"],"_links":{"self":[{"href":"https:\/\/labopothier.com\/index.php\/wp-json\/wp\/v2\/posts\/1419","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/labopothier.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/labopothier.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/labopothier.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/labopothier.com\/index.php\/wp-json\/wp\/v2\/comments?post=1419"}],"version-history":[{"count":8,"href":"https:\/\/labopothier.com\/index.php\/wp-json\/wp\/v2\/posts\/1419\/revisions"}],"predecessor-version":[{"id":1830,"href":"https:\/\/labopothier.com\/index.php\/wp-json\/wp\/v2\/posts\/1419\/revisions\/1830"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/labopothier.com\/index.php\/wp-json\/wp\/v2\/media\/985"}],"wp:attachment":[{"href":"https:\/\/labopothier.com\/index.php\/wp-json\/wp\/v2\/media?parent=1419"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/labopothier.com\/index.php\/wp-json\/wp\/v2\/categories?post=1419"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/labopothier.com\/index.php\/wp-json\/wp\/v2\/tags?post=1419"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}