Savoir la forme mathématique des fenêtres basiques
Comprendre la notion du fenêtrage
Savoir l’utilité du fenêtrage
Savoir les différents types des fenêtres
Introduire la carte Portenta H7
Savoir implémenter la DFT en C/Arduino
Test de la DFT sur Arduino Mega/Due
Analyse des performances temporelles du code sur Mega/Due
Analyse de la DFT d’un signal sinusoïdal
Analyse de la DFT d’une entrée réelle
Prendre consciente du problème du sur-échantillonnage
Etc.
Voir le tuto pour plus de détails
La fonction getData()
float getData(float *dataout,int nn, unsigned long ts_us, int analogpin, float gain, int noDC)
Nous avons optimisé la fonction getData() utilisée dans le tuto afin d’obtenir une mesure précise de la fréquence. Elle permet de lire un buffer de données de taille N dans un pin analogique. La fonction peut supprimer ou non la composante DC du signal, ainsi l’ajustement du gain du signal acquis. Elle retourne la valeur approchée de la fréquence d’échantillonnage ainsi le tableau des données. Ci-dessous la définition de la fonction.
float getData(float *dataout,int nn, unsigned long ts_us, int analogpin, float gain, int noDC) { // Lecture des données brutes float ts_f=0.0; unsigned long t11; for(int i=0; i<nn; i++) { t11=micros(); dataout[i]=(float)analogRead(54+analogpin); delayMicroseconds(ts_us); ts_f+=(float)micros()-(float)t11; } ts_f=ts_f/(float)nn;
// Conversion en V for(int i=0; i<nn; i++) dataout[i]=gain*dataout[i]*3.3/4095.0;
// Suppression de la valeur DC if(noDC==0) { float Vm=0.0; for(int i=0; i<nn;i++) Vm+=dataout[i]; Vm/=(float)nn; for(int i=0; i<nn;i++) dataout[i]=dataout[i]-Vm; } return 1E6/ts_f; }
La fonction setWindow()
float setWindow(float *datain, float *dataout, int n, int type)
La fonction setWindow() permet d’appliquer une fenêtre à un buffer de données. Elle prend en entrée le buffer et sa taille, ainsi le type de la fenêtre :
Type=0: Fenêtre de Hann
Type=1: Fenêtre de Hamming
Type=2: Fenêtre de Blackman
Type=3: Fenêtre Gaussienne
Type=4: Fenêtre Sin²
Type=X: Sans Fenêtre
Les amplitudes sont corrigées par rapport à un coefficient constant. Ci-dessous la définition de la fonction.
float getData(float *dataout,int nn, unsigned long ts_us, int analogpin, float gain, int noDC) { // Lecture des données brutes float ts_f=0.0; unsigned long t11; for(int i=0; i<nn; i++) { t11=micros(); dataout[i]=(float)analogRead(54+analogpin); delayMicroseconds(ts_us); ts_f+=(float)micros()-(float)t11; } ts_f=ts_f/(float)nn;
// Conversion en V for(int i=0; i<nn; i++) dataout[i]=gain*dataout[i]*3.3/4095.0;
// Suppression de la valeur DC if(noDC==0) { float Vm=0.0; for(int i=0; i<nn;i++) Vm+=dataout[i]; Vm/=(float)nn; for(int i=0; i<nn;i++) dataout[i]=dataout[i]-Vm; } return 1E6/ts_f; }
float setWindow(float *datain, float *dataout, int n, int type) { float Hi, t=0.0,t0=0.0, sig=0.0; const float gain[6]={0.5581,0.5934,0.4765,0.6456,0.5581,1.0000};
switch(type) { //Fenêtre de Hann case 0: for(int i=0;i<n; i++) { t=(float)i/float(n); Hi=0.5-0.5*cos(2.0*PI*t); dataout[i]=Hi*datain[i]; } return gain[type];
//Fenêtre de Hamming case 1: for(int i=0;i<n; i++) { t=(float)i/float(n); Hi=0.54-0.46*cos(2.0*PI*t); dataout[i]=Hi*datain[i]; } return gain[type];
// Fenêtre de Blackman case 2: for(int i=0;i<n; i++) { t=(float)i/float(n); Hi=0.42-0.5*cos(2.0*PI*t)+0.08*cos(4.0*PI*t); dataout[i]=Hi*datain[i]; } return gain[type];
//Fenêtre de Gauss case 3: for(int i=0;i<n; i++) { t=((float)i/float(n))-0.5; t0=0.5; sig=t0/2.0; Hi=exp(-0.5*t*t/(sig*sig)); dataout[i]=Hi*datain[i]; } return gain[type];
#define N 256 // Données N=2^n, TFD Nf=2^(n-1) // Agit sur la Résolution fréquentielle!!!!!!!! // df= Fs/N
#define Ts_us 100 // Ts=1/Fs: Approchée (voir le programme) // Agit sur la fréquence MAX du spéctre!!!!!!!! // FMXA = Fs/2 /* Type=0: Fenêtre de Hann Type=1: Fenêtre de Hamming Type=2: Fenêtre de Blackman Type=3: Fenêtre Gaussienne Type=4: Fenêtre Sin² Type=X: Sans Fenêtre */