Simple Digital Low-Pass Filter by using Arduino UNO [EP1]

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

Simple Digital Low-Pass Filter by using Arduino UNO

สำหรับในการทดลองในบทความครั้งนี้ จะเป็นการสร้างตัวกรองความถี่ต่ำผ่านแบบดิจิตอล (Digital Low-Pass Filter) โดยใช้บอร์ดประมวลผล Arduino ซึ่งมีวิธีการที่หลากหลาย แต่ที่นิยมและเข้าใจง่ายคือ Exponentially Weighted Moving Average (EWMA) หรือเรียกว่า Simple Moving Average (SMA) ในลักษณะของการถ่วงน้ำหนักด้วยการเฉลี่ยค่าโดยให้น้ำหนักกับค่าปัจจุบันและค่าเฉลี่ยก่อนหน้า ดังสมการที่แสดงข้างล่าง

FilteredValue=(α×CurrentValue)+((1−α)×PreviousFilteredValu

เมื่อกำหนดให้
– CurrentValue ค่าปัจจุบันที่อ่านได้จากเซนเซอร์
– PreviousFilteredValue ค่าที่ผ่านการกรองแล้วในรอบก่อนหน้า
α (alpha) เป็นค่าคงที่ระหว่าง 0 ถึง 1 ที่ใช้กำหนดน้ำหนักของการกรองความถี่สูงคือ เมื่อกำหนดให้ค่า alpha น้อยจะช่วยให้การกรองความถี่สูงออกได้ดีขึ้น ในทางกลับกันเมื่อกำหนดให้ค่า alpha ใกล้เคียง 1 จะทำให้การตอบสนองต่อการกรองความถี่สูงลดลง

    
    /* 
     Arduino UNO Code By : https://gemini.google.com/ 
     Key word prompt : Digital Low-Pass Filter by using Arduino and Exsample code
    */
    
    const int analogPin = A0;      
    float alpha = 0.1;             
    float filteredValue = 0;
    int   fdelay = 0;   
    int currentValue = 0;     
    
    void setup() {
      Serial.begin(9600);                                  
      filteredValue = analogRead(analogPin); 
    }
    
    void loop() {
      // int currentValue = analogRead(analogPin); 
    
      currentValue = random(1,1023); // Adj Amplitude Signal Analog input
      
      fdelay = random(1,300);        // Adj Frequency Signal Analog input 
               delay(fdelay); 
      
      filteredValue = (alpha * currentValue) + ((1 - alpha) * filteredValue);
    
      Serial.print("Raw Value: ");
      Serial.print(currentValue);
      Serial.print(" | Filtered Value: ");
      Serial.println(filteredValue); 
    }

    ในโปรแกรม Code Arduino ที่แสดงข้างบนจะเห็นว่า เดิมที่คำสั่ง int currentValue = analogRead(analogPin); จะให้ถูกหยุดการใช้งาน (กำหนดเป็นคอมเมนแทน) แต่จะเป็นคำสั่ง currentValue = random(1,1023); เพื่อเป็นการจำลองสร้างสัญญาณอะนาลอกแทน โดยจะสุ่มค่าออกมาเรื่อยๆ (สุ่มค่าในช่วง 0-1023) และทำให้มีขนาดของแอมปริจูดที่แตกต่างกัน อีกส่วนหนึ่งคือคำสั่ง fdelay = random(1,300); และ delay(fdelay); จะทำให้เกิดการสุ่มค่าการหน่วงเวลา (สุ่มในช่วง 1-300mS) ซึ่งจะทำให้เกิดความถี่ที่ต่างกันออกไปสำหรับใช้ในการทดลองครั้งนี้

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

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

    Simple Digital Low-Pass Filter by using Arduino UNO

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

    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/