Implémentation logicielle du filtre IIR dans le canal de mesure de l'information

Des informations sur l'état de l'environnement ou, par exemple, un certain objet de contrôle peuvent être obtenues en mesurant les valeurs actuelles de paramètres caractérisant certaines propriétés de l'environnement ou de l'objet. Pour recevoir, traiter et transmettre ces informations par des moyens techniques, la valeur du paramètre mesuré doit être convertie par des appareils de mesure automatiques en un signal d'informations de mesure. Pour ce faire, mettre en œuvre le canal de mesure de l'information ( IIC ), en tant que combinaison de moyens techniques, chacun remplissant sa fonction spécifique, à partir de la perception de la valeur mesurée et se terminant par la réception des informations de mesure sous une forme adaptée à la perception humaine ou à son traitement ultérieur. Et tout irait bien, mais le long du chemin des informations, l'interférence e (t) se superpose au signal utile y (t) des informations de mesure - une fonction aléatoire du temps qui peut simuler l'erreur aléatoire du transducteur de mesure, des capteurs électriques dans les fils de connexion et des ondulations aléatoires paramètre mesuré et autres facteurs.

Sur cette base, le problème se pose du traitement primaire des informations dans l'IIC - filtrage du signal y (t) des informations de mesure à partir des interférences aléatoires e (t). Fondamentalement, les méthodes de filtrage sont basées sur la différence dans les spectres de fréquence des fonctions y (t) et e (t), et l'interférence est considérée comme plus haute fréquence.

La synthèse du filtre optimal mis en œuvre est une tâche complexe, dont la solution nécessite la spécification exacte des caractéristiques du signal utile et des interférences. Par conséquent, en pratique, la fonction de transfert du filtre est généralement spécifiée et limitée à la synthèse paramétrique à l'aide d'algorithmes de filtrage simples.

Les méthodes de filtration sont effectuées à la fois au niveau logiciel et au niveau matériel. Par exemple, dans le capteur BMP280 (BOSCH), il est possible de connecter un filtre IIR au niveau matériel, en changeant le coefficient de filtre k, si nécessaire, [1].

Filtre IIR


Les filtres à réponse impulsionnelle infinie sont des filtres récursifs et calculent le signal de sortie en fonction des valeurs des échantillons d'entrée et de sortie précédents. Théoriquement, la réponse impulsionnelle d'un filtre IIR n'atteint jamais zéro, la sortie est donc d'une durée infinie.

En général, nous écrivons l'algorithme de filtrage d'un filtre numérique scalaire unidimensionnel comme [2]:

y[n]=T(x[n],x[n1],...,x[nM],y[n1],...,y[nN],n), (1),
T est une fonction scalaire d'une variable.

La fonction T dépend du signal d'entrée actuel x [n], et précédente: M échantillons du signal d'entrée et N échantillons du signal de sortie

La sortie du filtre IIR est décrite par une équation de différence de la forme:

(2)
où x [n], y [n] est respectivement l'entrée et la sortie du filtre, { ak} Est l'ensemble des coefficients directs, M est le nombre de coefficients directs, { bk} Est un ensemble de coefficients inverses, N est le nombre de coefficients inverses.

En appliquant la transformation z aux deux côtés de l'équation (2), nous obtenons:

(3).

Ensuite, la fonction de transfert du filtre ressemblera à ceci:

(4)

Algorithme de filtrage d'un filtre IIR unidimensionnel


En termes généraux, l'algorithme de filtrage pour un filtre récursif stationnaire scalaire unidimensionnel ressemble à ceci:

y[n]=T(x[n],y[n1]). (5)

Nous écrivons maintenant l'équation de différence pour le filtre IIR sous la forme [1]:

(6)
où k est le coefficient de filtrage;
ou
y[n]=ay[n1]+bx[n](7)
Sont les coefficients de filtre inverse et direct, respectivement.

D'après (7), il est évident qu'à k = 1, le signal de sortie du filtre répétera l'entrée, et à mesure que le coefficient de filtre k augmente, le poids du signal filtré précédent tend vers 1 et le poids de la valeur mesurée tend vers 0.

