{"id":1417,"date":"2024-09-10T06:09:17","date_gmt":"2024-09-10T04:09:17","guid":{"rendered":"https:\/\/labopothier.com\/?p=1417"},"modified":"2024-09-23T11:39:13","modified_gmt":"2024-09-23T09:39:13","slug":"activite-arduino-python-recuperer-avec-python-les-donnees-dune-carte-arduino-pour-tracer-la-caracteristique-dune-ldr-avec-regression-lineaire-2","status":"publish","type":"post","link":"https:\/\/labopothier.com\/index.php\/2024\/09\/10\/activite-arduino-python-recuperer-avec-python-les-donnees-dune-carte-arduino-pour-tracer-la-caracteristique-dune-ldr-avec-regression-lineaire-2\/","title":{"rendered":"ACTIVITE ARDUINO\/PYTHON : R\u00e9cup\u00e9rer avec Python les donn\u00e9es d&rsquo;une carte Arduino pour tracer la caract\u00e9ristique d&rsquo;une LDR (avec r\u00e9gression lin\u00e9aire)"},"content":{"rendered":"\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>Si cette biblioth\u00e8que n&rsquo;est pas install\u00e9e (pour le v\u00e9rifier, tester dans le shell<strong> import serial <\/strong>), il faudra \u00e9crire dans le shell (interpr\u00e9teur) :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"python\" class=\"language-python\">pip install serial<\/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\/\"> <\/a><a href=\"https:\/\/labopothier.com\/wp-admin\/post.php?post=359&amp;action=edit\">Trac\u00e9 de caract\u00e9ristique d&rsquo;une photor\u00e9sistance<\/a>). Les mesures dans le code Arduino se font en continu (boucle infinie avec<strong> while(true)<\/strong>) <\/p>\n\n\n\n<p><strong>Rappel : <\/strong>Tracer la caract\u00e9ristique U = f(I) d\u2019une photor\u00e9sistance en faisant varier une tension (\u00e0 l\u2019aide d\u2019un potentiom\u00e8tre) aux bornes d\u2019une association s\u00e9rie LDR-r\u00e9sistance connue (par exemple&nbsp; 1k\u03a9).<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"317\" src=\"https:\/\/labopothier.com\/wp-content\/uploads\/2020\/04\/trace_caracteristique-1024x317.png\" alt=\"\" class=\"wp-image-360\" srcset=\"https:\/\/labopothier.com\/wp-content\/uploads\/2020\/04\/trace_caracteristique-1024x317.png 1024w, https:\/\/labopothier.com\/wp-content\/uploads\/2020\/04\/trace_caracteristique-300x93.png 300w, https:\/\/labopothier.com\/wp-content\/uploads\/2020\/04\/trace_caracteristique-768x238.png 768w, https:\/\/labopothier.com\/wp-content\/uploads\/2020\/04\/trace_caracteristique.png 1417w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p><strong>Bonus<\/strong> : Faire une r\u00e9gression lin\u00e9aire en utilisant le module <strong>&nbsp;linregress <\/strong>(en important le module <strong>stats<\/strong> de <strong>scipy<\/strong>).<\/p>\n\n\n\n<pre title=\"Avec le langage Arduino\" class=\"wp-block-code\"><code lang=\"cpp\" class=\"language-cpp line-numbers\">\nfloat R= 1000;\nint const broche_LDR = A0;\nint const broche_alim = A1;\nint Valeur_LDR;\nint Valeur_alim;\nfloat U_alim;\nfloat U_LDR;\n\n\/\/==================================================================================================\n\/\/ Proc\u00e9dure d'initialisation des p\u00e9riph\u00e9riques\n\/\/==================================================================================================\nvoid setup() {\n  \/\/ Initialisation de la communication s\u00e9rie avec le terminal \u00e0 9600 baud.\n  Serial.begin(9600);\n  \n}\n\n\n\/\/==================================================================================================\n\/\/ Boucle principale Arduino.\n\/\/==================================================================================================\nvoid loop() {\n\n\n\n\n\n  \/\/ Mesures de la tension U_LDR en faisant varier U_alim avec le potentiom\u00e8tre\n\n  while(true)\n  { \n    Valeur_alim = analogRead(broche_alim); \/\/ Valeur comprise entre 0 et 1023\n    U_alim = Valeur_alim *5.0\/1023; \/\/ Calcul de la tension U_alim\n    Valeur_LDR   = analogRead(broche_LDR); \/\/ Valeur comprise entre 0 et 1023\n    U_LDR = (float)Valeur_LDR*5\/1023; \/\/Calcul de la tension aux bornes de la photor\u00e9sistance\n    \n    delay(1000);       \/\/ D\u00e9lai en ms pour la stabilisation de la tension \n                       \/\/pour la mesure de r\u00e9sistances.\n    \n   \n    float courant_A   = (U_alim - U_LDR)\/R; \/\/Calcul de l'intensit\u00e9 du courant en A\n\n    \/\/Affichage des resultats\n\n\n    Serial.print(\" Tension LDR: \");   \/\/ Affichage de la tension en V sur le moniteur s\u00e9rie\n    Serial.print(U_LDR);            \n    Serial.print(\" V\");              \n  \n    Serial.print(\" Courant: \");          \/\/ Affichage du courant en mA sur le moniteur s\u00e9rie\n    Serial.print(courant_A*1000);       \n    Serial.print(\" mA\");                \n    \n    Serial.println(\"\");                 \/\/ Saut de ligne.\n\n  }\n           \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<figure class=\"wp-block-image size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"391\" src=\"https:\/\/labopothier.com\/wp-content\/uploads\/2021\/02\/Sans-titre-4-1024x391.png\" alt=\"\" class=\"wp-image-637\" style=\"width:672px;height:256px\" srcset=\"https:\/\/labopothier.com\/wp-content\/uploads\/2021\/02\/Sans-titre-4-1024x391.png 1024w, https:\/\/labopothier.com\/wp-content\/uploads\/2021\/02\/Sans-titre-4-300x115.png 300w, https:\/\/labopothier.com\/wp-content\/uploads\/2021\/02\/Sans-titre-4-768x293.png 768w, https:\/\/labopothier.com\/wp-content\/uploads\/2021\/02\/Sans-titre-4.png 1029w\" 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 : R\u00e9cup\u00e9rer les valeurs dans Python pour les stocker dans une liste<\/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 faire appel \u00e0 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 les listes :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"python\" class=\"language-python\"># Initialisation des listes \n\nlines = ['I(mA)\\tU(V)\\n'] # premi\u00e8re ligne du fichier texte dans lequel on enregistrera les donn\u00e9es\nU = []  # liste pour les valeurs de tension aux bornes de la LDR\nI = []  # liste pour les valeurs d'intensit\u00e9 du courant<\/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 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            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 la 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>Ensuite, 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>La m\u00e9thode <strong>.split()<\/strong> permet de 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' Tension LDR: 2.65 V Courant: 2.24 mA\\r\\n'\n[b'Tension', b'LDR:', b'2.65', b'V', b'Courant:', b'2.24', b'mA']<\/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 une liste avec les diff\u00e9rents \u00e9l\u00e9ments de cette cha\u00eene. L&rsquo;information qui nous int\u00e9resse (valeur de distance) est donc les 3\u00e8me et 6\u00e8me \u00e9l\u00e9ment de la liste &#8230; donc d&rsquo;indice 2 et 5 &#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>Nous pouvons choisir une acquisition pour 10 points (et de stocker les valeurs mesur\u00e9es dans les listes<strong> U et I<\/strong>) de la fa\u00e7on suivante :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"python\" class=\"language-python\">for i in range(10) : #acquisition pour 10 valeurs\n    line = Data.readline()  # Lit la ligne venant du port s\u00e9rie.\n    print (line)\n    listeDonnees = line.strip()\n    listeDonnees = line.split() # on s\u00e9pare les donn\u00e9es de la ligne  et on les stocke dans une liste\n    print(listeDonnees)  # affichage de la liste obtenue.\n\n    if len(listeDonnees)!=0: # extraction des donn\u00e9es (valeurs d'intensit\u00e9 et tension)\n        tension = float(listeDonnees[2].decode())\n        courant = float(listeDonnees[5].decode())\n        U.append(tension)\n        print(\"U = %f\"%(tension))\n        I.append(courant)\n        print(\"I = %f\"%(courant))\n        \n    \nData.close()   # pour arr\u00eater la lecture des donn\u00e9es s\u00e9rie<\/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\n\nfor i in range (len (I)):\n    line = str(I[i]) +'\\t'+ str(U[i])+'\\n'\n    lines.append(line)\n\nopen('data.txt', 'w').writelines(lines) #cr\u00e9ation d'un nouveau fichier texte<\/code><\/pre>\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>Nous allons utiliser la fonction <strong>stats.linregress(X,Y)<\/strong> pour faire la r\u00e9gression lin\u00e9aire. Cette fonction retourne plusieurs valeurs, les trois premi\u00e8res sont la pente, l&rsquo;origine \u00e0 l&rsquo;ordonn\u00e9e et le coefficient de corr\u00e9lation (\u00e0 mettre au carr\u00e9)<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"python\" class=\"language-python\">eq = stats.linregress (I,U) # pour faire la r\u00e9gression lin\u00e9aire\n\npente = eq[0] # pente\nordorig = eq[1] # ordonn\u00e9e \u00e0 l'origine\ncoeff2 = eq[2]**2 # coefficient de corr\u00e9lation au carr\u00e9 r\u00b2\n\nXcalc = np.linspace(0,max(I) , 256) # cr\u00e9ation de points pour le trac\u00e9 du mod\u00e8le : on cr\u00e9e 256 points r\u00e9guli\u00e8rement espac\u00e9s entre 0 et la valeur max de I\nYcalc = pente*Xcalc+ordorig # on fait calculer U avec les param\u00e8tres de la r\u00e9gression lin\u00e9aire pour ces valeurs de I\ntexte = 'equation de la droite  U = '+str(round(pente,3))+' I + '+str(round(ordorig,3))+'     R\u00b2 = '+str(round(coeff2,3)) # on affiche l'\u00e9quation de la droite avec 3 d\u00e9cimales\n\nprint (texte)<\/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\"># Affichage du graphique\nplt.title('U=f(I)') # titre du graphique\nplt.scatter(I,U, color ='r', marker = 'o') # On affiche les points de coordonn\u00e9es (I,U) avec des points rouges\nplt.plot(Xcalc,Ycalc,color = 'b',label = texte) # Affichage de la courbe mod\u00e9lis\u00e9e en bleu\nplt.xlabel('I')       # nommer l'axe des abscisses\nplt.ylabel('U')       # nommer l'axe des ordonn\u00e9ees\nplt.xlim (min(I),max(I))  #limtes pour les axes avec les valeurs extr\u00eames de I et de U\nplt.ylim(min(U),max(U))\nplt.legend()   # pour afficher les l\u00e9gendes (label)\nplt.show()  #afficher le graphique (ne rien mettre dans la parenth\u00e8se)<\/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=\"Caract\u00e9ristique d'une photor\u00e9sistante avec r\u00e9gression lin\u00e9aire. Mesures avec la carte Arduino et r\u00e9cup\u00e9ration des donn\u00e9es avec Python pour trac\u00e9 de graphe et traitement (r\u00e9gression lin\u00e9aire)\" class=\"wp-block-code\"><code lang=\"python\" class=\"language-python\">\n\"\"\"\nProgramme Python pour r\u00e9cup\u00e9rer les donnn\u00e9es d'un code Arduino permettant de tracer une caract\u00e9ristique d'une photor\u00e9sistance (ou autre capteur r\u00e9sistif). On affiche ensuite les r\u00e9sultats d'une r\u00e9gression lin\u00e9aire.\nMontage : Une tension de 5 V est appliqu\u00e9e aux deux points extr\u00eames d'un potentiom\u00e8tre. On cr\u00e9e une alimentation variable en r\u00e9cup\u00e9rant la tension entre le point milieu et la masse .\nOn applique cette tension \u00e0 une association s\u00e9rie photor\u00e9sistance avec r\u00e9sistance connue (1 kohms)-. On fait mesurer par Arduino la tension aux bornes de la photor\u00e9sistance et l'intensit\u00e9 parcourant le circuit I = (tension alim - tension photor\u00e9sistance)\/R.\n\"\"\"\n\n#########################################  IMPORTATION DES BIBLIOTHEQUES ET MODULES  ########################################################\n\nimport numpy   # numpy pour les maths , par exemple pour cr\u00e9er 256 valeurs r\u00e9guli\u00e8rement espac\u00e9es entre 0 et 10 : np.linspace(0,10,256)\nfrom time import sleep             # pour faire des \"pauses\" dans l'ex\u00e9cution du programme\nimport matplotlib.pyplot as plt # pour les graphiques\n\n\nfrom scipy import stats # module permettant de faire la r\u00e9gression lin\u00e9aire \u00e0 partir d'une liste X et d'une liste Y, stats.linregress(X,Y) renvoie 5 valeurs. Les 3 premi\u00e8res valeurs sont la pente, l'ordonn\u00e9e \u00e0 l'origine, et le coefficient de corr\u00e9lation (\u00e0 mettre au carr\u00e9)\n\n\nimport serial\nimport serial.tools.list_ports\n\n\n\n#########################################  COMMUNICATION AVEC CARTE ARDUINO ET DEFINITION DES VARIABLES  #######################################################\n\n#initialisation des listes\nU=[]\nI=[]\nlines = ['I(mA)\\tU(V)\\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            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#########R\u00e9cup\u00e9ration des donn\u00e9es qu'on stocke dans des listes ########################################################################\n\nData =recup_port_Arduino() #r\u00e9cup\u00e9ration des donn\u00e9es\n\nfor i in range(10) : #acquisition pour 10 valeurs\n    line = Data.readline()  # Lit la ligne venant du port s\u00e9rie.\n    print (line)\n    listeDonnees = line.strip()\n    listeDonnees = line.split() # on s\u00e9pare les donn\u00e9es de la ligne  et on les stocke dans une liste\n    print(listeDonnees)  # affichage de la liste obtenue.\n\n    if len(listeDonnees)!=0: # extraction des donn\u00e9es (valeurs d'intensit\u00e9 et tension)\n        tension = float(listeDonnees[2].decode())\n        courant = float(listeDonnees[5].decode())\n        U.append(tension)\n        print(\"U = %f\"%(tension))\n        I.append(courant)\n        print(\"I = %f\"%(courant))\n        \n    \nData.close()\n\n#Ecriture dans un fichier txt\nfor i in range (len (I)):\n    line = str(I[i]) +'\\t'+ str(U[i])+'\\n'\n    lines.append(line)\n\nopen('data.txt', 'w').writelines(lines) #cr\u00e9ation d'un nouveau fichier texte sans la premi\u00e8re ligne\n\n\neq = stats.linregress (I,U) # pour faire la r\u00e9gression lin\u00e9aire\n\npente = eq[0] # pente\nordorig = eq[1] # ordonn\u00e9e \u00e0 l'origine\ncoeff2 = eq[2]**2 # coefficient de corr\u00e9lation au carr\u00e9 r\u00b2\n\nXcalc = numpy.linspace(0,max(I) , 256) # cr\u00e9ation de points pour le trac\u00e9 du mod\u00e8le : on cr\u00e9e 256 points r\u00e9guli\u00e8rement espac\u00e9s entre 0 et la valeur max de I\nYcalc = pente*Xcalc+ordorig # on fait calculer U avec les param\u00e8tres de la r\u00e9gression lin\u00e9aire pour ces valeurs de I\n\nglobal texte\ntexte = 'equation de la droite  U = '+str(round(pente,3))+' I + '+str(round(ordorig,3))+'     R\u00b2 = '+str(round(coeff2,3)) # on affiche l'\u00e9quation de la droite avec 3 d\u00e9cimales\n\nprint (texte)\n\n# Affichage du graphique\nplt.title('U=f(I)') # titre du graphique\nplt.scatter(I,U, color ='r', marker = 'o') # On affiche les points de coordonn\u00e9es (I,U) avec des points rouges\nplt.plot(Xcalc,Ycalc,color = 'b',label = texte) # Affichage de la courbe mod\u00e9lis\u00e9e en bleu\nplt.xlabel('I')       # nommer l'axe des abscisses\nplt.ylabel('U')       # nommer l'axe des ordonn\u00e9ees\nplt.xlim (min(I),max(I))  #limtes pour les axes avec les valeurs extr\u00eames de I et de U\nplt.ylim(min(U),max(U))\nplt.legend()   # pour afficher les l\u00e9gendes (label)\nplt.show()  #afficher le graphique (ne rien mettre dans la parenth\u00e8se)\n<\/code><\/pre>\n\n\n\n<div class=\"wp-block-group is-layout-flow wp-block-group-is-layout-flow\">\n<figure class=\"wp-block-gallery aligncenter has-nested-images columns-default is-cropped wp-block-gallery-1 is-layout-flex wp-block-gallery-is-layout-flex\">\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"755\" data-id=\"650\" src=\"https:\/\/labopothier.com\/wp-content\/uploads\/2021\/02\/Capture-decran-2021-02-18-a-22.48.06-1-1024x755.png\" alt=\"\" class=\"wp-image-650\" srcset=\"https:\/\/labopothier.com\/wp-content\/uploads\/2021\/02\/Capture-decran-2021-02-18-a-22.48.06-1-1024x755.png 1024w, https:\/\/labopothier.com\/wp-content\/uploads\/2021\/02\/Capture-decran-2021-02-18-a-22.48.06-1-300x221.png 300w, https:\/\/labopothier.com\/wp-content\/uploads\/2021\/02\/Capture-decran-2021-02-18-a-22.48.06-1-768x566.png 768w, https:\/\/labopothier.com\/wp-content\/uploads\/2021\/02\/Capture-decran-2021-02-18-a-22.48.06-1.png 1286w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><figcaption class=\"wp-element-caption\">Forte luminosit\u00e9<\/figcaption><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"767\" data-id=\"651\" src=\"https:\/\/labopothier.com\/wp-content\/uploads\/2021\/02\/Capture-decran-2021-02-18-a-22.46.27-2-1024x767.png\" alt=\"\" class=\"wp-image-651\" srcset=\"https:\/\/labopothier.com\/wp-content\/uploads\/2021\/02\/Capture-decran-2021-02-18-a-22.46.27-2-1024x767.png 1024w, https:\/\/labopothier.com\/wp-content\/uploads\/2021\/02\/Capture-decran-2021-02-18-a-22.46.27-2-300x225.png 300w, https:\/\/labopothier.com\/wp-content\/uploads\/2021\/02\/Capture-decran-2021-02-18-a-22.46.27-2-768x575.png 768w, https:\/\/labopothier.com\/wp-content\/uploads\/2021\/02\/Capture-decran-2021-02-18-a-22.46.27-2.png 1242w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><figcaption class=\"wp-element-caption\">Faible luminosit\u00e9<\/figcaption><\/figure>\n<figcaption class=\"blocks-gallery-caption wp-element-caption\">Trac\u00e9s avec des \u00e9clairements diff\u00e9rents<\/figcaption><\/figure>\n\n\n\n<p><\/p>\n<\/div>\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>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\">def animate(i):\n\n    line = Data.readline()  # Lit la ligne venant du port s\u00e9rie.\n    print (line)\n    listeDonnees = line.strip()\n    listeDonnees = line.split() # on s\u00e9pare les donn\u00e9es de la ligne  et on les stocke dans une liste\n    print(listeDonnees)  # affichage de la liste obtenue.\n    while  len (U)&lt;10 :\n        if len(listeDonnees)!=0: # extraction des donn\u00e9es (valeurs d'intensit\u00e9 et tension)\n            tension = float(listeDonnees[2].decode())\n            courant = float(listeDonnees[5].decode())\n            U.append(tension)\n            print(\"U = %f\"%(tension))\n            I.append(courant)\n            print(\"I = %f\"%(courant))\n            line0.set_data(I, U)\n            return line0,\n    \n\n\n\n<\/code><\/pre>\n\n\n\n<p>Puis on r\u00e9cup\u00e8re les donn\u00e9es et on fait affchier la figure anim\u00e9e avec la m\u00e9thode<strong> animation.FuncAnimation<\/strong> :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"python\" class=\"language-python\">\nData =recup_port_Arduino() #r\u00e9cup\u00e9ration des donn\u00e9es\n\n\n# Cr\u00e9ation figure\n\nfig=plt.figure()\nline0, = plt.plot([],[])\nplt.xlim(0, 5)\nplt.ylim(0,5)\nplt.xlabel(\"I\")\nplt.ylabel(\"U\")\n\n#Animation\nani = animation.FuncAnimation(fig, animate,  frames=21,  interval=20,repeat=False)\n\nplt.show()\nData.close()<\/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\">\n\"\"\"\nProgramme Python pour r\u00e9cup\u00e9rer les donnn\u00e9es d'un code Arduino permettant de tracer en temps r\u00e9el une caract\u00e9ristique d'une photor\u00e9sistance (ou autre capteur r\u00e9sistif). On affiche ensuite les r\u00e9sultats d'une r\u00e9gression lin\u00e9aire.\nMontage : Une tension de 5 V est appliqu\u00e9e aux deux points extr\u00eames d'un potentiom\u00e8tre. On cr\u00e9e une alimentation variable en r\u00e9cup\u00e9rant la tension entre le point milieu et la masse .\nOn applique cette tension \u00e0 une association s\u00e9rie photor\u00e9sistance avec r\u00e9sistance connue (1 kohms)-. On fait mesurer par Arduino la tension aux bornes de la photor\u00e9sistance et l'intensit\u00e9 parcourant le circuit I = (tension alim - tension photor\u00e9sistance)\/R.\n\"\"\"\n\n#########################################  IMPORTATION DES BIBLIOTHEQUES ET MODULES  ########################################################\n\nimport numpy   # numpy pour les maths , par exemple pour cr\u00e9er 256 valeurs r\u00e9guli\u00e8rement espac\u00e9es entre 0 et 10 : np.linspace(0,10,256)\nfrom time import sleep             # pour faire des \"pauses\" dans l'ex\u00e9cution du programme\nimport matplotlib.pyplot as plt # pour les graphiques\nimport matplotlib.animation as animation\n\nfrom scipy import stats # module permettant de faire la r\u00e9gression lin\u00e9aire \u00e0 partir d'une liste X et d'une liste Y, stats.linregress(X,Y) renvoie 5 valeurs. Les 3 premi\u00e8res valeurs sont la pente, l'ordonn\u00e9e \u00e0 l'origine, et le coefficient de corr\u00e9lation (\u00e0 mettre au carr\u00e9)\n\n\nimport serial\nimport serial.tools.list_ports\n\n\n\n#########################################  COMMUNICATION AVEC CARTE ARDUINO ET DEFINITION DES VARIABLES  #######################################################\n\nR= 1000.0 # valeur de r\u00e9sistance connue pour mesure de l'intensit\u00e9\n\n\nU_alim = 0.0\ncourant_A =0.0\nlines = ['I(mA)\\tU(V)\\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            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#########################################  Fonction animate(i) pour trac\u00e9 en temps r\u00e9el    ##############################################################################\n\n\ndef animate(i):\n\n    line = Data.readline()  # Lit la ligne venant du port s\u00e9rie.\n    print (line)\n    listeDonnees = line.strip()\n    listeDonnees = line.split() # on s\u00e9pare les donn\u00e9es de la ligne  et on les stocke dans une liste\n    print(listeDonnees)  # affichage de la liste obtenue.\n    while  len (U)&lt;10 :\n        if len(listeDonnees)!=0: # extraction des donn\u00e9es (valeurs d'intensit\u00e9 et tension)\n            tension = float(listeDonnees[2].decode())\n            courant = float(listeDonnees[5].decode())\n            U.append(tension)\n            print(\"U = %f\"%(tension))\n            I.append(courant)\n            print(\"I = %f\"%(courant))\n            line0.set_data(I, U)\n            return line0,\n    \n\n\n\nData =recup_port_Arduino() #r\u00e9cup\u00e9ration des donn\u00e9es\n\n\n#initialisation des listes\n\nU=[]\nI=[]\n# Cr\u00e9ation figure \"dynamique\" en temps r\u00e9el\n\nfig=plt.figure()\nline0, = plt.plot([],[])\nplt.xlim(0, 5)\nplt.ylim(0,5)\nplt.xlabel(\"I\")\nplt.ylabel(\"U\")\n\n#Animation\nani = animation.FuncAnimation(fig, animate,  frames=21,  interval=20,repeat=False)\n\nplt.show()\nData.close()\n\n\neq = stats.linregress (I,U) # pour faire la r\u00e9gression lin\u00e9aire\n\npente = eq[0] # pente\nordorig = eq[1] # ordonn\u00e9e \u00e0 l'origine\ncoeff2 = eq[2]**2 # coefficient de corr\u00e9lation au carr\u00e9 r\u00b2\n\nXcalc = numpy.linspace(0,max(I) , 256) # cr\u00e9ation de points pour le trac\u00e9 du mod\u00e8le : on cr\u00e9e 256 points r\u00e9guli\u00e8rement espac\u00e9s entre 0 et la valeur max de I\nYcalc = pente*Xcalc+ordorig # on fait calculer U avec les param\u00e8tres de la r\u00e9gression lin\u00e9aire pour ces valeurs de I\n\nglobal texte\ntexte = 'equation de la droite  U = '+str(round(pente,3))+' I + '+str(round(ordorig,3))+'     R\u00b2 = '+str(round(coeff2,3)) # on affiche l'\u00e9quation de la droite avec 3 d\u00e9cimales\n\nprint (texte)\n\n# trac\u00e9 du graphe \"statique\" avec r\u00e9sultat de la r\u00e9gression lin\u00e9aire apr\u00e8s fermeture du graphe \"dynamique\"\nplt.title('U=f(I)') # titre du graphique\nplt.scatter(I,U, color ='r', marker = 'o') # On affiche les points de coordonn\u00e9es (I,U) avec des points rouges\nplt.plot(Xcalc,Ycalc,color = 'b',label = texte) # Affichage de la courbe mod\u00e9lis\u00e9e en bleu\nplt.xlabel('I')       # nommer l'axe des abscisses\nplt.ylabel('U')       # nommer l'axe des ordonn\u00e9ees\nplt.xlim (min(I),max(I))  #limtes pour les axes avec les valeurs extr\u00eames de I et de U\nplt.ylim(min(U),max(U))\nplt.legend()   # pour afficher les l\u00e9gendes (label)\nplt.show()  #afficher le graphique (ne rien mettre dans la parenth\u00e8se)\n\n\n#Ecriture dans un fichier txt\nfor i in range (len (I)):\n    line = str(I[i]) +'\\t'+ str(U[i])+'\\n'\n    lines.append(line)\n\nopen('data.txt', 'w').writelines(lines) #cr\u00e9ation d'un nouveau fichier texte sans la premi\u00e8re ligne\n\n\n<\/code><\/pre>\n\n\n\n<p>Voici en vid\u00e9o ce qui se passe  : pendant l&rsquo;ex\u00e9cution du programme, nous tournons r\u00e9guli\u00e8rement le potentiom\u00e8tre pour l&rsquo;acqusition de 10 points et el trac\u00e9 se fait en temps r\u00e9el. Une fois la fen\u00eatre de ce graphique ferm\u00e9e, il apparait un graphe (statique) avec les r\u00e9sultats de la r\u00e9gression lin\u00e9aire.<\/p>\n\n\n\n<figure class=\"wp-block-video\"><video controls src=\"https:\/\/labopothier.com\/wp-content\/uploads\/2021\/03\/Mon-film-bisYoutube-HD.mov\"><\/video><\/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>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 un code inconnu et s&rsquo;en sortir quand m\u00eame !) Pour l&rsquo;initiation au langage Python , je vous invite \u00e0 consulter cet article [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":733,"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-1417","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\/1417","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=1417"}],"version-history":[{"count":3,"href":"https:\/\/labopothier.com\/index.php\/wp-json\/wp\/v2\/posts\/1417\/revisions"}],"predecessor-version":[{"id":1558,"href":"https:\/\/labopothier.com\/index.php\/wp-json\/wp\/v2\/posts\/1417\/revisions\/1558"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/labopothier.com\/index.php\/wp-json\/wp\/v2\/media\/733"}],"wp:attachment":[{"href":"https:\/\/labopothier.com\/index.php\/wp-json\/wp\/v2\/media?parent=1417"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/labopothier.com\/index.php\/wp-json\/wp\/v2\/categories?post=1417"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/labopothier.com\/index.php\/wp-json\/wp\/v2\/tags?post=1417"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}