IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Calcul scientifique Python Discussion :

Récupération données Arduino


Sujet :

Calcul scientifique Python

  1. #1
    Membre éprouvé

    Homme Profil pro
    Technicien
    Inscrit en
    Août 2013
    Messages
    437
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Technicien
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2013
    Messages : 437
    Points : 1 190
    Points
    1 190
    Par défaut Récupération données Arduino
    Bonjour

    J'aimerais pouvoir traiter mes données issues d'Arduino. Par diverses recherches, j'ai trouvé une solution qui fonctionne plus ou moins bien : je récupère les données du moniteur série (arduino.readline), je nettoie mon fichier obtenu pour enlever les caractères "parasites" qui sont mis (fonction nettoie), j'écris les données dans un fichier texte puis je traite les données du fichier texte.
    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
    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
    #Importation des modules utilisés
    import serial
    import numpy as np
    import matplotlib.pyplot as plt
    from math import exp
    from scipy.optimize import curve_fit
     
    #Définition de la fonction pour la modélisation
    def fonction( x, a):
        return ((exp(1)**(-1*a*x)))
     
    #Ouverture de la liaison série
    try :
        arduino=serial.Serial("COM3", baudrate=115200, timeout=1)
    except:
        print("Vérifier le port série")
     
     
    #Initialisation des variables
    rawdata=[]
    compt=0
     
    #Réception et stockage des données
    while compt<50:
        rawdata.append(str(arduino.readline()))
        compt+=1
     
    #Fonction de nettoyage pour supprimer
    def nettoie(L):
        newL=[]
        for i in range (len(L)):
            temp=L[i][2:]
            newL.append(temp[:-5])
        return newL
     
    cleandata=nettoie(rawdata)
    print(cleandata)
     
    #Ecriture des données dans un fichier texte
    #Une ligne par donnée
    def write(L):
        file=open("data.txt", mode="w")
        for i in range(len(L)):
            file.write(L[i]+"\n")
        file.close()
     
    write(cleandata)
     
    temps,tension=np.loadtxt("data.txt", delimiter=";",unpack=True)
     
     
    #modele=np.polyfit(logtension,temps,1)
    #print("logtension = ",modele[0]," x temps + ",modele[1])
    #print("tau = ")
     
    #Modélisation des données expérimentales
    params, covar = curve_fit(fonction, temps, tension, p0 = 1e-3)
    print(params, covar)
     
    modele = []
    for val in temps:
        modele.append(fonction(val, params))
     
    #Affichage des données expérimentales + modélisées
    plt.plot(temps, tension, 'o', label="valeurs expérimentales")
    plt.plot(temps, modele, label="modele".format(*params))
    plt.legend()
    plt.title("modélisation de lacharge d'un condensateur")
    plt.xlabel('Temps (s)')
    plt.ylabel('U(condensateur) (V)')
    plt.show()
    Mon principal problème vient de la présence de caractères vides dans le fichier de nettoyage.
    Par exemple : ['', '', '0.000;0.06', '0.001;0.62', '0.003;1.12', '0.004;1.56', '0.005;1.95', '0.007;2.29', '0.008;2.59', '', '', '', '', '', '', '', '', '', '']

    Dans le cas de cette expérience (charge d'un condensateur), je pourrais vouloir calculer le logarithme de la tension (la 2ème donnée) mais comme j'ai les caractères vides, j'ai une erreur "only size-1 arrays can be converted to Python scalars"

    Ensuite, j'aimerais savoir si une autre méthode pour récupérer les données d'Arduino existait plus "jolie" : je trouve un peu fastidieuse et poussive cette méthode (avec le passage par un fichier texte).

    J'ai un dernier problème (modélisation par l'exponentielle qui ne fonctionne pas) mais je vais faire la demande dans une autre discussion.

    Merci pour votre aide.
    [Nouveau] Envie de tracer des circuits électriques : essayez le package LaTeX CircuiTikZ

    Pour créer une belle table des matières sur LibreOffice - N'oubliez pas de consulter les FAQ en cas de question !

    Envie de se lancer dans l'aventure Arduino : allez faire un tour sur ce cours.


    Ma réponse vous a plu ? Un petit vote serait sympa
      1  0

  2. #2
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 242
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 242
    Points : 36 699
    Points
    36 699
    Par défaut
    Salut,

    Citation Envoyé par nlbmoi Voir le message
    Mon principal problème vient de la présence de caractères vides dans le fichier de nettoyage.
    Par exemple : ['', '', '0.000;0.06', '0.001;0.62', '0.003;1.12', '0.004;1.56', '0.005;1.95', '0.007;2.29', '0.008;2.59', '', '', '', '', '', '', '', '', '', '']
    Les "caractères vides" et autres joyeusetés sont ajoutées par:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    #Réception et stockage des données
    while compt<50:
        rawdata.append(str(arduino.readline()))
        compt+=1
    Avec un timeout=1, .readline() retournera une séquence de bytes incomplète (voire "vide") s'il n'a pas vu de fin de ligne avant le timeout.
    Appliquer "str" aux bytes reçus ajoute du garbage:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    >>> s = b'123'
    >>> str(s)
    "b'123'"
    >>>
    Si nécessaire s.decode() serait plus approprié.


    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels
      0  0

  3. #3
    Membre éprouvé

    Homme Profil pro
    Technicien
    Inscrit en
    Août 2013
    Messages
    437
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Technicien
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2013
    Messages : 437
    Points : 1 190
    Points
    1 190
    Par défaut
    Bonjour

    Merci pour l'aide.
    Je ne comprends pas à quel moment je dois faire le decode dans mon programme ?
    [Nouveau] Envie de tracer des circuits électriques : essayez le package LaTeX CircuiTikZ

    Pour créer une belle table des matières sur LibreOffice - N'oubliez pas de consulter les FAQ en cas de question !

    Envie de se lancer dans l'aventure Arduino : allez faire un tour sur ce cours.


    Ma réponse vous a plu ? Un petit vote serait sympa
      0  0

  4. #4
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 242
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 242
    Points : 36 699
    Points
    36 699
    Par défaut
    Citation Envoyé par nlbmoi Voir le message
    Je ne comprends pas à quel moment je dois faire le decode dans mon programme ?
    à la place de "str"...

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels
      0  0

  5. #5
    Membre du Club
    Homme Profil pro
    Enseignant
    Inscrit en
    Février 2019
    Messages
    67
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Février 2019
    Messages : 67
    Points : 42
    Points
    42
    Par défaut Comlément Excel, datastreamer
    Bonjour,

    oui, il est possible de récupérer directement les données sur tableur Excel en utilisant le complément de données DataStreamer.
    Le hasard faisant bien les choses, j'ai déjà fait un tutoriel concernant la charge simultanée de 2 condensateurs avec Arduino et le transfert direct des données sur Excel, puis la modélisation des courbes (complément Solveur)

    Si vous êtes intéressé je peux vous envoyer le lien de la vidéo (YouTube).



    Citation Envoyé par nlbmoi Voir le message
    Bonjour

    J'aimerais pouvoir traiter mes données issues d'Arduino. Par diverses recherches, j'ai trouvé une solution qui fonctionne plus ou moins bien : je récupère les données du moniteur série (arduino.readline), je nettoie mon fichier obtenu pour enlever les caractères "parasites" qui sont mis (fonction nettoie), j'écris les données dans un fichier texte puis je traite les données du fichier texte.
    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
    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
    #Importation des modules utilisés
    import serial
    import numpy as np
    import matplotlib.pyplot as plt
    from math import exp
    from scipy.optimize import curve_fit
     
    #Définition de la fonction pour la modélisation
    def fonction( x, a):
        return ((exp(1)**(-1*a*x)))
     
    #Ouverture de la liaison série
    try :
        arduino=serial.Serial("COM3", baudrate=115200, timeout=1)
    except:
        print("Vérifier le port série")
     
     
    #Initialisation des variables
    rawdata=[]
    compt=0
     
    #Réception et stockage des données
    while compt<50:
        rawdata.append(str(arduino.readline()))
        compt+=1
     
    #Fonction de nettoyage pour supprimer
    def nettoie(L):
        newL=[]
        for i in range (len(L)):
            temp=L[i][2:]
            newL.append(temp[:-5])
        return newL
     
    cleandata=nettoie(rawdata)
    print(cleandata)
     
    #Ecriture des données dans un fichier texte
    #Une ligne par donnée
    def write(L):
        file=open("data.txt", mode="w")
        for i in range(len(L)):
            file.write(L[i]+"\n")
        file.close()
     
    write(cleandata)
     
    temps,tension=np.loadtxt("data.txt", delimiter=";",unpack=True)
     
     
    #modele=np.polyfit(logtension,temps,1)
    #print("logtension = ",modele[0]," x temps + ",modele[1])
    #print("tau = ")
     
    #Modélisation des données expérimentales
    params, covar = curve_fit(fonction, temps, tension, p0 = 1e-3)
    print(params, covar)
     
    modele = []
    for val in temps:
        modele.append(fonction(val, params))
     
    #Affichage des données expérimentales + modélisées
    plt.plot(temps, tension, 'o', label="valeurs expérimentales")
    plt.plot(temps, modele, label="modele".format(*params))
    plt.legend()
    plt.title("modélisation de lacharge d'un condensateur")
    plt.xlabel('Temps (s)')
    plt.ylabel('U(condensateur) (V)')
    plt.show()
    Mon principal problème vient de la présence de caractères vides dans le fichier de nettoyage.
    Par exemple : ['', '', '0.000;0.06', '0.001;0.62', '0.003;1.12', '0.004;1.56', '0.005;1.95', '0.007;2.29', '0.008;2.59', '', '', '', '', '', '', '', '', '', '']

    Dans le cas de cette expérience (charge d'un condensateur), je pourrais vouloir calculer le logarithme de la tension (la 2ème donnée) mais comme j'ai les caractères vides, j'ai une erreur "only size-1 arrays can be converted to Python scalars"

    Ensuite, j'aimerais savoir si une autre méthode pour récupérer les données d'Arduino existait plus "jolie" : je trouve un peu fastidieuse et poussive cette méthode (avec le passage par un fichier texte).

    J'ai un dernier problème (modélisation par l'exponentielle qui ne fonctionne pas) mais je vais faire la demande dans une autre discussion.

    Merci pour votre aide.
      0  0

  6. #6
    Membre éprouvé

    Homme Profil pro
    Technicien
    Inscrit en
    Août 2013
    Messages
    437
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Technicien
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2013
    Messages : 437
    Points : 1 190
    Points
    1 190
    Par défaut
    Citation Envoyé par Olivier20000 Voir le message
    Bonjour,

    oui, il est possible de récupérer directement les données sur tableur Excel en utilisant le complément de données DataStreamer.
    Le hasard faisant bien les choses, j'ai déjà fait un tutoriel concernant la charge simultanée de 2 condensateurs avec Arduino et le transfert direct des données sur Excel, puis la modélisation des courbes (complément Solveur)

    Si vous êtes intéressé je peux vous envoyer le lien de la vidéo (YouTube).
    Bonjour

    Je veux bien le lien.
    L'idéal aurait plutôt été d'avoir un tutoriel avec Calc car nous ne disposons pas d'excel au lycée.
    [Nouveau] Envie de tracer des circuits électriques : essayez le package LaTeX CircuiTikZ

    Pour créer une belle table des matières sur LibreOffice - N'oubliez pas de consulter les FAQ en cas de question !

    Envie de se lancer dans l'aventure Arduino : allez faire un tour sur ce cours.


    Ma réponse vous a plu ? Un petit vote serait sympa
      0  0

  7. #7
    Membre éprouvé

    Homme Profil pro
    Technicien
    Inscrit en
    Août 2013
    Messages
    437
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Technicien
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2013
    Messages : 437
    Points : 1 190
    Points
    1 190
    Par défaut
    Citation Envoyé par wiztricks Voir le message
    à la place de "str"...

    - W
    en écrivant donc
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    rawdata.append(decode(arduino.readline()))
    ?
    Ca ne marche pas
    [Nouveau] Envie de tracer des circuits électriques : essayez le package LaTeX CircuiTikZ

    Pour créer une belle table des matières sur LibreOffice - N'oubliez pas de consulter les FAQ en cas de question !

    Envie de se lancer dans l'aventure Arduino : allez faire un tour sur ce cours.


    Ma réponse vous a plu ? Un petit vote serait sympa
      0  0

  8. #8
    Membre du Club
    Homme Profil pro
    Enseignant
    Inscrit en
    Février 2019
    Messages
    67
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Février 2019
    Messages : 67
    Points : 42
    Points
    42
    Par défaut
    Citation Envoyé par nlbmoi Voir le message
    Bonjour

    Je veux bien le lien.
    L'idéal aurait plutôt été d'avoir un tutoriel avec Calc car nous ne disposons pas d'excel au lycée.


    Voici le lien :


    A vous de voir si c'est adaptable pour Calc.

    Cordialement,
      0  0

  9. #9
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 242
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 242
    Points : 36 699
    Points
    36 699
    Par défaut
    Citation Envoyé par nlbmoi Voir le message
    en écrivant donc
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    rawdata.append(decode(arduino.readline()))
    ?
    Ca ne marche pas
    Si vous faites n'importe quoi, çà ne marchera pas.
    Relisez ce que j'ai raconté. Si çà ne suffit pas, cherchez des exemples d'utilisation de .decode sur Internet et essayez de comprendre un peu le code que vous écrivez.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels
      0  1

  10. #10
    Membre éprouvé

    Homme Profil pro
    Technicien
    Inscrit en
    Août 2013
    Messages
    437
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Technicien
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2013
    Messages : 437
    Points : 1 190
    Points
    1 190
    Par défaut
    Citation Envoyé par wiztricks Voir le message
    Si vous faites n'importe quoi, çà ne marchera pas.
    Relisez ce que j'ai raconté. Si çà ne suffit pas, cherchez des exemples d'utilisation de .decode sur Internet et essayez de comprendre un peu le code que vous écrivez.

    - W
    Si je viens demander de l'aide, c'est que j'ai un problème.
    J'ai compris (enfin je crois) la problématique que vous avez soulevé à votre première réponse : le problème vient de la conversion en str de la lecture sur le port série d'Arduino qui rajoute des caractères donc la ligne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    rawdata.append(str(arduino.readline()))
    Mais je ne comprends pas comment je peux arriver (et à quel moment en fait) à supprimer les caractères indésirables.
    J'ai bien vu que decode permettait d'enlever les textes liés à l'encodage mais je me suis toujours heurté à un mur !
    [Nouveau] Envie de tracer des circuits électriques : essayez le package LaTeX CircuiTikZ

    Pour créer une belle table des matières sur LibreOffice - N'oubliez pas de consulter les FAQ en cas de question !

    Envie de se lancer dans l'aventure Arduino : allez faire un tour sur ce cours.


    Ma réponse vous a plu ? Un petit vote serait sympa
      1  0

  11. #11
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 242
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 242
    Points : 36 699
    Points
    36 699
    Par défaut
    Salut,

    Citation Envoyé par nlbmoi Voir le message
    Si je viens demander de l'aide, c'est que j'ai un problème.
    Quel problème? Comment décoder bytes en str ou encoder un str en bytes?

    Vous n'êtes pas en train d'essayer de faire un exo. pour apprendre à programmer mais en train de mettre au point un vrai programme.
    Vous savez programmer un minimum. Si vous avez appris, retrouver dans votre cours/tuto. préféré où çà en parle pour réviser un peu et essayer de comprendre est un minimum.

    Dans le Swinnen, c'est ici.

    Mais ne vous précipitez pas dessus car vous avez d'autres problèmes à régler avant:
    est ce qu'un timeout de 1 ne serait pas trop court? Faut-il utiliser un timeout pour communiquer avec l'engin qui vous expédie les données? Si oui, comment trier les lignes incomplètes signalant timeout?


    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels
      0  0

  12. #12
    Membre expert
    Homme Profil pro
    Inscrit en
    Octobre 2011
    Messages
    2 872
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2011
    Messages : 2 872
    Points : 3 716
    Points
    3 716
    Par défaut
    Salut,

    Citation Envoyé par nlbmoi Voir le message
    J'aimerais pouvoir traiter mes données issues d'Arduino. Par diverses recherches, j'ai trouvé une solution qui fonctionne plus ou moins bien : je récupère les données du moniteur série (arduino.readline), je nettoie mon fichier obtenu pour enlever les caractères "parasites" qui sont mis (fonction nettoie), j'écris les données dans un fichier texte puis je traite les données du fichier texte.
    Je me demande pourquoi tu devrais nettoyer, pourquoi ne pas envoyer directement des données "propres" ?

    Pourrais-tu poster le code C++ qui est exécutè par l'Arduino ?
      0  0

  13. #13
    Membre éprouvé

    Homme Profil pro
    Technicien
    Inscrit en
    Août 2013
    Messages
    437
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Technicien
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2013
    Messages : 437
    Points : 1 190
    Points
    1 190
    Par défaut
    Citation Envoyé par wiztricks Voir le message

    Mais ne vous précipitez pas dessus car vous avez d'autres problèmes à régler avant:
    est ce qu'un timeout de 1 ne serait pas trop court? Faut-il utiliser un timeout pour communiquer avec l'engin qui vous expédie les données? Si oui, comment trier les lignes incomplètes signalant timeout?
    Je vais être honnête : je n'en ai aucune idée. J'ai eu du mal à trouver des informations pour récupérer dans le moniteur série d'Arduino à l'aide de Python --> sur celui que j'ai trouvé, que j'ai testé, j'ai obtenu des résultats satisfaisants.
    C'est en voulant aller plus loin que je me suis heurté à quelques problèmes, sans doute dû au fait que j'ai pris un code brut de décoffrage.
    [Nouveau] Envie de tracer des circuits électriques : essayez le package LaTeX CircuiTikZ

    Pour créer une belle table des matières sur LibreOffice - N'oubliez pas de consulter les FAQ en cas de question !

    Envie de se lancer dans l'aventure Arduino : allez faire un tour sur ce cours.


    Ma réponse vous a plu ? Un petit vote serait sympa
      0  0

  14. #14
    Membre éprouvé

    Homme Profil pro
    Technicien
    Inscrit en
    Août 2013
    Messages
    437
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Technicien
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2013
    Messages : 437
    Points : 1 190
    Points
    1 190
    Par défaut
    Citation Envoyé par Beginner. Voir le message
    Salut,

    Je me demande pourquoi tu devrais nettoyer, pourquoi ne pas envoyer directement des données "propres" ?

    Pourrais-tu poster le code C++ qui est exécutè par l'Arduino ?
    Salut

    Mon code Arduino :
    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
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    /* ----------------------------------------------------------------------
       Auteur : Nicolas Le Boulaire
     
       Date de mise à jour : 9 avril 2020
     
       Programme pour étudier la charge d'un condensateur
       préalablement déchargé (programmée par Arduino)
     
       Entrée : broche du "générateur" 5V
     
       Sortie : broche de mesure de la tenonsion aux bornes de C
     
       Remarques : Pour le bon fonctionnement du programme, il faut
       sélectionner "Pas de fin de ligne" dans le moniteur série
    */
     
     
    // Déclaration des variables du programme
    unsigned long baud = 115200; // 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=1 ; // période d'échantillonnage en ms
    int dureeAcquisition=50 ; // durée totale de l'acquisition  en s
     
    unsigned long tempsZero;
    unsigned long tempsCourant;
    int topDepart = 1; //variable pour lancer l'acquisiti
    String envoi;
     
    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);
      tempsPrec = millis();
      tempsZero = millis();
      envoi = "0";
     
      //configure la broche commandePin en tant que sortie
      pinMode(chargeCondo, OUTPUT) ;
     
      //on décharge le condensateur en le mettant à 0V
      digitalWrite(chargeCondo, LOW) ;
     
      //Affichage d'un texte pour présenter le programme
      //Serial.println("*******   Etude de la charge d'un condensateur *******");
      //Serial.println("");
     
      //Affichage d'un texte pour spécifier d'attendre
      //Serial.println("***   Attendre 3 secondes   ***");
      //Serial.println("");
     
      //on attend 3sec pour être sur de l'avoir déchargé
      delay(delai) ;
            tempsPrec = 0;
          tempsZero = millis();
          //Serial.print("t");  // donne la date en seconde
          //Serial.print(';');
          //Serial.println("Uc"); // donne la valeur recalculée de la tension
          //Serial.print("s");  // donne la date en seconde
          //Serial.print(';');
          //Serial.println("V"); // donne la valeur recalculée de la tension
     
    }
     
    //  Boucle principale
    void loop() 
    {
      tempsCourant = millis() - tempsZero;
      if (  topDepart == 0) {
        reglages();
      } else {
        if (tempsCourant <= dureeAcquisition) {
          if (tempsCourant >= tempsPrec) {
            lecture();
          }
        }
      }
      Serial.flush();
    }
     
    void reglages()
    {
      while (topDepart == 0) {
        envoi = Serial.readString();
     
        Serial.print("Saisir la période d'échantillonnage (en ms) : ");
        while (Serial.available() == 0 );
        if (Serial.available() != 0)
        {
          timeRes = Serial.parseInt(); //on enregistre la valeur saisie dans timeRes
          Serial.println(timeRes);
          delay(100); //délai de temporisation
        }
     
        Serial.print("Saisir la durée d'acquisition (en ms) : ");
        while (Serial.available() == 0 );
        if (Serial.available() != 0)
        {
          dureeAcquisition = Serial.parseInt(); //on enregistre la valeur saisie dans dureeAcquisition
          Serial.println(dureeAcquisition);
          delay(100); //délai de temporisation
        }
     
        Serial.println("Saisir S pour lancer l'acquisition : ");
        while (Serial.available() == 0 );
        if (Serial.available() != 0)
        {
          topDepart = 1;
          tempsPrec = 0;
          tempsZero = millis();
          Serial.print("t");  // donne la date en seconde
          Serial.print(';');
          Serial.println("Uc"); // donne la valeur recalculée de la tension
          Serial.print("s");  // donne la date en seconde
          Serial.print(';');
          Serial.println("V"); // donne la valeur recalculée de la tension
        }
      }
    }
     
    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); // donne la date en seconde
      Serial.print(';');
      Serial.println(tension, 2); // donne la valeur recalculée de tension aux bornes de C
      tempsPrec += timeRes;
    }
    [Nouveau] Envie de tracer des circuits électriques : essayez le package LaTeX CircuiTikZ

    Pour créer une belle table des matières sur LibreOffice - N'oubliez pas de consulter les FAQ en cas de question !

    Envie de se lancer dans l'aventure Arduino : allez faire un tour sur ce cours.


    Ma réponse vous a plu ? Un petit vote serait sympa
      1  0

  15. #15
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 242
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 242
    Points : 36 699
    Points
    36 699
    Par défaut
    Salut,

    Citation Envoyé par nlbmoi Voir le message
    Je vais être honnête : je n'en ai aucune idée. J'ai eu du mal à trouver des informations pour récupérer dans le moniteur série d'Arduino à l'aide de Python --> sur celui que j'ai trouvé, que j'ai testé, j'ai obtenu des résultats satisfaisants..
    Certes mais on ne peut pas coder sans une idée du protocole de communication à respecter entre les équipements.
    A défaut difficile de savoir si les résultats obtenus sont corrects, complets,... puisqu'on ne sait pas ce qu'on doit construire pour les obtenir.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels
      0  0

  16. #16
    Membre expert
    Homme Profil pro
    Inscrit en
    Octobre 2011
    Messages
    2 872
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2011
    Messages : 2 872
    Points : 3 716
    Points
    3 716
    Par défaut
    Salut,
    Citation Envoyé par nlbmoi Voir le message
    Ensuite, j'aimerais savoir si une autre méthode pour récupérer les données d'Arduino existait plus "jolie" : je trouve un peu fastidieuse et poussive cette méthode (avec le passage par un fichier texte).
    Ben en fait les données provenant de l'Arduino tu les récupères bel et bien et ce avant l'écriture dans un fichier... Ces données tu les stockes dans la liste rawdata, tu pourrais donc utiliser directement cette liste sans passer par un fichier...

    En fait si tu passes par un fichier ce n'est pas pour récupérer les données d'Arduino (puisqu'elles sont déjà dans la liste rawdata) mais c'est pour pouvoir utiliser la fonction np.loadtxt comme cela : temps,tension=np.loadtxt("data.txt", delimiter=";",unpack=True) or tu n'es pas obligé d'utiliser cette fonction pour obtenir les points (temps,tension).

    Citation Envoyé par nlbmoi Voir le message
    J'ai compris (enfin je crois) la problématique que vous avez soulevé à votre première réponse : le problème vient de la conversion en str de la lecture sur le port série d'Arduino qui rajoute des caractères donc la ligne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    rawdata.append(str(arduino.readline()))
    Ce n'est pas à cause de cela que tu as des caractères vides et d'ailleurs ce problème de caractères indésirables (à ne pas confondre avec le problème des caractères vides) tu l'as réglé avec la fonction nettoie mais c'est vrai qu'il y a plus simple cf.ci-après...

    Citation Envoyé par nlbmoi Voir le message
    Mais je ne comprends pas comment je peux arriver (et à quel moment en fait) à supprimer les caractères indésirables.
    J'ai bien vu que decode permettait d'enlever les textes liés à l'encodage mais je me suis toujours heurté à un mur !
    Comme déjà dit tu supprimes déjà ces caractères indésirables avec la fonction nettoie :
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    def nettoie(L):
        newL=[]
        for i in range (len(L)):
            temp=L[i][2:]
            newL.append(temp[:-5])
        return newL

    Dans la liste tu as des données comme ça : "b'0.000;0.12\\r\\n'" et ta fonction permet d'obtenir ça : "0.000;0.12" c'est-à-dire tu supprimes la lettre b,les deux quotes, le retour chariot et le retour à la ligne...

    Mais tu peux faire ça plus facilement au moment où tu remplies la liste rawdata en faisant cela : data_read = arduino.readline().decode()[:-2] juste avant rawdata.append(data_read)...


    PS : Le problème des caractères vides c'est une autre histoire que la fonction nettoie ne règle pas...
      0  0

  17. #17
    Membre expert
    Homme Profil pro
    Inscrit en
    Octobre 2011
    Messages
    2 872
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2011
    Messages : 2 872
    Points : 3 716
    Points
    3 716
    Par défaut
    Je continue cette fois avec ton "principal problème" (présence de caractères vides) pour les autres voir message précédent...

    Citation Envoyé par nlbmoi Voir le message
    Mon principal problème vient de la présence de caractères vides dans le fichier de nettoyage.
    Par exemple : ['', '', '0.000;0.06', '0.001;0.62', '0.003;1.12', '0.004;1.56', '0.005;1.95', '0.007;2.29', '0.008;2.59', '', '', '', '', '', '', '', '', '', '']
    Là c'est plus compliqué...

    Tout d'abord une chose qui n'est pas évidente à voir au premier abord c'est que ce n'est pas l'Arduino (via le port série) qui envoi ces caractères vides...

    1- Les premiers caractères vides sont dus à un problème de synchronisation :

    Dans le code C++ tu commences par décharger le condensateur durant un certain temps (réglable par la variable delai) or le problème c'est que pendant ce temps-là coté python tu es déjà en "mode attende" de donnée du port série... On pourrait se dire que la fonction arduino.readline attendra que l'arduino envoi des données avant de commencer à remplir la liste rawdata mais ce n'est pas le cas car tu as fixé un timeout à 1s cela signifie qu'au bout de 1s la fonction cesse d'attendre bien que l'arduino n'ait encore rien envoyé du coup cette fonction renvoie une chaine vide qui est par la suite ajouté à la liste rawdata...

    Plus la durée de décharge est longue et plus il y aura des caractères vides au début de la liste...

    Tu peux régler ce problème en fixant un plus grand timeout ou en le fixant à None (la fonction attend indéfiniment) mais le mieux serait de synchroniser le code C++ et le code Python : coté python tu envois une commande pour lancer l'acquisition coté Arduino...

    --> D'ailleurs dans le code C++ il y a la fonction réglage qui fait entre autres cela mais tu l'as court-circuitée ---> elle n'est jamais exécutée...


    2- Les caractères vides à la fin de la liste sont dus à une mauvaise gestion :

    Tu fixes une durée d'acquisition (plutôt qu'un nombre de points) du coup la fin de l'acquisition est conditionnée à une durée ce qui est une mauvaise idée dans ton cas car le nombre de points que tu va acquérir n'est pas simple à évaluer, il dépend de trop de choses or tu as besoin du nombre exacte coté python... C'est l'erreur dans l'évaluation de ce nombre qui cause la présence des caractères vides à la fin de la liste...

    Dans ton code C++ tu fixes la période d'échantillonnage (timeRes = 1;) à 1 ms et la durée totale de l'acquisition à 50 ms (int dureeAcquisition = 50;) du coup logiquement tu t'attends à acquérir 50 points mais ce n'est pas le cas...

    La raison c'est que les fonctions Serial.print, Serial.println consomment trop de temps au point que l'acquisition d'un point prend plus qu'une milliseconde... Du coup le nombre de points acquis et envoyés est inférieure à 50 or ta boucle coté python essaye de lire 50 données donc pour chaque donnée non envoyée tu auras une chaines vide...

    ---> Il faut donc que tu changes de stratégie : on fixe le nombre de points et la période d'échantillonnage voulue sachant que cette dernière ne sera pas forcément respectée mais au moins ta courbe sera bonne car les temps seront bons (mais intervalle entre deux temps ne sera pas forcément égal à la période d'échantillonnage).


    Mais bien sûr plus tu réduis les temps d’exécution et mieux la période d'échantillonnage sera respectée...

    Une chose simple pour faire cela --> augmenter le baudrate : tu peux mettre un million à la place de 115200. Tu peux aussi réduire au minimum ce que tu envois et éviter certains calculs coté C++ pour les faire coté Python...

    Tu peux aussi (coté C++) stocker les mesures en mémoire dans un tableau et ne les envoyer qu'à la fin de l'acquisition, l’inconvénient étant que tu ne peux plus exploiter les données de l’acquisition en direct/en live (mais de toute façon tu ne fais pas du live, tu n'affiches pas la courbe en direct par exemple) et bien sûr la mémoire est limitée donc le nombre de points sera limité...

    Citation Envoyé par nlbmoi Voir le message
    Mais je ne comprends pas comment je peux arriver (et à quel moment en fait) à supprimer les caractères indésirables.
    Si tu as besoin d'un exemple de code avec la solution la plus simple fais-le nous savoir...
    Il faudra d'ailleurs faire un peu de ménage...
      0  0

  18. #18
    Membre éprouvé

    Homme Profil pro
    Technicien
    Inscrit en
    Août 2013
    Messages
    437
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Technicien
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2013
    Messages : 437
    Points : 1 190
    Points
    1 190
    Par défaut
    Bonsoir Beginner,

    J'ai lu avec attention ta réponse qui a aiguisé ma curiosité.
    Pour les caractères vides, j'ai "blousé" dans le code Python en ne prenant comme valeur intéressante que celle qui commence à la 3ème ligne : ce n'est pas propre mais dans un premier temps, ça suffit à démarrer.
    Pour les caractères vides, en fait, je comptais à l'aide d'un compteur avec un nombre défini par avance qui n'avait rien à voir avec les paramètres expérimentaux qui intéressent (comme tu l'as soulevé).

    J'ai modifié un peu le programme python (et de la même manière, à l'inverse, le code arduino) en donnant les paramètres d'acquisition via Python :
    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
    # Saisie par l'utilisateur des paramètres expérimentaux
    time.sleep(3)
    periode=input("Saisir la période d'échantillonnage (en ms) : ")
    arduino.write(periode.encode("ascii"))
    time.sleep(0.1)
    duree=input("Saisir la durée totale (en ms) : ")
    arduino.write(duree.encode("ascii"))
    time.sleep(0.1)
    acquisition=input("Saisir S pour lancer l'acquisition")
    arduino.write(acquisition.encode("ascii"))
     
    #Initialisation des variables
    rawdata=[]
    compt=0
    fin_compteur=int(duree)/int(periode)+3 #le +3 prend en compte les lignes introduites par Arduino
     
    #Réception et stockage des données
    while compt<fin_compteur:
        rawdata.append(str(arduino.readline()))
        compt+=1
    J'avoue que ce bidouillage n'est pas propre dans la programmation mais je suis débutant et je fais avec les moyens dont je dispose : je suis prêt à écouter les conseils et les améliorations du code.

    Toutes tes remarques sont pleines de bon sens : si je comprends bien, pour améliorer la transmission des données, si je ne récupérais que les données analogiques (
    Code arduino : Sélectionner tout - Visualiser dans une fenêtre à part
    analogRead(mesure)
    et que je faisais le calcul de la tension dans python, ce serait plus rapide ? Et pour améliorer encore, je stocke tous les couples (temps,mesure) dans un tableau Arduino avant, en fin d'acquisition, les faire afficher pour faire le traitement dans Python ?
    [Nouveau] Envie de tracer des circuits électriques : essayez le package LaTeX CircuiTikZ

    Pour créer une belle table des matières sur LibreOffice - N'oubliez pas de consulter les FAQ en cas de question !

    Envie de se lancer dans l'aventure Arduino : allez faire un tour sur ce cours.


    Ma réponse vous a plu ? Un petit vote serait sympa
      0  0

  19. #19
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 242
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 242
    Points : 36 699
    Points
    36 699
    Par défaut
    Salut,

    Citation Envoyé par nlbmoi Voir le message
    J'avoue que ce bidouillage n'est pas propre dans la programmation mais je suis débutant et je fais avec les moyens dont je dispose : je suis prêt à écouter les conseils et les améliorations du code.
    C'est pas tellement le code qu'il faut améliorer mais sa conception.
    Vous pourriez partir avec un programme "serveur" côté Arduino qui écoute ce qui est expédié par Python (des "commandes") et qui lui retourne un status (histoire de synchroniser les 2).
    Vous pourriez avoir la commande "SETUP x y z\n" qui expédie des paramètres et attend la réponse "OK\n" de l'Arduino.

    Puis un READDATA auquel le serveur retourne un nombre de mesures, un status, suivi des n mesures qu'il a pu faire depuis le READDATA précédent. Le "status" pouvant servir à signaler que le temps écoulé depuis le READDATA précédent était trop long et qu'on n'a pas toutes les mesures.

    Bon j'invente pour vous donner des idées du boulot qu'il y a à faire (avant de coder).
    Sinon vous allez juste avoir un tas de nouille côté Arduino et un autre tas de nouilles côté Python et beaucoup d'ennuis pour faire fonctionner le tout de façon fiable.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels
      0  0

  20. #20
    Membre expert
    Homme Profil pro
    Inscrit en
    Octobre 2011
    Messages
    2 872
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2011
    Messages : 2 872
    Points : 3 716
    Points
    3 716
    Par défaut
    Salut,

    Citation Envoyé par nlbmoi Voir le message
    Pour les caractères vides, j'ai "blousé" dans le code Python en ne prenant comme valeur intéressante que celle qui commence à la 3ème ligne : ce n'est pas propre mais dans un premier temps, ça suffit à démarrer.
    Alors oui tu peux éviter les premiers caractères vides mais il faut savoir que leur nombre n'est pas forcément égal à 2, cela dépend de plusieurs choses du coup cela oblige à faire attention à plusieurs choses. En plus il y a aussi les caractères vides qui sont à la fin de la liste dont le nombre peut aussi varier...

    Dans ces conditions il est difficile d'évaluer le nombre de mesures effectuées, par exemple si on prend tes premiers codes (C++ et Python) avec la période d'échantillonnage (timeRes = 1;) fixée à 1 ms et la durée totale de l'acquisition fixée à 50 ms (int dureeAcquisition = 50;) alors tu obtiens une liste de 50 éléments contenant 38 mesures* au lieu des 50 attendues et 12 caractères vides (2 au début et 10 à la fin).

    Si tu changes les paramètres ou si tu modifies certaines parties de ton code eh bien ce nombre changera...
    Bon à la limite si ce qui compte pour toi c'est la durée d'acquisition et non le nombre de points acquis alors il suffit d'ajouter coté Python un traitement des caractères vides...

    *Une remarque si on regarde les premières mesures que tu as postées on constate que l'intervalle entre deux temps n'est pas toujours égale à 1 ms...

    Citation Envoyé par nlbmoi Voir le message
    J'ai modifié un peu le programme python (et de la même manière, à l'inverse, le code arduino) en donnant les paramètres d'acquisition via Python :
    Tu n'as pas posté le nouveau code C++, est-ce que les deux codes fonctionnent bien ensemble ?

    Citation Envoyé par nlbmoi Voir le message
    J'avoue que ce bidouillage n'est pas propre dans la programmation mais je suis débutant et je fais avec les moyens dont je dispose : je suis prêt à écouter les conseils et les améliorations du code.
    Juste quelques remarques :

    - Je pense qu'on peut se passer des pauses avec time.sleep() car le temps que prendra l'utilisateur pour lire la consigne et saisir le paramètre demandé sera probablement supérieur et suffisant...

    - Comme je l'avais suggéré ce serait plus simple de remplacer cette ligne rawdata.append(str(arduino.readline())) par rawdata.append(arduino.readline().decode()[:-2]) cela t’évitera de devoir nettoyer la liste rawdata avec la fonction nettoie...

    - Ce serait peut-être mieux d'éviter (même si ça marche) d'avoir un float pour fin_compteur... Il suffit juste d'ajouter un caractère "/" pour que ce soit un entier :fin_compteur=int(duree)/int(periode)+3--> fin_compteur=int(duree)//int(periode)+3...

    Et là tu ajoutes 3 je suppose pour tenir compte des deux premiers caractères vides mais ce n'est pas vraiment utile dans ton cas, tu vas juste te retrouver avec plus de caractères vides à la fin de la liste ... En effet avec les paramètres rappelés ci-dessus l'Arduino n’envoie que 38 mesures au lieu des 50 attendues... Cette fois fin_compteur est égal à 53, tu obtiendras donc une liste de 53 éléments contenant 38 mesures et 15 caractères vides (2 au début et 13 à la fin).

    Pour éviter cela il faudrait fixer le nombre de mesures (effectués et envoyées par l'Arduino) mais comme déjà dit, dans ton C++ tu ne fixes pas ce nombre mais tu fixes une durée d'acquisition du coup la fin de l'acquisition est conditionnée à la durée d'acquisition et non au nombre de mesures qui est du coup difficile à évaluer...

    ---> Pour infos il est possible de fixer un nombre de mesures, voici un exemple de code C++ avec le code Python (j'ai repris certaines parties de tes codes...) :

    Code C++ : 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
     
    // 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 = 1;    // période d'échantillonnage en ms
    int nbrPoints = 50; // Nombre de points
    unsigned long cpt = 1;
     
    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();
    }
     
    //  Boucle principale
    void loop()
    {        
        tempsCourant = millis() - tempsZero;
        if (tempsCourant >= tempsPrec && cpt <= nbrPoints)
        {
            lecture();
            cpt++;
        }     
    }
     
    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();
    }

    Code python : 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
    # Importation des modules utilisés
    import serial
     
    # Initialisation des variables
    arduino = None
    rawdata = []
    nbrPoints = 50
     
    def acuisition(nbrPoints):
        # Ouverture de la liaison série
        try:
            arduino = serial.Serial("COM4", baudrate=115200, timeout=3)
        except Exception as e:
            print("Vérifier le port série:", e)
            return
     
        # 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))

    Citation Envoyé par nlbmoi Voir le message
    Toutes tes remarques sont pleines de bon sens : si je comprends bien, pour améliorer la transmission des données, si je ne récupérais que les données analogiques (
    Code arduino : Sélectionner tout - Visualiser dans une fenêtre à part
    analogRead(mesure)
    et que je faisais le calcul de la tension dans python, ce serait plus rapide ?
    Oui ce serait mieux le but étant que le code C++ exécuté entre deux mesures prenne le moins de temps possible car c'est de ce temps d'exécution que la fréquence max d'échantillonnage dépend.

    Coté python ces calculs prendront aussi un certain temps mais là c'est à l'échelle humaine, l'utilisateur ne se rendra probablement pas compte et cela n'a pas d'influence sur la fréquence max d'échantillonnage (c'est ça l'important)...

    Mais il n'y a pas que le temps des calculs, il y a aussi et surtout le temps de formatage des données et le temps de transmission via le port série, plus il y a de donnée plus cela prendra du temps...

    Par exemple la fonction analogRead que tu prend en exemple revoie un entier codé sur 10 bits on pourrait donc se contenter d'envoyer que deux octets... Mais quand on fait cela :
    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    tension = analogRead(mesureTension) * 5.0 / 1024; // mesure analogique et conversion en tension    
       ...
    Serial.println(tension, 2)
    Ici tension est un float qui est ensuite converti en string (en interne quelque part dans la fonction Serial.println) donc on envoi plus de données et en plus il y a une conversion qui prend un certain temps (avec un formatage comme les 2 chiffres après la virgule/le point)...

    Citation Envoyé par nlbmoi Voir le message
    Et pour améliorer encore, je stocke tous les couples (temps,mesure) dans un tableau Arduino avant, en fin d'acquisition, les faire afficher pour faire le traitement dans Python ?
    Oui si tu as besoin d'augmenter le plus possible la fréquence max d'échantillonnage sinon pas la peine car il y a quand même des inconvénients : mémoire limitée donc nombre de mesures limité et tu dois attendre la fin de l’acquisition pour exploiter les données, tu ne peux plus les exploiter en direct/en live...

    Et comme déjà dit : une chose simple (alors pourquoi s'en priver ?) pour faire cela --> augmenter le baudrate : tu peux mettre un million à la place de 115200...

    Et il faut savoir que la fonction Serial.flush prend du temps... En la supprimant de ton code la période d'échantillonnage d'une milliseconde est beaucoup mieux respectée...
      0  0

Discussions similaires

  1. HELP récupération données formulaire
    Par liichiii dans le forum Général JavaScript
    Réponses: 1
    Dernier message: 17/05/2006, 01h29
  2. probleme récupération donnée dans script xsl
    Par jmacdev dans le forum XSL/XSLT/XPATH
    Réponses: 2
    Dernier message: 12/05/2006, 18h37
  3. Récupération données formulaire en php5
    Par jcaspar dans le forum Langage
    Réponses: 1
    Dernier message: 08/03/2006, 21h45
  4. Récupération données en registre
    Par cgoln dans le forum Général JavaScript
    Réponses: 1
    Dernier message: 02/12/2005, 12h05
  5. Réponses: 3
    Dernier message: 13/09/2005, 13h21

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo