3 minute read

Biblio

  • Trop compliqué et complet : si on se pose une question la réponse y sera : Traitement des signaux et acquisition de données, Francis Cottet éditions Dunod
  • Regarder programme psi et bouquins de PSI, ça balise un peu la leçon c’est mieux
  • Dunod PSI tout en un
  • Précis électronique PSI : la base sur le filtrage et la DSF
  • Electronique, Pérez
  • Transmission de signaux, Christophe More

Notions importantes : Spectre d’un signal temporel, description via TF, application filtrage. Numérisation : échantillonnage, FFT et critère de Shannon. Peut être une dernière partie sur la modulation en amplitude nécessaire pour transporter la voix par exemple ?

Plans possibles

  • I Outils d’analyse spectrale : 1) Signal périodique et DSF, spectre 2) Filtrage : couper fréquences … Application au passe haut de l’oscillo, transition numérique?
  • II Aquisition d’un signal : 1) échantillonnage d’un signal 2) traitement : FFT, critère de Shannon, application au repliement et diapason?
  • III Modulation/démodulation fil rouge objectif radio : 1) multiplication de signaux, appliction modulante porteuse. 2) Transmission du signal et modulation en amplitude 3) Démodulation ouvertude détection synchrone

Regarder du côté de la modulation à porteuse conservée. Le risque de ce plan est qu’on part.

On pourrait faire une leçon qui se base sur un niveau de prérequis plus avancé, notemment pour “traitement linéaire et non linéaire d’un signal”, et prendre fil rouge modulation/Démodulation pour la radio :

  • Intro : Radio émet voix, problème bruit, vitesse de propagation(?), antennes longues
  • I Modulation d’amplitude : 1) Multiplication de signaux avec le montage, et ce que ça permet 2) Application radio : porteuse et enveloppe, spectre
  • II Réception du signal et démodulation : Détection synchrone, problèmes associés

Peut être dans le cas non linéaire discuter de la non validité de la notation cpx.

Manips possibles

  • translation de fréquence diapason
  • Modulation en amplitude
  • Etude du filtre de l’oscillo
  • Multiplexage optique

Python

Modulation et échantillonnage

import numpy as np
import matplotlib.pyplot as plt

t=np.linspace(0,2e-2,1000)

# Signal s
fm=100
fp=500
s=(1+0.5*np.sin(2*np.pi*t*fm))*np.sin(2*np.pi*t*fp)
m=(1+0.5*np.sin(2*np.pi*t*fm))

# Signal échantillonné
N=30
t_ech=np.linspace(0,2e-2,N)
s_ech=(1+0.5*np.sin(2*np.pi*t_ech*fm))*np.sin(2*np.pi*t_ech*fp)

#Graphique
plt.figure()
plt.plot(1000*t,s,'red',lw=3)
plt.plot(1000*t,m,'orange',lw=2)
plt.plot(1000*t,-m,'orange',lw=2)
(markerLines, stemLines, baseLines) =plt.stem(1000*t_ech,s_ech,linefmt='b--')
plt.setp(markerLines,markersize=10)
plt.setp(stemLines, lw=2)
plt.xlabel('t [ms]',size=20)
plt.ylabel('$u_e$(t) [V]',size=20)
plt.xticks(size=15)
plt.yticks(size=15)
plt.title('Signal modulé avec $f_m$=100 Hz et $f_p$=500 Hz\nÉchantillonnage : N=30 points et $T_0$=20 ms',size=20)
#plt.title('Signal modulé avec $f_m$=100 Hz et $f_p$=2 kHz',size=20)
plt.grid()
plt.show()

# Fonction d'échantillonnage
dt=0.1e-3
p=[]
for t_i in t:
    t_ech_i=np.argmin(np.abs(t_ech-t_i))
    if t_ech[t_ech_i]<=t_i<=t_ech[t_ech_i]+dt:
        p.append(1)
    else:
        p.append(0)
plt.figure()
plt.plot(1000*t,p,'black',lw=3)
plt.xlim(0,5)
plt.xlabel('t [ms]',size=20)
plt.ylabel('p(t) [V]',size=20)
plt.xticks(size=15)
plt.yticks(size=15)
plt.grid()
plt.show()

Filtrage linéaire

Filtre et passe bas:

import numpy as np
from matplotlib import pyplot as plt


R=5000
C=1e-6
w0=1/(R*C)
Tp=1/(100*w0)
T0=100*Tp
f0=10

def H(x):
    return np.sqrt(1/((1+(R*C*2*np.pi*x)**2)))
def Gdb(x):
    return 20*np.log(H(x))


