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
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))
qui faisait face, côté Arduino, au code suivant :
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:
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:])
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