Simple Digital Band-Pass Filter by using Arduino UNO [EP3]

ในบทความนี้จะเป็นการทดลองการกรองความถี่โดยให้ช่วงความถี่ที่ต้องการผ่านแบบดิจิตอล (Digital Band-Pass Filter : DBPF) โดยใช้บอร์ดประมวลผล Arduino UNO ซึ่งเป็นเนื้อหาต่อเนื่องจากการกรองความถี่สูงและความถี่ต่ำผ่านที่นำเสนอก่อนหน้า สำหรับนำความรู้ไปประยุกต์ใช้งานในการกรองความถี่ในช่วงที่ต้องการ และเข้าใจการประมวลผลสัญญาณดิจิตอล การปรับแต่งช่วงความถี่ที่เหมาะสม เพื่อเป็นพื้นฐานความรู้ต่อไป

แนวความคิดพื้นฐานของการกรองช่วงความถี่ที่ต้องการ (Digital Band-Pass Filter)
การกรองช่วงความถี่ผ่าน (Band-pass filter) จะใช้พื้นฐานความรู้ของ 2 ส่วนคือ
1. Low-pass filter (LPF) ยอมให้ความถี่ต่ำกว่าค่าความถี่ cutoff ผ่านไปได้ และลดทอนความถี่ที่สูงกว่า cutoff
2. High-pass filter (HPF) ยอมให้ความถี่สูงกว่าค่าความถี่ cutoff ผ่านไปได้ และลดทอนความถี่ที่ต่ำกว่า cutoff
จากนั้นจะนำผลของ LPF และ HPF มาต่อกัน (Cascading) โดยที่ความถี่ cutoff frequency ของ LPF สูงกว่า cutoff frequency ของ HPF และผลลัพธ์ที่ได้จะเป็น Band-pass filter ที่ยอมให้สัญญาณในช่วงความถี่ระหว่าง cutoff ทั้งสองผ่านไปได้
ประเภทของการกรองความถี่แบบดิจิตอล (Digital Filter)
1. FIR (Finite Impulse Response) Filters จะมี phase response ที่เป็นเชิงเส้น ทำให้ไม่มีการหน่วงเวลาที่แตกต่างกันสำหรับความถี่ต่างๆ มักจะใช้การคำนวณที่ซับซ้อน
2. IIR (Infinite Impulse Response) Filters จะมีประสิทธิภาพในการคำนวณสูงกว่า แต่ phase response อาจไม่เป็นเชิงเส้น ซึ่งจะทำให้มีการเลื่อนของเฟสในสัญญาณ
สำหรับการกรองความถี่โดยใช้บอร์ด Arduino UNO จะมีข้อจำกัดในเรื่องของหน่วยความจำและความสามารถในการประมวลผล ดังนั้นการกรองความถี่แบบ Exponential Moving Average (EMA)จะเป็นตัวเลือกที่เหมาะสมสำหรับการประมวลผลแบบเรียลไทม์
สมการสำหรับการกรองความถี่แบบ EMA (Low-Pass Filter)
Yt = α⋅Xt +(1−α)⋅Yt−1 … (1)
เมื่อกำหนดให้
Yt คือ ค่าสัญญาณที่ถูกกรอง ณ เวลาปัจจุบัน
Xt คือ ค่าสัญญาณอินพุต ณ เวลาปัจจุบัน
Yt−1 คือ ค่าสัญญาณที่ถูกกรองก่อนหน้า
α(alpha)คือ ค่าคงที่สำหรับการปรับลักษณะของการกรองความถี่ต่ำคือ ในกรณีที่กำหนดค่า alpha น้อยลงจะทำให้การกรองความถี่ต่ำได้ดีขึ้นหรือเรียกว่าความถี่คัตออฟต่ำลง
การสร้างตัวกรองความถี่สูงผ่าน High-Pass Filter จาก Low-Pass Filter
ในการสร้างการกรองความถี่สูงผ่านสามารถทำได้โดยการนำสัญญาณอินพุตเดิม (Xt) มาลบด้วยผลลัพธ์ของกรองความถี่ต่ำผ่าน (Yt) ดังสมการที่ 2 แสดงข้างล่าง
HPF Output = Xt − Yt … (2)
การสร้างตัวกรองช่วงความถี่ผ่าน (Band-Pass Filter)
จะใช้แนวความคิดของการใช้ LPF สองตัวที่มีค่า alpha ที่แตกต่างกันคือ
1. LPF_High: เป็น Low-pass filter ที่มี cutoff frequency สูงขึ้น (alpha สูงขึ้น) เพื่อให้ความถี่สูงๆ ผ่านไปได้
2. LPF_Low: เป็น Low-pass filter ที่มี cutoff frequency ต่ำลง (alpha ต่ำลง) เพื่อกำจัดความถี่สูงๆ ออกไป
จากนั้นจะหาผลลัพธ์ด้วยการนำค่า LPF_Low มาลบกับ LPF_High เพื่อให้เหลือเฉพาะช่วงความถี่ที่อยู่ ระหว่างตรงกลาง
BPF Output = LPF_High Output−LPF_Low Output … (3)
/* Arduino UNO Code By : https://gemini.google.com/ Key word prompt : Digital Band-Pass Filter by using Arduino and Exsample code */ const float EMA_ALPHA_LOW = 0.05; // 0.02 กรองความถี่สูงออกไปมาก, เหลือแต่ความถี่ต่ำมากๆ const float EMA_ALPHA_HIGH = 0.1; // 0.1 กรองความถี่สูงออกไปน้อยลง, ยอมให้ความถี่สูงขึ้นมาหน่อยผ่านได้ float ema_lp_low = 0; float ema_lp_high = 0; void setup() { Serial.begin(9600); pinMode(A0, INPUT); } void loop() { // int rawValue = analogRead(A0); int rawValue = random(1,1023); // Adj Amplitude Signal Analog input int fdelay = random(1,300); // Adj Frequency Signal Analog input delay(fdelay); //------- Calc Lower Cutoff for Band-Pass ------- ema_lp_low = EMA_ALPHA_LOW * rawValue + (1 - EMA_ALPHA_LOW) * ema_lp_low; //------- Calc Upper Cutoff for Band-Pass ------- ema_lp_high = EMA_ALPHA_HIGH * rawValue + (1 - EMA_ALPHA_HIGH) * ema_lp_high; //------- Calc Band-Pass Filter OUT PUT --------- float filteredBP = ema_lp_high - ema_lp_low; Serial.print("Raw Value: "); Serial.print(rawValue); Serial.print("\tHighpass: "); Serial.print(ema_lp_high); Serial.print("\tFiltered BP: "); Serial.println(filteredBP); }
สำหรับโปรแกรมกรองช่วงความถี่ผ่าน (Band-Pass Filter) ที่แสดงข้างบน จะแบ่งออกเป็น 6 กลุ่ม ดังนี้
กลุ่มแรก จะเป็นการประกาศค่าตัวแปรต่างๆ สำหรับใช้การคำนวณในช่วงต้นๆ ของโปรแกรม โดยจะรวมทั้งการกำหนดอัตราการสื่อสารพอร์ตอนุกรม (Serial.begin(9600);)และการกำหนดฟังก์ชั่นการใช้งานขา (pinMode(A0, INPUT))
กลุ่มที่สอง จะเป็นคำสั่งสร้างสัญญาณอะนาลอกด้วยการสุ่มขึ้นมาจากการใช้คำสั่ง int rawValue = random(1,1023); ซึ่งในส่วนนี้จะกำหนดขนาดแอมปริจูดและที่คำสั่ง int fdelay = random(1,300); และ delay(fdelay); จะทำหน้าที่กำหนดความถี่ที่แตกต่างกัน ทั้งนี้เพื่อนำค่าที่สุ่มขึ้นมาได้ใช้ในการทดสอบการทำงานของโปรแกรมกรองความถี่ครั้งนี้
กลุ่มที่สาม จะเป็นโปรแกรมสมการเพื่อกรองสัญญาณความถี่ต่ำ สำหรับความถี่คัตออฟช่วงล่าง (Lower Cutoff)หรือความถี่ที่ต่ำกว่าความถี่คัตออฟนี้ให้ผ่านน้อย
กลุ่มที่สี่ จะเป็นโปรแกรมสมการเพื่อกรองสัญญาณความถี่ต่ำเช่นกัน (แต่จะกรองความถี่ที่สูงกว่า Lower Cutoff) โดยความถี่คัตออฟช่วงนี้จะเป็น (Upper Cutoff) ซึ่งความถี่ที่ต่ำกว่าความถี่คัตออฟนี้ให้ผ่านน้อยเช่นกัน
กลุ่มที่ห้า จะเป็นโปรแกรมสมการเพื่อหาผลต่างของ Upper Cutoff และ Lower Cutoff ซึ่งผลลัพธ์ที่ได้จะเป็นช่วงความถี่ที่ต้องการ (Band-Pass Filter) ทางด้านเอาต์พุต
กลุ่มที่หก จะเป็นคำสั่งสำหรับแสดงผลการทำงานของโปรแกรมที่ได้จากการสมการต่างๆ โดยจะสามารถดูผลที่เกิดขึ้นที่เมนู Serial Plotter โดยจะแสดงในส่วนของสัญญาณอินพุต, สัญญาณความถี่คัตออฟช่วง (Upper Cutoff) เทียบกับสัญญาณเอาต์พุตช่วงความถี่ผ่านให้เข้าใจง่าย



