Simple Digital Band-Stop Filter by using Arduino UNO [LEP]

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

Simple Digital Band-Stop Filter by using Arduino UNO

ดังนั้นจึงสรุปได้ว่า โปรแกรมส่วนใหญ่ของการกรองช่วงความถี่ที่ไม่ต้องการออก (Band-Stop Filter) จะเป็นโปรแกรมคำสั่งของการกรองความถี่แบบให้ช่วงความถี่ที่ต้องการผ่าน (Band-Pass Filter) ซึ่งในบทความนี้จะของยกโปรแกรมทั้งหมดมาจากบทความในตอนที่ 3 (EP3) แต่จะเพิ่มสมการคำนวณในส่วนของผลต่างระหว่างสัญญาณอินพุตที่เข้ามากับการกรองความถี่แบบให้ช่วงความถี่ผ่านเท่านั้น (float filteredBS = rawValue – filteredBP;) เพื่อให้เข้าใจโปรแกรมทั้งหมดได้ง่ายยิ่งขึ้น

/* 
   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.09; // 0.02 กรองความถี่สูงออกไปมาก, เหลือแต่ความถี่ต่ำมากๆ
const float EMA_ALPHA_HIGH = 0.4; // 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 -----------------   
  float filteredBP = ema_lp_high - ema_lp_low; 

  //------- Calc Band-stop Filter OUT PUT ---------  
  float filteredBS = rawValue - filteredBP; 
 
  Serial.print("Raw Value: ");
  Serial.print(rawValue);
  Serial.print("\tfilteredBP: ");
  Serial.print(filteredBP);
  Serial.print("\tFiltered BS: ");
  Serial.println(filteredBS); 
}

สำหรับโปรแกรมกรองช่วงความถี่ผ่านไม่ให้ผ่าน (Band-Stop Filter) ที่แสดงข้างบน จะแบ่งออกเป็น 7 กลุ่ม ดังนี้

กลุ่มแรก จะเป็นการประกาศค่าตัวแปรต่างๆ สำหรับใช้การคำนวณในช่วงต้นๆ ของโปรแกรม โดยจะรวมทั้งการกำหนดอัตราการสื่อสารพอร์ตอนุกรม (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)
กลุ่มที่หก จะเป็นโปรแกรมสมการเพื่อหาผลต่างระหว่างสัญญาณอินพุตกับผลของการกรองช่วงความถี่ผ่าน(Band-Pass Filter) ซึ่งจะเป็นผลลัพธ์ของการกรองความถี่แบบช่วงความถี่ที่ไม่ต้องการออกทางด้านเอาต์พุต (float filteredBS = rawValue – filteredBP;)
กลุ่มที่เจ็ด จะเป็นคำสั่งสำหรับแสดงผลการทำงานของโปรแกรมที่ได้จากการสมการต่างๆ โดยจะสามารถดูผลที่เกิดขึ้นที่เมนู Serial Plotter โดยจะแสดงในส่วนของสัญญาณอินพุต, สัญญาณความถี่คัตออฟช่วง (Upper Cutoff) เทียบกับสัญญาณเอาต์พุตช่วงความถี่ผ่านให้เข้าใจง่าย

Simple Digital Band-Stop Filter by using Arduino UNO
รูปที่ 1 การทดลองกำหนดให้ค่า EMA_ALPHA_LOW = 0.01 และ EMA_ALPHA_HIGH = 0.1
Simple Digital Band-Stop Filter by using Arduino UNO
รูปที่ 2 การทดลองกำหนดให้ค่า EMA_ALPHA_LOW = 0.05 และ EMA_ALPHA_HIGH = 0.2
Simple Digital Band-Stop Filter by using Arduino UNO
รูปที่ 3 การทดลองกำหนดให้ค่า EMA_ALPHA_LOW = 0.08 และ EMA_ALPHA_HIGH = 0.3

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

Simple Digital Band-Stop Filter by using Arduino UNO

ในบทความเกี่ยวกับกรองความถี่แบบดิจิตอลด้วยบอร์ดประมวลผล Arduino UNO ที่นำเสนอมาทั้ง 4 ตอนนี้ เป็นเนื้อหาในรูปแบบหนึ่งของวิธีการกรองความถี่แบบดิจิตอล (Exponentially Weighted Moving Average : EWMA) ที่ใช้ความสามารถของบอร์ดประมวลผลไม่มากนัก รวมทั้งต้องการให้เนื้อหาที่นำเสนอเป็นแนวทางเบื้องต้น ของการนำไปประยุกต์ใช้งาน นอกจากนี้ยังมีวิธีการกรองความถี่ในรูปแบบต่างๆ สำหรับผู้อ่านที่ต้องการศึกษาเพิ่มเติม (ลองใช้คำค้นหา “Type of digital filter for Arduino”) โดยแนะนำให้ใช้บอร์ดประมวลผลที่มีความสามารถที่สูงขึ้น

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/