f=np.logspace(1,3,num=1000)
for i in range(len(f)):
    f[i]=np.int(f[i])

frequences=np.zeros(len(f))

def horizon(x):
    return (x/x)*-3


for i in range(len(f)):
    if i%2==1 and f[i]>=f0:
        frequences[i]=1/i
       



fig,ax=plt.subplots()
ax2=ax.twinx()
ax2.vlines(f0,0,1,color='green',linewidth=2,label="Spectre du signal (f0="+str(f0)+"Hz)")
for n in range(2,np.int(f[len(f)-1]/f0)):
    if n%2==1:
        ax2.vlines(n*f0,0,(1/n),color='green',linewidth=2)
ax.semilogx(f,Gdb(f),label="Bode du filtre, f0="+str(round(w0/(2*np.pi),1))+"Hz")
ax.semilogx(f,horizon(f),color='r')
ax.set_ylabel("Gdb (dB)")
ax2.set_ylabel("Amplitude normalisée")
ax.set_xlabel("Frquence (Hz)")
fig.legend(fontsize=12,loc='lower left')
#plt.semilogx(f,horizon(f))

DSF du signal créneau :

#-----------------------------------------------------------------------
# Analyse spectrale d'un signal quelconque
#
# Utiliser la barre inférieure pour sélectionner le nombre d'harmoniques
#-----------------------------------------------------------------------
# Renseignements/bugs : Guillaume Dewaele <agreg(at)sci-phy.org>
#-----------------------------------------------------------------------

# Paramètres modifiables

# Nombre d'harmoniques considérées

max_harm = 40

# Bibliothèque de fonctions

@np.vectorize
def triangle(t) :
    return -0.25+t if t<0.5 else 0.75-t

@np.vectorize
def scie(t) :
    return -0.25+t if t<0.75 else t-1.25

@np.vectorize
def creneau(t) :
    return -0.5 + (1.0 if 0.1<=t<0.6 else 0.0)

@np.vectorize
def bruitblanc(t) :
    np.random.seed(int(t*1000000))
    return np.random.random()-0.5

# Choix de la fonction

foo = creneau

#-----------------------------------------------------------------------

# Bibliothèques utilisées

import numpy as np
import numpy.fft as fft
import matplotlib
import matplotlib.pyplot as plt
import matplotlib.animation as ani
import matplotlib.widgets as mwg

#-----------------------------------------------------------------------

# Détection utilisation hors Pyzo

if '__iep__' not in globals() :
    matplotlib.interactive(False)

# Calcul du spectre

N = 8192
T = np.linspace(0.0, 1.0, N)
Y = foo(T)
Yp = fft.fft(Y)

# Tracés

Tr = np.linspace(0.0, 2.0, 2*N)
Ampl = 20*np.log10(np.abs(Yp[:max_harm]))

# Signal

axTmp = plt.axes([0.11, 0.6, 0.78, 0.32])
axTmp.plot(Tr, np.concatenate([Y, Y]), "k--")
partial, = axTmp.plot(Tr, np.concatenate([Y, Y]), "b")
axTmp.set_xlim([0, 2])
axTmp.set_ylim([ min(Y) - (max(Y)-min(Y))*0.3, max(Y) + (max(Y)-min(Y))*0.3 ])
axTmp.set_title("signal")
axTmp.set_ylabel("amplitude")
axTmp.set_xlabel("temps (t/T0)")

# Spectre

axTmp = plt.axes([0.11, 0.15, 0.78, 0.32])
axTmp.bar(np.arange(max_harm)-0.5, Ampl, color="white")
rects = axTmp.bar(np.arange(max_harm)-0.5, Ampl, color="blue")
axTmp.set_xlim([0, max_harm])
axTmp.set_ylim([0, np.max(Ampl)*1.1])
axTmp.set_title("spectre")
axTmp.set_ylabel("amplitude (dB)")
axTmp.set_xlabel("fréquences (f/f0)")

# Slider

axTmp = plt.axes([0.11, 0.035, 0.78, 0.035])
slider = mwg.Slider(axTmp, '', valmin=0, valmax=max_harm, valinit=max_harm)

def Update(i) :
    PartialY = np.real(fft.ifft(Yp * np.fromfunction(lambda j : j<=i, (len(Yp),))))
    partial.set_data(Tr, 2*np.concatenate([PartialY, PartialY]))
    for j, rect in enumerate(rects) :
        rect.set_height(0 if j>i else Ampl[j])

slider.on_changed(Update)

Update(max_harm)

# Détection utilisation hors Pyzo

if '__iep__' not in globals() :
    plt.show()