ลดทอนสัญญาณรบกวนแบบง่ายๆ
หลายคนคงเคยใช้เซ็นเซอร์จำพวก Infrared sensor, ultrasonic sensor, temperature sensor, sound sensor, light sensor, inertial sensor, current sensor ในโครงงาน arduino ที่เกี่ยวข้องกับการตรวจวัดและสำรวจสภาพแวดล้อมต่างๆ หรืออาจจะเป็นงานที่ต้องมีการโต้ตอบกับสิ่งรอบข้าง
![](https://o.lnwfile.com/d7b0pb.png)
แต่ทราบกันไหมครับว่าสัญญาณที่ได้จากเซ็นเซอร์เหล่านี้ล้วนแล้วแต่มีสัญญาณรบกวนติดมาด้วยทั้งสิ้น สัญญาณรบกวนนี้เองหากไม่กำจัดหรือทำการลดทอนลงจะทำให้ค่าที่เราทำการคำนวณมีความคลาดเคลื่อนจะมากน้อยขึ้นอยู่กับปริมาณสัญญาณรบกวนที่หลุดเข้ามาในระบบนั้นเอง
บทความนี้นำเสนอขั้นตอนง่ายๆในการลดทอนสัญญาณรบกวนที่ทำได้ในซอฟแวร์ด้วยโค๊ดแค่ไม่กี่บรรทัดโดยไม่ต้องต่อวงจรเพิ่มเติม สามารถเขียนฟังชันลดทอนสัญญาณรบกวนแบบลูปได้ตามสูตร y(n)=(1-a)*x(n)+a*y(n-1) โดยที่ y(n) คือ สัญญาณที่ทำการฟิลเตอร์แล้วของลูปล่าสุด y(n-1) คือสัญญาณที่ถูกฟิลเตอร์แล้วแต่ว่าเป็นของลูปที่แล้ว ส่วน x(n) คือสัญญาณที่วัดได้ของลูปล่าสุด และ a คือค่าคงที่ของฟิลเตอร์ (มีค่าระหว่าง 0 ถึง 1) ถ้าใครไม่ทราบว่าจะให้ a มีค่าเท่าไร อาจจะเริ่มจา a=0.95 ก่อนก็ได้ แล้วค่อบปรับจูนค่าตามความหมาะสมหลังจากดูผลการรันแล้ว ดูข้อมูลเพิ่มเติมเกี่ยวกับค่าคงที่นี้ได้ที่ Link
ใครอยากทดสอบประสิทธิภาพของวิธีนี้สามารถทดลองได้ตามโค๊ดด้านล่างซึ่งเป็นการจำลองสถานการณ์ว่าบอร์ดได้ต่อกับเซ็นเซอร์และรับสัญญาณที่มีสัญญาณรบกวนติดเข้ามาด้วย โดยใช้ a = 0.95 และค่าเบี่ยงเบนของสัญญาณรบกวนมีค่าเท่ากับหนึ่ง
int counter = 0;
float randNumber = 0.0;
float newVal = 0.0;
float dcBias = 1.0;
float simulatedVal = 0.0;
float filterConstant = 0.95; // filter constant
// the setup routine runs once when you press reset:
void setup() {
Serial.begin(9600);
randomSeed(100);
}
void loop() {
counter ++; // กำหนดให้หยุดการแสดงผลใน serial monitor ที่ 1000 ลูป
if (counter <= 1000) {
// สร้างสัญญาณรบกวนที่มีค่าเบี่ยงเบนมาตรฐานเท่ากับ 1
randNumber = (float) random(0,1000)/1000;
// แสดงผล column ที่ 1 คือ ครั้งที่ column ที่ 2 คือ ค่าสัญญาณที่มี nosie
// column ที่ คือค่าที่ถูก filter แล้ว
Serial.println("\t");
Serial.print(counter, DEC);
Serial.print("\t");
Serial.print(simulatedVal);
Serial.print("\t");
Serial.print(newVal);
Serial.print("\t");
Serial.print("");
}
// สร้างสัญญาณที่รับมาจาก sensor
simulatedVal = dcBias + randNumber;
// เรียกใช้ฟังชัน lowpass filter
newVal = smooth(simulatedVal, filterConstant, newVal);
delay(100);
}
// ฟังชั่น smooth หรือ lowpass filter
float smooth(float data, float filterVal, float smoothedVal){
smoothedVal = (data * (1 - filterVal)) + (smoothedVal * filterVal);
return smoothedVal;
}
|
โดยผลที่ได้หากนำมาพล็อตเป็นกราฟจะได้ตามรูปด้านล่าง กราฟสีดำเป็นสัญญาณจากเซ็นเซอร์ที่มีสัญญาณรบกวนติดมาด้วยส่วนกราฟแดงเป็นสัญญาณที่ถูกทำการฟิลเตอร์แล้วซึ่งจะเห็นว่าสามารถลดสัญญาณรบกวนไปได้เยอะพอสมควร
![](https://o.lnwfile.com/mhnuej.png)
By "Pink Panther"
Tags : Digital Filter
Share :
บทความการติดตั้งและใช้งาน Raspberry Pi
- การลงโปรแกรม
- Raspberry Pi - Media Center (ตอนที่ 1)
- Raspberry Pi - Media Center (ตอนที่ 2)
- Raspberry Pi - How to Cook Raspbian OS
- Raspberry Pi - Connect to the real world : Part 1
- Raspberry Pi -- Connect to the real world GPIO : Part 2
- Raspberry Pi กับ Shield ของ Arduino
- Raspberry Pi - Analog Input with ADC (MCP3208)
บทความการใช้งาน Arduino และอุปกรณ์ต่อพ่วงต่างๆ
- การลงโปรแกรมและไลบรารี่
- เรื่องของบอร์ด Arduino และ การใช้งานบอร์ด
- โมดูลเพื่อวัดค่าจากสิ่งแวดล้อม
- การใช้งาน DHT11 Humitdity and Temperature Sensor กับบอร์ด Arduino
- Ultrasonic Ranging Module HC-SR04
- Inertial Sensors: หามุม Pitch และ Roll จากเซ็นเซอร์วัดความเร่ง
- Real Time Clock DS3231
- Moisture Sensor on Arduino and Android over Bluetooth
- Moisture Sensor on Arduino and Android over Bluetooth: Part 2
- I2C Communication: Case study of GY-30 (Ambient Light Sensor)
- Inertial Measurement Unit - GY-80 Module for Arduino: Part 1 ADXL345
- Inertial Measurement Unit - GY-80 Module for Arduino: Part 2 L3G4200D
- โมดูลสื่อสาร
- การใช้งาน Motor และ Relay
- การแสดงค่าต่างๆ (แสง สี เสียง จอ)
- โมดูลเพื่อการบันทึกค่าและส่งค่า
- เรื่องของสัญญาณ
- เรื่องของ GPS และการประยุกต์ใช้
- เรื่องทั่วไปเกี่ยวกับ Arduino
ไม่มีความคิดเห็น:
แสดงความคิดเห็น