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 :

FFT sur signal carré et problème de valeur moyenne. [Python 3.X]


Sujet :

Calcul scientifique Python

  1. #1
    Modérateur

    Avatar de Vincent PETIT
    Homme Profil pro
    Consultant en Systèmes Embarqués
    Inscrit en
    Avril 2002
    Messages
    3 253
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Consultant en Systèmes Embarqués
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Avril 2002
    Messages : 3 253
    Par défaut FFT sur signal carré et problème de valeur moyenne.

    Je fais une FFT sur un signal carré, 100Hz, amplitude 5V, rapport cyclique 50%

    Nom : nH3sC.png
Affichages : 3536
Taille : 23,9 Ko

    En toute logique la valeur moyenne (ou composante continue qui est à la fréquence 0Hz), d'un tel signal c'est simplement 2.5V puisque ce signal de 5V est haché de 50%. Mais dans l'image ci dessous, la valeur moyenne est bien trop grande.

    Nom : SrhhD.png
Affichages : 3640
Taille : 8,4 Ko

    Je tourne en rond depuis quelques jours car je ne comprends pas pourquoi j'ai une valeur moyenne (composante continue) aussi grande sur la courbe issue d'un calcul avec scipy.fftpack ? Est ce que je l'utilise mal ?


    D'avance merci.
    A+



    Voici mon code. Nota : Pourtant la fondamentale est ok (à 100Hz elle fait 2.5V d'amplitude) ensuite on voit les harmoniques de rang impaire (300Hz, 500Hz, 700Hz, ...), typique d'un signal carré. Ce qui cloche c'est la composante continue


    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
    from scipy.fftpack import fft
    from scipy import signal
    import matplotlib.pyplot as plt
    import numpy as np
     
    #
    # configuration
    # time analyse = L * (1/Fsample)
    #
    L = 512 # lenght buffer
    Fsample = 2000 # frequency sample
    Fsignal = 100 # frequency
     
    #********************************
     
    # perdiode sample
    Tsample = 1.0/Fsample
     
    # time vector, start = 0s, stop = 0.1024s, step = (0.1024s / (1/Fe))
    t = np.linspace(0.0, L*Tsample, L)
     
    # signal definition, DC offet = 2.5V, Amplitude = 2.5V
    signal = 2.5 + 2.5*signal.square(2 * np.pi * Fsignal * t, 0.5)
     
    # plot time signal
    plt.subplot(2,1,1)
    plt.plot(t, signal)
     
    # fft of time signal
    yf = fft(signal)
     
    # time vector of fft 
    xf = np.linspace(0.0, 1.0/(2.0*Tsample), L//2)
     
    # plot spectral
    plt.subplot(2,1,2)
    plt.plot(xf, 2.0/L * np.abs(yf[0:L//2]))

  2. #2
    Modérateur

    Avatar de Vincent PETIT
    Homme Profil pro
    Consultant en Systèmes Embarqués
    Inscrit en
    Avril 2002
    Messages
    3 253
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Consultant en Systèmes Embarqués
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Avril 2002
    Messages : 3 253
    Par défaut
    Salut,
    J'ai trouvé mon problème, à la toute dernière ligne la normalisation de l'amplitude n'était pas bonne, c'est plt.plot(xf, 1.0/L * np.abs(yf[0:L//2])) et non pas plt.plot(xf, 2.0/L * np.abs(yf[0:L//2])) (au lieu de multiplier par 1/L pour avoir une cohérence des amplitudes, j'avais multiplier par 2/L)

    Maintenant j'observe bien la théorie.

    Avec un signal carré 0V-5V de 20% de rapport cyclique la valeur moyenne est de 20% de 5V soit 1V.

    Nom : Figure_1.png
Affichages : 6418
Taille : 21,8 Ko



    Le bon code ci dessous.
    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
    from scipy.fftpack import fft
    from scipy import signal
    import matplotlib.pyplot as plt
    import numpy as np
     
    #
    # configuration
    # time analyse = L * (1/Fsample)
    #
    L = 512 # lenght buffer
    Fsample = 2000 # frequency sample
    Fsignal = 100 # frequency
     
    #********************************
     
    # perdiode sample
    Tsample = 1.0/Fsample
     
    # time vector, start = 0s, stop = 0.1024s, step = (0.1024s / (1/Fe))
    t = np.linspace(0.0, L*Tsample, L)
     
    # signal definition, DC offet = 2.5V, Amplitude = 2.5V
    signal = 2.5 + 2.5*signal.square(2 * np.pi * Fsignal * t, 0.5)
     
    # plot time signal
    plt.subplot(2,1,1)
    plt.plot(t, signal)
     
    # fft of time signal
    yf = fft(signal)
     
    # time vector of fft 
    xf = np.linspace(0.0, 1.0/(2.0*Tsample), L//2)
     
    # plot spectral
    plt.subplot(2,1,2)
    plt.plot(xf, 1.0/L * np.abs(yf[0:L//2]))

  3. #3
    Membre éprouvé
    Homme Profil pro
    Vagabong étudiant en annalyse du signal.
    Inscrit en
    Avril 2019
    Messages
    130
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 26
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Vagabong étudiant en annalyse du signal.
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Avril 2019
    Messages : 130
    Par défaut
    Bonjour,

    Je suis très étonné que ça fonctionne! Si le signal carré était infini, on observerai des diracs, d'une amplitude très haute...
    Comment avez vous fait pour que la masse des diracs se retrouve sur l'axe vertical? Il y a très probablement une explication mais le passage de l'aire à l'amplitude me parait un peu magique

  4. #4
    Modérateur

    Avatar de Vincent PETIT
    Homme Profil pro
    Consultant en Systèmes Embarqués
    Inscrit en
    Avril 2002
    Messages
    3 253
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Consultant en Systèmes Embarqués
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Avril 2002
    Messages : 3 253
    Par défaut
    Salut,
    Je ne suis sur d'avoir bien compris ta question. En revanche j'ai noté une erreur dans mon précédent programme (c'est une erreur d'un facteur d'échelle)

    Pourquoi devrais je avoir des raies très haute ? Lorsqu'on regarde mon image on devine le sinus cardinal typique de la FTT d'un train d'impulsion.



    Exemple d'un cours trouvé sur internet (pour comparaison)

    Nom : capture.png
Affichages : 3731
Taille : 55,6 Ko


    L'erreur dans mon code vient de là :
    C'était bel et bien plt.plot(xf, 2.0/L * np.abs(yf[0:L//2])) mais cela fausse la composante continue. En prenant L//2 je ne garde que la partie des fréquences positives du spectre, alors que sur l'image ci dessus on voit bien qu'il y a aussi une partie négative. Et le 2.0/L permet simplement de multiplier par 2 les amplitudes puisque je ne garde que la moitié du spectre. Seulement il y a un soucis avec la fréquence 0, la valeur moyenne, car elle se retrouve doublée également par le calcul ce qui fausse le résultat.

  5. #5
    Membre éprouvé
    Homme Profil pro
    Vagabong étudiant en annalyse du signal.
    Inscrit en
    Avril 2019
    Messages
    130
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 26
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Vagabong étudiant en annalyse du signal.
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Avril 2019
    Messages : 130
    Par défaut
    on devine le sinus cardinal typique de la FTT d'un train d'impulsion.
    Justement, La TF d'une porte, c'est un sinus cardinal d'amplitude proportionnelle à la largeur de la porte. Donc on pourrait s’attendre à voir des pics 2 fois plus haut si on prend un signal 2 fois plus long.
    Pourtant, la valeur moyenne du signal créneau ne dépend pas de ça longueur. Et je croyais que la valeur moyenne se lisait dans l'aire du sinus cardinal centré en 0, pas dans ça hauteur qui dépend essentiellement de la largeur du signal.
    Je ne pensais vraiment pas que c'était possible de passer de l'un à l'autre de façon si limpide Pourtant une simple division semble fonctionner! Génial! Mais... Un peu magique pour moi...

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [Débutant] FFT sur signal acoustique
    Par MalexLionnel dans le forum Signal
    Réponses: 2
    Dernier message: 01/06/2017, 13h21
  2. FFT sur signal CW
    Par f4bjh dans le forum Signal
    Réponses: 2
    Dernier message: 23/08/2013, 11h05
  3. fft sur signal lumineu
    Par Djeu Kuru dans le forum Signal
    Réponses: 1
    Dernier message: 24/05/2013, 13h46
  4. Réponses: 3
    Dernier message: 13/07/2012, 17h46
  5. Réponses: 7
    Dernier message: 14/02/2009, 10h24

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