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

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

Digital Band-Pass Filter by using 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) เทียบกับสัญญาณเอาต์พุตช่วงความถี่ผ่านให้เข้าใจง่าย

Simple Digital Band-Pass Filter by using Arduino UNO
รูปที่ 1 การทดลองกำหนดให้ค่า EMA_ALPHA_LOW = 0.01 ในการกรองความถี่
Simple Digital Band-Pass Filter by using Arduino UNO
รูปที่ 2 การทดลองกำหนดให้ค่า EMA_ALPHA_LOW = 0.03 ในการกรองความถี่
Simple Digital Band-Pass Filter by using Arduino UNO
รูปที่ 3 การทดลองกำหนดให้ค่า EMA_ALPHA_LOW = 0.06 ในการกรองความถี่

ในรูปที่ 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 ให้มากหรือน้อย ตามความเหมาะสมกับการนำไปใช้งานได้

Simple Digital Band-Pass Filter by using Arduino UNO

สำหรับการกรองช่วงความถี่ผ่านด้วยบอร์ดประมวลผล Arduno UNO ในตอนนี้ จะเป็นเนื้อหาต่อเนื่องมาจากการกรองสัญญาณความถี่ต่ำและความถี่สูงที่ผ่านมา ซึ่งจะใช้พื้นฐานเดียวกันมาทั้งหมดและเราสามารถนำไปประยุกใช้งานได้ไม่ยากนัก ในตอนต่อไปจะเป็นวิธีการกรองช่วงความถี่ที่ไม่ต้องการออก (Digital Band-Stop Filter) ซึ่งจะเป็นการกรองความถี่ด้วยบอร์ดประมวลผล Arduno 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/