Implementasi perangkat lunak filter IIR dalam saluran pengukur informasi

Informasi tentang keadaan lingkungan atau, misalnya, objek kontrol tertentu dapat diperoleh dengan mengukur nilai parameter saat ini yang mengkarakterisasi properti tertentu dari lingkungan atau objek. Untuk menerima, memproses, dan mentransmisikan informasi tersebut dengan cara teknis, nilai parameter yang diukur harus dikonversi oleh perangkat pengukur otomatis menjadi sinyal informasi pengukuran. Untuk melakukan ini, terapkan saluran pengukur informasi ( IIC ) sebagai satu set sarana teknis, yang masing-masing akan memenuhi fungsi spesifiknya, dari persepsi nilai terukur hingga penerimaan informasi pengukuran dalam bentuk yang nyaman untuk persepsi manusia atau untuk pemrosesan lebih lanjut. Dan semuanya akan baik-baik saja, tetapi di sepanjang jalur informasi, gangguan e (t) ditumpangkan pada sinyal yang berguna y (t) dari informasi pengukuran - fungsi waktu acak yang dapat mensimulasikan kesalahan acak dari transduser pengukur, pickup listrik di kabel penghubung, dan riak acak parameter yang diukur, dan faktor lainnya.

Berdasarkan hal ini, masalah muncul dari pemrosesan informasi utama dalam IIC - memfilter sinyal y (t) informasi pengukuran dari gangguan acak e (t). Pada dasarnya, metode penyaringan didasarkan pada perbedaan dalam spektrum frekuensi dari fungsi y (t) dan e (t), dan interferensinya dianggap lebih berfrekuensi tinggi.

Sintesis filter optimal yang diimplementasikan adalah tugas yang kompleks, solusinya membutuhkan spesifikasi yang tepat dari karakteristik sinyal dan gangguan yang berguna. Oleh karena itu, dalam praktiknya, fungsi transfer filter biasanya ditentukan dan dibatasi untuk sintesis parametrik menggunakan algoritma penyaringan sederhana.

Metode filtrasi dilakukan pada level perangkat lunak dan pada tingkat perangkat keras. Misalnya, dalam sensor BMP280 (BOSCH), dimungkinkan untuk menghubungkan filter IIR pada tingkat perangkat keras, mengubah koefisien filter k, jika perlu, [1].

Filter IIR


Filter dengan respons impuls tak terbatas adalah filter rekursif dan menghitung sinyal output berdasarkan nilai input dan sampel sampel sebelumnya. Secara teoritis, respons impuls filter IIR tidak pernah mencapai nol, sehingga outputnya tidak terbatas durasinya.

Secara umum, kami menulis algoritma untuk memfilter filter digital skalar satu dimensi sebagai [2]:

y[n]=T(x[n],x[n−1],...,x[n−M],y[n−1],...,y[n−N],n), (1),
di mana T adalah fungsi skalar dari satu variabel.

Fungsi T tergantung pada sinyal input saat ini x [n], dan sebelumnya: M sampel sinyal input dan N sampel sinyal keluaran

Output dari filter IIR dijelaskan oleh persamaan perbedaan bentuk:

(2)
di mana x [n], y [n] adalah input dan output dari filter, masing-masing, { ak} Apakah himpunan koefisien langsung, M adalah jumlah koefisien langsung, { bk} Adalah seperangkat koefisien terbalik, N adalah jumlah koefisien terbalik.

Dengan menerapkan transformasi-z pada kedua sisi persamaan (2), kita memperoleh:

(3)

Maka fungsi transfer filter akan terlihat seperti ini:

(4)

Algoritma untuk memfilter filter IIR satu dimensi


Secara umum, algoritma penyaringan untuk filter rekursif stasioner skalar satu dimensi terlihat seperti ini:

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

Kami sekarang menulis persamaan perbedaan untuk filter IIR dalam bentuk [1]:

(6)
di mana k adalah koefisien filter;
atau
y[n]=ay[n−1]+bx[n](7)
dimana Apakah koefisien filter terbalik dan maju, masing-masing.

Dari (7) jelas bahwa pada k = 1 sinyal output dari filter akan mengulangi input, dan ketika koefisien filter k meningkat, berat dari sinyal yang difilter sebelumnya cenderung ke 1, dan berat dari nilai yang diukur cenderung ke 0.

Algoritma (6) diimplementasikan sebagai contoh saluran pengukur informasi tekanan atmosfer absolut untuk sensor BMP280, pada tingkat perangkat lunak di lingkungan pengembangan Perangkat Lunak Arduino (IDE), daftar 1. Diagram sambungan listrik komponen IIC ditunjukkan pada Gambar. 1. Pandangan umum dari prototipe tekanan atmosfer absolut IIC disajikan pada Gambar. 2. Prototipe ini menyediakan kemampuan untuk mengubah koefisien filter dalam kisaran 1 ... 50 dengan penambahan 1, dengan memutar kenop potensiometer. Tanda layar kristal cair menunjukkan nilai tekanan terukur (untuk k = 1) atau nilai yang disaring (untuk k = 2 ... 50), dan koefisien filter 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 - Diagram pengkabelan komponen-komponen prototipe IIC


Fig. 2 - Pandangan umum dari prototipe IIC

Skrip Python untuk meneliti filter IIR


Listing 2 memperlihatkan skrip Python untuk memeriksa filter IIR. Koefisien filter k ditulis dalam skrip. Nilai tekanan yang diukur dibaca secara berurutan dari port COM virtual dan difilter. Nilai yang diukur dan difilter dari parameter yang diukur secara real time ditampilkan di jendela grafik dan di konsol. Hasil percobaan dicatat oleh tabel dalam file, dan garis waktu dari nilai yang diukur dan difilter ditampilkan di jendela grafik.

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,   ") 


Hasil Eksperimen


   : 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.97 â€Ļ 30 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,   





Kesimpulan


Algoritma penyaringan di atas sangat sederhana dalam implementasi perangkat lunak dan, dalam praktiknya, dapat digunakan dalam IICs seperti yang dibahas dalam artikel ini.
Losikhin D.A., s.v. kafe CITYM .

Sumber informasi


  1. Sensor Tekanan Digital BMP280
  2. Filter respons impuls tak terbatas

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


All Articles