Simple Digital High-Pass Filter by using Arduino UNO [EP2]

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

สำหรับวิธีการกรองความถี่สูงนั้น จะนิยมใช้หลักการ Exponential Moving Average (EMA) หรือ First-Order Filter โดยใช้แนวความคิดของการหาผลต่างระหว่างค่าปัจจุบันทางด้านอินพุตกับค่าที่ผ่านการกรองความถี่ต่ำที่ได้ ดังแสดงในสมการข้างล่างคือ
High-Pass Filter Output = Current Value – Low-Pass Filter Output
/* Arduino UNO Code By : https://gemini.google.com/ Key word prompt : Digital High-Pass Filter by using Arduino and Exsample code */ const int analogInputPin = A0; // Analog input pin (e.g., connected to a potentiometer) float rawValue = 0.0; int fdelay = 0; float lowPassFilteredValue = 0.0; // The output of the internal low-pass filter float highPassFilteredValue = 0.0; // The final high-pass filtered output const float alpha = 0.5; // Smoothing factor for the *internal low-pass filter* // Smaller alpha = lower cutoff frequency for the LP filter, // which means the HP filter will pass more higher frequencies. // Think of it as: small alpha makes the LP filter very "smooth", // so subtracting a very smooth signal from the raw signal leaves more of the "changes". void setup() { Serial.begin(9600); } void loop() { // rawValue = analogRead(analogInputPin); rawValue = random(1,1023); // Adj Amplitude Signal Analog input fdelay = random(1,300); // Adj Frequency Signal Analog input delay(fdelay); // --- Step 1: Apply a Low-Pass Filter --- // This low-pass filter aims to capture the "slow" or DC component of the signal. lowPassFilteredValue = (alpha * rawValue) + ((1.0 - alpha) * lowPassFilteredValue); // --- Step 2: Calculate High-Pass Filtered Value --- // Subtract the low-pass filtered (slow/DC) component from the raw signal. // What's left are the faster changes. highPassFilteredValue = rawValue - lowPassFilteredValue; Serial.print("Raw: "); Serial.print(rawValue); Serial.print("\tLPF: "); Serial.print(lowPassFilteredValue); Serial.print("\tHPF: "); Serial.println(highPassFilteredValue); }
โปรแกรมคำสั่งที่สำคัญของ Digital High-Pass Filter ในโค้ด Arduino คือ
ส่วนที่หนึ่ง จะเป็นคำสั่ง rawValue = random(1,1023); เพื่อเป็นการจำลองสร้างสัญญาณอะนาลอกแทน โดยจะสุ่มค่าออกมาเรื่อยๆ (สุ่มค่าในช่วง 0-1023)
ส่วนที่สอง float alpha = 0.05; : เป็นค่าที่จะกำหนดลักษณะของฟิลเตอร์ ในกรณีที่ค่า alpha มีค่าน้อย จะทำให้การกรองความถี่ต่ำได้มากขึ้น ซึ่งจะหมายความว่าการกรองความถี่ต่ำผ่าน จะตัดความถี่ต่ำได้ดีขึ้น และเน้นการเปลี่ยนแปลงสัญญาณที่รวดเร็ว
ส่วนที่สาม filteredLPValue = alpha * rawValue + (1.0 – alpha) * filteredLPValue; : เป็นสมการของการกรองความถี่ต่ำผ่าน Exponential Moving Average (EMA) ซึ่งจะเป็นการกำหนดลักษณะของสัญญาณความถี่ต่ำที่ต้องการ ด้วยการกำจัดสัญญาณความถี่สูงออกไป
ส่วนที่สี่ filteredHPValue = rawValue – filteredLPValue; : เป็นสมการที่สำคัญของการกรองความถี่สูงผ่าน ด้วยการนำสัญญาณอินพุต (rawValue) มาลบด้วยค่าที่ผ่านการกรองความถี่ต่ำแล้ว (lowPassFilteredValue) และผลลัพธ์ที่ได้คือส่วนของสัญญาณความถี่สูง (highPassFilteredValue) ที่เกิดขึ้นนั้นเอง
ส่วนที่ห้า Serial.print จะแสดงผลที่ได้จากสมการต่างๆ เป็นรูปสัญญาณผ่าน Serial Plotter โดยจะแสดงค่าสัญญาณอินพุต,สัญญาณความถี่ต่ำผ่าน โดยเทียบกับสัญญาณเอาต์พุตให้เข้าใจง่าย



ในรูปที่ 1 ถึงรูปที่ 3 แสดงผลการทดลองโปรแกรม Digital High-Pass Filter โดยทำการเปลี่ยนค่า alpha ให้เป็น 0.1, 0.5 และ 0.9 ตามลำดับ (คล้ายกับการทดลองการกรองความถี่ต่ำผ่าน) แต่จะสัญญาณเพิ่มขึ้นมาอีก 1 สัญญาณ รูปสัญญาณอินพุตเดิม (rawValue) จะเป็นสีชมพู, สัญญาณเอาต์พุตที่ผ่านการกรอง (highPassFilteredValue) เป็นสีเทาและสัญญาณความถี่ต่ำ (lowPassFilteredValue) จะเป็นสีส้ม โดยจะสังเกตเห็นว่าที่ค่า alpha เท่ากับ 0.1 สัญญาณอินพุตและสัญญาณเอาต์พุตจะคล้ายกัน แต่ที่ค่า alpha กับค่า 0.5 และ 0.9 จะสามารถกรองความถี่สูงได้ดี ทั้งนี้เราสามารถปรับค่า alpha ให้มากหรือน้อยเพื่อเลือกผลลัพธ์ที่ต้องการนำไปใช้งานได้

ในการกรองสัญญาณความถี่สูงผ่านแบบดิจิตอล (Digital High-Pass Filter) โดยใช้บอร์ดประมวลผล Arduino 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/