L'algorithme (6) est implémenté comme exemple du canal de mesure des informations de pression atmosphérique absolue pour le capteur BMP280, au niveau logiciel dans l'environnement de développement Arduino Software (IDE), liste 1. Le schéma de connexion électrique des composants IIC est illustré à la Fig. 1. La vue générale du prototype IIC de pression atmosphérique absolue est présentée à la Fig. 2. Le prototype offre la possibilité de modifier le coefficient de filtrage dans la plage de 1 ... 50 par incréments de 1, en tournant le bouton du potentiomètre. Le signe de l'affichage à cristaux liquides indique la valeur de pression mesurée (pour k = 1) ou la valeur filtrée (pour k = 2 ... 50), et le coefficient de filtre k.

Listing 1
//    () // -  - //https://github.com/orgua/iLib/blob/master/src/i2c.h #include "i2c.h" //https://github.com/orgua/iLib/blob/master/src/i2c_BMP280.h #include "i2c_BMP280.h" //https://github.com/arduino-libraries/LiquidCrystal #include <LiquidCrystal.h> //https://github.com/orgua/iLib/tree/master/examples/i2c_BMP280 BMP280 bmp280; const int rs = 12, en = 11, d4 = 6, d5 = 5, d6 = 4, d7 = 3; //const int rs = PB4, en = PB3, d4 = PD6, d5 = PD5, d6 = PD4, d7 = PD3; LiquidCrystal lcd(rs, en, d4, d5, d6, d7); float pascal_f = 100500; float filter_K = 1; const int analogInPin = A0; //    int sensorValue = 0; //   int outputValue = 0; void setup() { Serial.begin(9600); //Serial.print("Probe BMP280: "); if (bmp280.initialize()) { //Serial.println("Sensor found"); ; } else { Serial.println("Sensor missing"); while (1) {} } bmp280.setEnabled(0); bmp280.triggerMeasurement(); bmp280.setFilterRatio(0); lcd.begin(16, 2); lcd.setCursor(0, 0); lcd.print("measure"); lcd.setCursor(7, 1); lcd.print("Pa"); lcd.setCursor(10, 0); lcd.print("filter"); } void loop() { float temperature; float pascal, hpascal; sensorValue = analogRead(analogInPin); outputValue = map(sensorValue, 0, 1023, 1, 50); filter_K = outputValue; bmp280.awaitMeasurement(); bmp280.getTemperature(temperature); temperature -= 1.7; // bmp280.getPressure(pascal); pascal -= 50;// hpascal = pascal/100.; bmp280.triggerMeasurement(); pascal_f = (pascal_f * (filter_K - 1) + pascal) / filter_K; //(6) Serial.println(pascal_f,0); if(pascal_f < 100000) lcd.setCursor(6, 1); lcd.print(" "); lcd.setCursor(0, 1); lcd.print(pascal_f,0); if(filter_K < 10) lcd.setCursor(13, 1); lcd.print(" "); lcd.setCursor(10, 1); lcd.print(filter_K,1); delay(300); } 



Fig. 1 - Schéma de câblage des composants du prototype IIC


Fig. 2 - Vue générale du prototype IIC

Script Python pour la recherche de filtres IIR


Le listing 2 montre un script Python pour examiner les filtres IIR. Le coefficient de filtre k est écrit dans le script. Les valeurs de pression mesurées sont lues séquentiellement à partir du port COM virtuel et filtrées. Les valeurs mesurées et filtrées du paramètre mesuré en temps réel sont affichées dans la fenêtre graphique et sur la console. Les résultats de l'expérience sont enregistrés par le tableau dans un fichier et les chronologies des valeurs mesurées et filtrées sont affichées dans la fenêtre graphique.

