Bonjour
Ce sujet fait suite à une discussion que j'avais entamée dans un autre fil (https://www.developpez.net/forums/d2...nnees-arduino/) mais les échanges entre certains contributeurs ont dévié vers un autre débat ce qui a conduit à sa fermeture.
Je reviens donc à la suite du dernier post de ce précédent fil.
Pour éviter d'avoir à tout relire le post, ma question initiale portait sur la récupération des données issues du moniteur série d'Arduino via Python pour ensuite traiter ces données : à l'aide d'un tutoriel trouvé de-ci de-là, j'avais opté pour une méthode assez "brute" qui engendrait des caractères vides dans mes listes de mesures.
J'ai donc mis en oeuvre la solution proposée par Beginner : j'obtiens bien effectivement une liste (rapidement !!) des données envoyées via Arduino sans caractère vide donc cool !
En termes de réglages, d'habitude, sur les 3 paramètres d'acquisition possibles (fréquence échantillonnage, durée, nombre de points) qui ne sont indépendants que 2 à 2 (la 3ème se calculant à partir des 2 autres), on choisit plus souvent la fréquence d'échantillonnage et la durée plutôt que le nombre de points : c'est d'ailleurs vers cette solution que j'avais orientée mon code
qui faisait face, côté Arduino, au code suivant :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38 # Importation des modules utilisés import serial # Initialisation des variables arduino = None rawdata = [] nbrPoints = 0 def acuisition(nbrPoints): # Ouverture de la liaison série try: arduino = serial.Serial("COM3", baudrate=115200, timeout=3) except Exception as e: print("Vérifier le port série:", e) return periode=input("Saisir la période d'échantillonnage (en ms) : ") arduino.write(periode.encode("ascii")) duree=input("Saisir la durée totale (en ms) : ") arduino.write(duree.encode("ascii")) acquisition=input("Saisir S pour lancer l'acquisition") arduino.write(acquisition.encode("ascii")) nbrPoints=int(duree)//int(periode) # Réception et stockage des données print("Début de l'acquisition...") compt = 0 while compt < nbrPoints: data_read = arduino.readline().decode()[:-2] rawdata.append(data_read) print(compt, rawdata[compt], sep=" - ") compt += 1 print("Fin de l'acquisition.") acuisition(nbrPoints) # print("\nrawdata:", rawdata, "\ntaille:", len(rawdata))
Code Arduino : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97 // Déclaration des variables du programme unsigned long baud = 115000; // flux de la liaison série int delai = 1000; // délai d'attente pour être sûr de décharger le condensateur // Variables d'acquisition int timeRes; // période d'échantillonnage en ms int dureeAcquisition ; // durée totale de l'acquisition en ms, saisi dans Python int nbrPoints; // sera calculé à partir des données précédentes unsigned long cpt = 1; int topDepart = 0; //variable pour lancer l'acquisition String envoi; unsigned long tempsZero; unsigned long tempsCourant; unsigned long tempsPrec; // Broches de branchement au circuit byte mesureTension = 2; //broche analogique de mesure de la tension aux bornes de C byte chargeCondo = 3; //broche pour décharger initialement le condensateur void setup() { Serial.begin(baud); //configure la broche commandePin en tant que sortie pinMode(chargeCondo, OUTPUT); //on décharge le condensateur en le mettant à 0V digitalWrite(chargeCondo, LOW); //on attend delai ms pour être sur de l'avoir déchargé delay(delai); tempsPrec = 0; tempsZero = millis(); reglages(); nbrPoints=dureeAcquisition/timeRes; } // Boucle principale void loop() { tempsCourant = millis() - tempsZero; if (tempsCourant >= tempsPrec && cpt <= nbrPoints) { lecture(); cpt++; } } void reglages() { while (topDepart == 0) { envoi = Serial.readString(); while (Serial.available() == 0 ); if (Serial.available() != 0) { timeRes = Serial.parseInt(); //on enregistre la valeur saisie dans timeRes delay(100); //délai de temporisation } while (Serial.available() == 0 ); if (Serial.available() != 0) { dureeAcquisition = Serial.parseInt(); //on enregistre la valeur saisie dans dureeAcquisition delay(100); //délai de temporisation } while (Serial.available() == 0 ); if (Serial.available() != 0) { topDepart = 1; tempsPrec = 0; tempsZero = millis(); } } } void lecture() { //on met à 5V le générateur pour voir la charge digitalWrite(chargeCondo, HIGH); float tension; // Lecture et conversion des données tension = analogRead(mesureTension) * 5.0 / 1024; // mesure analogique et conversion en tension // Envoie les données Serial.print(tempsCourant / 1000.0, 3); // temps en seconde Serial.print(';'); Serial.println(tension, 2); // donne la valeur recalculée de tension aux bornes de C tempsPrec += timeRes; //Serial.flush(); }
Les mesures obtenues sont bien mieux échantillonnées et la période d'échantillonnage est plutôt très bien respecté (à partir pour une période de 1 ms où quelques sauts apparaissent) mais cela ne me dérange pas car c'est ensuite l'allure de la courbe qui m'intérèsse.
J'ai essayé en augmentant le baudrate : pas de soucis.
Pour obtenir les listes de tension et de temps, j'ai essayé une nouvelle approche sans avoir à passer par un document texte (j'ai cru comprendre que c'était faisable) : j'ai donc essayé la syntaxe suivante à la fin de la fonction acuisition:Est-ce que c'est une bonne technique pour obtenir mes 2 listes ou est-ce un peu barbare ? Je précise qu'elle fonctionne mais en guide d'amélioration de mon code, je me renseigne.https://www.developpez.net/forums/d2.../#post11496668
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 for val in rawdata: temps.append(val[:5]) tension.append(val[6:])
Partager