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

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

Simple Digital High-Pass Filter by using 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 โดยจะแสดงค่าสัญญาณอินพุต,สัญญาณความถี่ต่ำผ่าน โดยเทียบกับสัญญาณเอาต์พุตให้เข้าใจง่าย

Simple Digital High-Pass Filter by using Arduino UNO
รูปที่ 1 การทดลองกำหนดให้ค่า alpha เท่ากับ 0.1 ในการกรองความถี่
Simple Digital High-Pass Filter by using Arduino UNO
รูปที่ 2 การทดลองกำหนดให้ค่า alpha เท่ากับ 0.5 ในการกรองความถี่
Simple Digital High-Pass Filter by using Arduino UNO
รูปที่ 3 การทดลองกำหนดให้ค่า alpha เท่ากับ 0.9 ในการกรองความถี่

ในรูปที่ 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 ให้มากหรือน้อยเพื่อเลือกผลลัพธ์ที่ต้องการนำไปใช้งานได้

Simple Digital High-Pass Filter by using Arduino UNO

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

Reference

  1. https://gemini.google.com/
  2. https://www.norwegiancreations.com/2016/03/arduino-tutorial-simple-high-pass-band-pass-and-band-stop-filtering/
  3. https://github.com/MartinBloedorn/libFilter
  4. https://docs.simplefoc.com/low_pass_filter
  5. https://www.instructables.com/FIR-Filtering-for-More-Reliable-Frequency-Detectio/