Listing 2
 import numpy as np import matplotlib.pyplot as plt import serial from drawnow import drawnow import datetime, time k = 6.0 #  + 1 filter_K = 1 + k #     def cur_graf(): plt.title("BMP280") plt.ylim( 100450, 100510 ) plt.plot(nw, lw1, "r.-", label='') plt.plot(nw, lw1f, "b.-", label='') plt.legend(loc='best') plt.ylabel(r'$, $') plt.xlabel(r'$ \ $') plt.grid(True) #      def all_graf(): plt.close() fig=plt.figure() ax = fig.add_subplot(111) fig.subplots_adjust(top=0.85) ax.set_title(" BMP280\n" + str(count_v) + "-  " + "(" + now.strftime("%d-%m-%Y %H:%M") + ")") ax.set_ylabel(r'$, $') ax.set_xlabel(r'$ \ $' + '; (  : {:.6f}, c)'.format(Ts)) ax.text(0.95, 0.03, " : " + str(filter_K) + "\n", verticalalignment='bottom', horizontalalignment='right', transform=ax.transAxes, color='black', fontsize=14) plt.plot( n, l1, "r-", label='') plt.plot( n, l1f, "b-", label='') plt.legend(loc='best') plt.grid(True) plt.show() #   #    str_m = input("  : ") m = eval(str_m) #    mw = 16 #    ser = serial.Serial() ser.baudrate = 9600 port_num = input("   : ") ser.port = 'COM' + port_num ser #   try: ser.open() ser.is_open print(" : " + ser.portstr) except serial.SerialException: print("   : " + ser.portstr) raise SystemExit(1) #  l1 = [] #    l1f = [] #     t1 = [] #     lw1 = [] #     lw1f= [] #      n = [] #     nw = [] #      #      filename = 'count.txt' in_file = open(filename,"r") count = in_file.read() count_v = eval(count) + 1 in_file.close() in_file = open(filename,"w") count = str(count_v) in_file.write(count) in_file.close() filename = count + '_' + filename out_file = open(filename,"w") #      print("\n:\n") print("n -  ;") print("P - , ;") print("\n   \n") print('{0}{1}\n'.format('n'.rjust(4),'P'.rjust(10))) #     #  #   #       i = 0 while i < m: n.append(i) nw.append(n[i]) if i >= mw: nw.pop(0) line1 = ser.readline().decode('utf-8')[:-2] t1.append(time.time()) if line1: l1.append(eval(line1)) lw1.append(l1[i]) if i : l1f.append( (l1f[i-1]*(filter_K - 1) + l1[i])/filter_K ) #(6) lw1f.append(l1f[i]) else : l1f.append(l1[i]) lw1f.append(l1f[i]) if i >= mw: lw1.pop(0) lw1f.pop(0) print('{0:4d} {1:10.2f} {2:10.2f}'.format(n[i],l1[i],l1f[i]) ) drawnow(cur_graf) i += 1 #   ser.close() ser.is_open time_tm = t1[m - 1] - t1[0] print("\n  : {0:.3f}, c".format(time_tm)) Ts = time_tm / (m - 1) print("\n  : {0:.6f}, c".format(Ts)) #    print("\n    {}\n".format(filename)) for i in np.arange(0,len(n),1): count = str(n[i]) + "\t" + str(l1[i]) + "\n" out_file.write(count) #    out_file.close() out_file.closed #    now = datetime.datetime.now() #     all_graf() end = input("\n Ctrl-C,   ") 


Résultats de l'expérience


   : 33    : 6  : COM6 : n -  ; P - , ;     n P 0 100490.00 100490.00 1 100488.00 100489.71 2 100487.00 100489.33 3 100488.00 100489.14 4 100488.00 100488.9730 100486.00 100488.14 31 100492.00 100488.70 32 100489.00 100488.74   : 16.028, c   : 0.500875, c     275_count.txt  Ctrl-C,   





Conclusions


L'algorithme de filtrage ci-dessus est très simple dans l'implémentation logicielle et, dans la pratique, peut être utilisé dans des IIC similaires à ceux abordés dans cet article.
Losikhin D.A., s.v. café CITYM .

Sources d'information


  1. Capteur de pression numérique BMP280
  2. Filtre de réponse impulsionnelle infinie

Source: https://habr.com/ru/post/fr414943/


All Articles