Bonjour, cliquez-ici pour vous inscrire et participer au forum.
  • Login:



+ Répondre à la discussion
Page 1 sur 2 1 DernièreDernière
Affichage des résultats 1 à 15 sur 21

[PYTHON] Transformée de Fourrier discrète sur un signal déjà échantillonné

  1. Shantorian

    Date d'inscription
    octobre 2014
    Messages
    135

    [PYTHON] Transformée de Fourrier discrète sur un signal déjà échantillonné

    Bonjour à tous,

    Après des heures de recherches, je ne trouve pas de réponses à mon problème.

    J'exploite et je traite un signal reçu sur la voie série, rien de bien compliqué.

    Je souhaite en faire une transformée de Fourrier.

    Les valeurs recues sont des tensions analogiques déjà échantillonnées par un CAN 16 bits, à 25Hz. Je convertis ces valeurs en un signal d'angle en fonction du temps.

    J'ai donc un tableau de valeurs et un tableau des temps correspondants.

    Comment à partir de ces deux tableaux faire un FFT grâces aux bibliothèques disponibles sous python ?

    Avec un signal continu, et un échantillonnage j'ai trouvé ce programme que je comprends à peu près ( pas assez pour l'adapter à mon problème).

    Sauriez-vous m'aider ?

    Merci d'avance !

    Code:
    # programme d'experimentation FFT FFTExperience1-0
    # Dominique Lefebvre pour TangenteX.com
    # 12 aout 2014
    #
    
    # importation des librairies
    from numpy import pi, sin, linspace, log10
    from numpy.fft import fft, fftfreq
    import matplotlib.pyplot as plt       
    
    # d�finition des constantes du signal
    K = 2*pi       # facteur conversion p�riode/fr�quence
    A0 = 4         # amplitude fr�quence fondamentale
    A1 = 8         # amplitude premi�re harmonique
    f0 = 2         # fr�quence fondamentale (Hz)
    f1 = 8         # fr�quence premi�re harmonique (Hz)
    
    # d�finition temporelle du signal
    t0 = 0         # d�but de l'acquisition du signal
    t1 = 10        # fin de l'acquisition (s)
    
    # d�finition des param�tres d'�chantillonnage
    FreqEch = 1024                  # fr�quence d'�chantillonage
    PerEch = 1./FreqEch             # p�riode d'�chantillonnage
    N = FreqEch*(t1 - t0)           # nombre de points �chantillonn�s sur l'intervalle
    
    # d�finition du temps
    t = linspace(t0, t1, N)
    
    # d�finition du signal
    signal = A0*sin(f0*K*t) + A1*sin(f1*K*t)
    
    # d�finition des donn�es de FFT
    FenAcq = signal.size             # taille de la fenetre temporelle
        
    # calcul de la TFD par l'algo de FFT
    signal_FFT = abs(fft(signal))    # on ne r�cup�re que les composantes r�elles
    
    # r�cup�ration du domaine fr�quentiel
    signal_freq = fftfreq(FenAcq,PerEch)
    
    # extraction des valeurs r�elles de la FFT et du domaine fr�quentiel
    signal_FFT = signal_FFT[0:len(signal_FFT)//2]
    signal_freq = signal_freq[0:len(signal_freq)//2]
    
    #affichage du signal
    plt.subplot(211)
    plt.title('Signal et son spectre')
    plt.ylim(-(A1+5), A1+5)
    plt.plot(t, signal)
    plt.xlabel('Temps (s)'); plt.ylabel('Amplitude')
    
    #affichage du spectre du signal
    plt.subplot(212)
    plt.xlim(0,f1+5)
    plt.plot(signal_freq,signal_FFT)
    plt.xlabel('Frequence (Hz)'); plt.ylabel('Amplitude')
    #plt.title('Signal et son spectre')
    plt.show()
    Voilà ce que je veux pour mon signal : figure_1.png

    Voici mon code python et l'allure de mon signal :

    Code:
    import serial 
    import matplotlib.pyplot as plt
    import time
    import numpy as np
    from numpy.fft import fft, fftfreq
     
    signal=[]
    temps=[]
     
    serie=serial.Serial('COM5',9600) 	# ouvre une liaison serie en 9600bps											
    
    plt.style.use('bmh')
    plt.ylabel("Delta (°)")
    plt.xlabel("Temps (sec)")
     
    plt.ion() 			# on entre en mode interactif
    start=time.time()	# mesure de l'instant initial
    
    i=0
    while (i<400):
    
        mesure1, mesure2 = map(float, serie.readline().split()) #lit la donnee sur la laison serie
        
        angle1 = mesure1 / (1/180)  #conversion tension - degrés (2V = 360°)
        angle2 = mesure2 / (1/180)
        
        if i == 3:       #les premières mesures ne sont pas fiables
            ref = (angle2-(angle1)*(1/25)) #différence entre theta et theta_theorique
        
        
        if abs(angle1) <= 1: 
            ref = (angle2-(angle1)*(1/25))
        
        instant=time.time()-start	# calcul du temps ecoule depuis l'instant initial
        if i >= 3:                   
        
        
            temps.append(instant)		# ajout de instant a la liste des temps
            valeur = (angle2-(angle1)*(1/25))-ref #on veut un écart autour de 0
            if abs(valeur) >= 1.5:
                valeur = 0
            
            signal.append(valeur) 
            print(valeur,instant)      # affiche dans la console les coordonnees du point
            
            
        plt.plot(temps,signal,marker='')  # trace la courbe
        plt.draw()                     # affiche la courbe en mode interactif
        i=i+1
        
    
    plt.show()
    plt.ioff() 		# on quitte le mode interactif pour rendre la main a l'utilisateur sur la courbe
    figure_1bis.jpg

    -----

    Dernière modification par Shantorian ; 28/09/2017 à 20h59.
     


    • Publicité



  2. CM63

    Date d'inscription
    juin 2006
    Localisation
    Un peu au large de la faille de Limagne
    Âge
    64
    Messages
    3 226

    Re : [PYTHON] Transformée de Fourrier discrète sur un signal déjà échantillonné

    Bonjour,

    Juste une précision (car je n'en connais pas davantage sur la question) : pour utiliser la FFT il faut que ton signal soit échantillonné sur un nombre de points qui soit une puissance de 2 : 2048 points ou 4096 points, etc. Si on ecrit les formules on s'aperçoit qu'il y a des termes qu'on calcule plusieurs fois, la technique de la FFT s’arrange pour ne les calculer qu'une fois.
     

  3. polo974

    Date d'inscription
    février 2007
    Messages
    8 319

    Re : [PYTHON] Transformée de Fourrier discrète sur un signal déjà échantillonné

    Citation Envoyé par Shantorian Voir le message
    Bonjour à tous,
    ...
    Je souhaite en faire une transformée de Fourrier.

    Les valeurs recues sont des tensions analogiques déjà échantillonnées par un CAN 16 bits, à 25Hz. Je convertis ces valeurs en un signal d'angle en fonction du temps.

    J'ai donc un tableau de valeurs et un tableau des temps correspondants.
    ...
    Bonjour,
    d'un coté, tu dis avoir un signal échantillonné à 25 Hz, de l'autre tu as 2 tableaux dont l'un "des temps correspondants".
    la question est as-tu systématiquement un échantillon tous les 25 ième de seconde?
    si oui, le tableau temps n'apporte rien.
    si non, il faut l'utiliser pour interpoler les "points manquants".

    selon le temps d'échantillonnage (et donc le nombre d'échantillons),tu pourras avoir une résolution en fréquence plus ou moins grande.

    à part ça, il faut bien penser à appliquer un fenêtrage à ton échantillon avant de le jeter dans la fft, sinon, les ruptures en bout de tableau vont te polluer l'analyse.
    Le mieux est l'ennemi du bien, et c'est bien mieux comme ça...
     

  4. Shantorian

    Date d'inscription
    octobre 2014
    Messages
    135

    Re : [PYTHON] Transformée de Fourrier discrète sur un signal déjà échantillonné

    Merci de m'avoir répondu.

    Non le problème c'est que le signal issu du CAN est échantillonné, seulement les irrégularités des transmissions du la voie série, la vitesse de traitement (arduino + python) font que je n'ai pas une mesure exactement toutes les 1/25 sec..

    Je ne vois pas trop comment faire, merci pour la précaution du fenêtrage.

    Ce type de calcul est-il plus simple avec Matlab, ou d'autres logiciels capables de communiquer sur la voie série ? Je sais seulement coder un peu en python et en C.
     

  5. Jack

    Date d'inscription
    avril 2003
    Localisation
    Metz
    Messages
    16 104

    Re : [PYTHON] Transformée de Fourrier discrète sur un signal déjà échantillonné

    Non le problème c'est que le signal issu du CAN est échantillonné, seulement les irrégularités des transmissions du la voie série, la vitesse de traitement (arduino + python) font que je n'ai pas une mesure exactement toutes les 1/25 sec..
    Ca n'a aucun rapport: si le convertisseur échantillonne à 25 Hz, les mesures sont effectués toutes les 1/25èmes de secondes à la précision de l'horloge du convertisseur.
     


    • Publicité



  6. polo974

    Date d'inscription
    février 2007
    Messages
    8 319

    Re : [PYTHON] Transformée de Fourrier discrète sur un signal déjà échantillonné

    Bonjour,
    je n'avais pas lu ton code pour le moment.
    je vois que tu reçois des couples de valeurs, à quoi correspondent-elles (grandeurs et unités)?
    tu fais des calculs affreux:

    angle2 = mesure2 / (1/180) # heureusement qu'en pyhton3 (1/180) ne donne pas 0 comme python2...
    angle2 *= 180 # c'est plus clair, non ? ? ? en tout cas ça économise 2 divisions (rappelez-vous comme c'est pénible une division...)

    sinon, tu pouvais déclarer hors la boucle
    kangulaire=180.

    et faire ensuite dans la boucle
    angle2 *= kangulaire

    et puis:
    ref = (angle2-(angle1)*(1/25))
    tu divises (seulement) angle1 par 25 est-ce bien ce que tu veux faire ?
    ou bien est-ce 1/25 pour le 25 échantillons par seconde, qui doit s'appliquer partout

    du coup, autant le mettre dans le kangulaire...
    kangulaire = 180./25.

    la liste temps est totalement inutile (sauf à vouloir détecter un endormissement du PC...).

    le pb est comment détectes-tu un dépassement de buffer coté arduino (car peu de mémoire dans ces petits trucs, et parfois le PC s'occupe d'autre chose)... (il faut espérer que ce n'est pas pour une mesure destructive (donc lourde à reproduire)).
    Le mieux est l'ennemi du bien, et c'est bien mieux comme ça...
     

  7. Shantorian

    Date d'inscription
    octobre 2014
    Messages
    135

    Re : [PYTHON] Transformée de Fourrier discrète sur un signal déjà échantillonné

    Citation Envoyé par Jack Voir le message
    Ca n'a aucun rapport: si le convertisseur échantillonne à 25 Hz, les mesures sont effectués toutes les 1/25èmes de secondes à la précision de l'horloge du convertisseur.
    Je suis d'accord, mais je constate que la période temporelle n'est pas exactement de 1/25 secondes de manière assez irrégulière.

    polo974 :

    Les valeurs sont des tensions lues avec un potentiomètre, converties en angles car je mesures des irrégularités de transmissions entre engrenages.

    En effet, j'aurais du y penser : j'ai recrée un fausse liste des temps (avec le bon pas constant théorique) et ça fonctionne (le résultat n'est pas très exploitable car mon tableau de valeurs n'est pas assez important pour faire apparaître des périodicité je pense. Néanmoins on distingue des pics prédits par l’étude théorique du système donc a priori l’algorithme me renvoie une bonne FFT malgré le fait que les valeurs ne soient pas mesurées tous les 1/25ème de sec.. )


    FFT1.jpg
    Dernière modification par Shantorian ; 10/10/2017 à 22h54.
     

  8. Jack

    Date d'inscription
    avril 2003
    Localisation
    Metz
    Messages
    16 104

    Re : [PYTHON] Transformée de Fourrier discrète sur un signal déjà échantillonné

    Citation Envoyé par Shantorian Voir le message
    Je suis d'accord, mais je constate que la période temporelle n'est pas exactement de 1/25 secondes de manière assez irrégulière.
    Dans ce cas, c'est que tu as mal configuré ton ADC ou son horloge. C'est tout l'intérêt d'utiliser une horloge hardware pour ce type d'opération: la période est invariablement la même pour tous les échantillons.

    PS: à quoi vois-tu que la période varie?
     

  9. Shantorian

    Date d'inscription
    octobre 2014
    Messages
    135

    Re : [PYTHON] Transformée de Fourrier discrète sur un signal déjà échantillonné

    A la sortie de l'ADC, la période est parfaite, mais dans mon algo c'est python qui mesure la période en mesurant le temps entre deux données reçues sur la voie série. Mon CAN est bien un circuit physique avec une horloge externe, ce n'est pas l'arduino qui joue le role de CAN (son CAN est de seulement 8bits)


    Je vois qu'elle varie car quand je prends mon tableau temps dans le code et que je fais temps[i+1]-temps[i] ça ne fait jamais là même chose (à quelques millièmes de secondes, mais je travaille avec des valeurs faibles donc ça peut jouer peut être ?)
    Dernière modification par Shantorian ; 10/10/2017 à 23h50.
     

  10. Jack

    Date d'inscription
    avril 2003
    Localisation
    Metz
    Messages
    16 104

    Re : [PYTHON] Transformée de Fourrier discrète sur un signal déjà échantillonné

    Citation Envoyé par Shantorian Voir le message
    A la sortie de l'ADC, la période est parfaite, mais dans mon algo c'est python qui mesure la période en mesurant le temps entre deux données reçues sur la voie série.
    C'est une très mauvaise idée qui ne présente aucun intérêt. Tu n'as pas besoin de connaitre l'heure absolue de chaque échantillon. Il suffit de considérer que chaque échantillon est prélevé toutes les 1/25èmes de seconde et c'est tout.
     

  11. polo974

    Date d'inscription
    février 2007
    Messages
    8 319

    Re : [PYTHON] Transformée de Fourrier discrète sur un signal déjà échantillonné

    je ne comprends toujours pas ce qui rentre:
    Code:
    mesure1, mesure2 = map(float, serie.readline().split()) #lit la donnee sur la laison serie
    tu lis 2 valeurs par ligne, que représentent-elles?
    as-tu un double potar sinus/cosinus? (il faut alors calculer la position angulaire avec un poil de trigo)

    as-tu un simple potar à réponse linéaire (donc en dent de scie quand on reboucle) ? donc 2 échantillons temporels sur la même ligne ? (il faut gérer le passage de la "dent de scie".

    normalement, tu as un angle absolu, il faut faire une différence entre 2 échantillons continus pour ramener ça en vitesse angulaire ( et gérer les passages de la "dent de scie" (en gros pas de valeur négative)).

    sinon, au lieu de traiter en temps réel, commence par enregistrer "un certain temps" dans un fichier, et ensuite analyse ce que tu lis, ce que tu en fais, etc... (python a un module csv assez simple à employer pour enregistrer/lire (même moi j'y arrive...))
    (et puis, du coup, tu peux même nous faire profiter d'un jeu de test...)
    Le mieux est l'ennemi du bien, et c'est bien mieux comme ça...
     

  12. Shantorian

    Date d'inscription
    octobre 2014
    Messages
    135

    Re : [PYTHON] Transformée de Fourrier discrète sur un signal déjà échantillonné

    Citation Envoyé par Jack Voir le message
    C'est une très mauvaise idée qui ne présente aucun intérêt. Tu n'as pas besoin de connaitre l'heure absolue de chaque échantillon. Il suffit de considérer que chaque échantillon est prélevé toutes les 1/25èmes de seconde et c'est tout.
    Effectivement... Je corrige mon algorithme.


    polo974 :

    Les deux valeurs sont deux tensions entre 0 et 2V mesurées par les potentiomètres je les convertis en angle. J'ai une expression qui me donne l'écart entre la valeur théorique de theta2 ( le deuxième angle) et la valeur mesurée en fonction theta1 et theta 2, donc en fonction des deux tensions issues des potentiomètres, je l'utilise dans mon algo.

    Cet écart est relatif il oscille donc autour de 0, les passages à la dents de scie sont gérés au niveaux hardware (suiveurs) et softaware (cf mon signal, pourtant passé par plusieurs "dents de scie").

    Pour ce qui est du signal, l’algorithme renvoie bien ce que je veux, tout est cohérent avec la théorie.

    Je ne vais pas rentrer dans les détails car mon problème fait partie d'une manipulation plus grande, mais pour résumer, chaque potentiomètre est branché sur un axe, les deux axes sont reliées par un liaison mécanique (roue - vis sans fin), et un des deux axes est entraîné par un moteur. La liaison mécanique présente des erreurs de transmission qui font qu'il existe un écart entre la position théorique et la position pratique (angulaire donc) sur le deuxième axe.

    Cette erreur est mon signal en degrés par secondes.
     

  13. Shantorian

    Date d'inscription
    octobre 2014
    Messages
    135

    Re : [PYTHON] Transformée de Fourrier discrète sur un signal déjà échantillonné

    Désolé pour le doublon, j'ai oublié d'ajouter : en fait c'est une étude globale et une correction des erreurs périodiques dans les télescopes par analyse prédictive si jamais vous voulez plus de détails.
     

  14. polo974

    Date d'inscription
    février 2007
    Messages
    8 319

    Re : [PYTHON] Transformée de Fourrier discrète sur un signal déjà échantillonné

    Ok, ça s’éclaircit...
    Tu as donc 2 angles normalement linéairement liés, mais pour de "sombres problèmes de la vraie vie", il y a des non linéarités et c'est ça qui t'intéresse...

    Sauf erreur, ta roue de vis sans fin fait 25 dents (vu la division par 25 sur un des angles).

    Finalement, la dimension temps n'est même pas nécessaire dans tes calculs, tu pourrais te baser sur un des angles, ce qui t'isolerait de la variation de vitesse d’entraînement (au cas où la vitesse de ton moteur ne serait pas régulière, genre le moteur ralenti lors de la rotation d'un truc pas équilibré). (Mais alors, il faudrait ré-échantillonner pour faire une fft)...
    Le mieux est l'ennemi du bien, et c'est bien mieux comme ça...
     

  15. Shantorian

    Date d'inscription
    octobre 2014
    Messages
    135

    Re : [PYTHON] Transformée de Fourrier discrète sur un signal déjà échantillonné

    Oui je me base sur un des angles (d'où 2 potentiomètres), je ne connais même pas la fonction de transfert de mon moteur... C'est juste un moteur DC que je commande en tension !

    Dès que je retourne sur cette manip, je pourrai vérifier si la FFT ainsi faite est concluante.

    C'est vrai que le temps est inutile, je m'étais basé sur un programme modifié, je n'avais pas assez réfléchi. Cependant dans mes calcul le temps n'intervient pas (cf mon programme) hormis ce problème de FFT mais qui semble résolu.

    Merci à vous !
    Dernière modification par Shantorian ; 12/10/2017 à 14h32.
     


    • Publicité







Sur le même thème :





 

Discussions similaires

  1. Questions traitement de signal, transformée de fourrier
    Par UknownStudent dans le forum Mathématiques du supérieur
    Réponses: 8
    Dernier message: 26/11/2015, 17h36
  2. transformée de Fourrier
    Par wiwi24 dans le forum Mathématiques du supérieur
    Réponses: 11
    Dernier message: 19/12/2012, 17h47
  3. transformee de fourrier
    Par imissu dans le forum Mathématiques du supérieur
    Réponses: 2
    Dernier message: 05/07/2012, 18h36
  4. Transformée de Fourrier
    Par azer2k20 dans le forum Électronique
    Réponses: 3
    Dernier message: 13/12/2006, 18h42