ในรูปที่ 1 ถึงรูปที่ 3 แสดงผลการทดลองโปรแกรม Digital Band-Pass Filter โดยทำการเปลี่ยนค่าตัวแปรเฉพาะ EMA_ALPHA_LOW ให้เป็น 0.1, 0.3 และ 0.6 ตามลำดับ เพื่อสังเกตผลการทดลองที่ได้ จากในรูปที่ 1 ถึงรูปที่ 3 จะเห็นรูปสัญญาณอินพุตเดิม (rawValue) จะเป็นสีเขียว, สัญญาณกรองความถี่ด้านสูง Upper Cutoff(ema_lp_high)จะเป็นสีม่วง และสัญญาณเอาต์พุตที่ผ่านการกรองทั้งหมด (filteredBP) จะเป็นสีดำ โดยจะสังเกตเห็นว่าที่ค่า EMA_ALPHA_LOW เท่ากับ 0.1 สัญญาณอินพุตเมื่อเทียบกับสัญญาณเอาต์พุตจะให้การตอบสนองความถี่ในช่วงที่กว้าง แต่เมื่อปรับค่า EMA_ALPHA_LOW ให้กับค่า 0.3 และ 0.6 จะทำให้การตอบสนองช่วงความถี่แคบลง ซึ่งเราสามารถปรับค่า EMA_ALPHA_LOW และ EMA_ALPHA_HIGH ให้มากหรือน้อย ตามความเหมาะสมกับการนำไปใช้งานได้

สำหรับการกรองช่วงความถี่ผ่านด้วยบอร์ดประมวลผล Arduno UNO ในตอนนี้ จะเป็นเนื้อหาต่อเนื่องมาจากการกรองสัญญาณความถี่ต่ำและความถี่สูงที่ผ่านมา ซึ่งจะใช้พื้นฐานเดียวกันมาทั้งหมดและเราสามารถนำไปประยุกใช้งานได้ไม่ยากนัก ในตอนต่อไปจะเป็นวิธีการกรองช่วงความถี่ที่ไม่ต้องการออก (Digital Band-Stop Filter) ซึ่งจะเป็นการกรองความถี่ด้วยบอร์ดประมวลผล Arduno UNO ในตอนสุดท้ายครับ.
Reference
- https://gemini.google.com/
- https://www.norwegiancreations.com/2016/03/arduino-tutorial-simple-high-pass-band-pass-and-band-stop-filtering/
- https://github.com/MartinBloedorn/libFilter
- https://docs.simplefoc.com/low_pass_filter
- https://www.instructables.com/FIR-Filtering-for-More-Reliable-Frequency-Detectio/