GLOBALBYTE PROJECTS / RASPBERRY PI / IMU / SENSOR FUSION
BNO055 กับ Raspberry Pi 5: ทดลอง Kalman Filter แก้ Gyro Drift
Gyroscope วางนิ่งอยู่บนโต๊ะ แต่ทำไมค่ามุมถึงค่อย ๆ เปลี่ยนไป? โปรเจกต์ของ Iloke Alusala นำ BNO055 Shuttle Board 3.0 เชื่อมต่อกับ Raspberry Pi 5 แล้วสร้าง Kalman Filter ด้วย Python เพื่อเปรียบเทียบข้อมูลจาก Raw Gyroscope กับมุมที่ผ่าน Sensor Fusion บน Web Dashboard แบบ 3D
- Gyroscope วัดอัตราการหมุน แต่การสะสมมุมอาจเกิด Drift จากค่า Bias
- Accelerometer ช่วยอ้างอิง Roll/Pitch จากแรงโน้มถ่วง แต่ได้รับผลกระทบจาก Noise และแรงเร่งขณะเคลื่อนไหว
- โปรเจกต์ใช้ BNO055 Shuttle Board 3.0 กับ Raspberry Pi 5 ผ่าน I²C
- โค้ดจริงใช้ AMG Mode เพื่ออ่านข้อมูลดิบ แล้วประมวลผล Kalman Filter ด้วย Python
- Web Dashboard แสดง Raw Gyro เทียบกับ Kalman Filter เป็นบอร์ด 3D สองฝั่ง
โปรเจกต์ Kalman Filter บน BNO055 คืออะไร?
Iloke Alusala สร้างโปรเจกต์นี้เพื่อแสดงให้เห็นว่า เมื่อใช้ข้อมูล Gyroscope ชุดเดียวกัน แต่เลือกวิธีคำนวณมุมต่างกัน ผลลัพธ์จะเปลี่ยนไปอย่างไร
ฝั่งแรกนำอัตราการหมุนจาก Gyroscope มาสะสมเป็นมุมโดยตรง ส่วนอีกฝั่งใช้ Kalman Filter ผสานข้อมูลจาก Gyroscope และ Accelerometer เพื่อประมาณมุม Roll/Pitch พร้อมชดเชย Gyro Bias
สะสมมุมจาก Gyro โดยไม่ใช้ Accelerometer แก้ Bias จึงเกิด Drift สะสมได้
ประมาณ Angle และ Gyro Bias โดยมีข้อมูล Accelerometer ช่วยปรับมุม Roll/Pitch
ทั้งสองวิธีใช้ข้อมูลจากเซนเซอร์เดียวกัน แล้วส่งผลลัพธ์ไปแสดงบนหน้าเว็บที่มีบอร์ด 3D สองฝั่ง เพื่อให้สามารถเปรียบเทียบพฤติกรรมของอัลกอริทึมได้
Gyro Drift คืออะไร และ Kalman Filter ช่วยอย่างไร?
Gyroscope วัดความเร็วในการหมุน ไม่ได้วัดมุมโดยตรง
เมื่ออ่านอัตราการหมุนจาก Gyroscope เราสามารถสะสมค่านั้นตามช่วงเวลาเพื่อประมาณมุมที่เปลี่ยนไปได้ แต่ถ้าเซนเซอร์มี Error หรือ Bias แม้เพียงเล็กน้อย ความคลาดเคลื่อนก็อาจสะสมเพิ่มขึ้นเรื่อย ๆ
Accelerometer ช่วยอ้างอิงทิศทางแรงโน้มถ่วง
Accelerometer ให้ข้อมูลที่ช่วยประมาณ Roll และ Pitch ได้เมื่ออยู่ในสภาพแวดล้อมเหมาะสม แต่การสั่นและแรงเร่งจากการเคลื่อนไหวอาจรบกวนค่าที่อ่าน จึงไม่ควรใช้ Accelerometer เพียงตัวเดียวสำหรับทุกสถานการณ์
Kalman Filter ทำให้ข้อมูลสองแบบช่วยกัน
ในโปรเจกต์นี้ Kalman Filter มีสถานะสำคัญสองส่วนต่อแกน ได้แก่ Angle และ Gyro Bias โดยใช้ข้อมูล Gyroscope สำหรับ Predict และข้อมูล Accelerometer สำหรับ Update
Hardware และ Software ที่ใช้
| รายการ | หน้าที่ |
|---|---|
| Raspberry Pi 5 | อ่านค่า IMU และรัน Python กับ Web Server |
| BNO055 Shuttle Board 3.0 | วัดข้อมูล Accelerometer, Gyroscope และ Magnetometer |
| สาย Jumper / Connector 1.27 มม. | เชื่อม Shuttle Board เข้ากับ Raspberry Pi |
| Raspberry Pi OS / SSH | ใช้งาน Raspberry Pi แบบ Headless |
| Python + smbus2 | อ่านเซนเซอร์ผ่าน I²C |
| aiohttp | Web Server และ WebSocket |
| uv | จัดการ Python Virtual Environment |
| Three.js | แสดงบอร์ด 3D ในเว็บเบราว์เซอร์ |
จุดที่ต้องระวังคือ Shuttle Board 3.0 ไม่ได้มี Connector แบบเดียวกับ BNO055 Breakout Board ทั่วไป ผู้สร้างระบุว่าคอนเนกเตอร์ของบอร์ดมีระยะ 1.27 มม. และต้องเตรียมสายให้เข้ากัน
Step 1: ต่อ BNO055 Shuttle Board 3.0 เข้ากับ Raspberry Pi 5
ขั้นตอนเริ่มจากเตรียมสาย Connector ให้พอดีกับ Shuttle Board จากนั้นจึงเชื่อมต่อ VDD, VDDIO, GND และสัญญาณ I²C ไปยัง Raspberry Pi 5
การเตรียมสาย Connector
ตาราง Wiring ที่ผู้สร้างใช้
| BNO055 Shuttle Board | Raspberry Pi 5 / การต่อ |
|---|---|
| P1-1 VDD | Pin 1 (3.3V) |
| P1-2 VDDIO | Pin 17 (3.3V) |
| P1-3 GND | Pin 6 (GND) |
| P1-6 PS0 | GND |
| P1-7 PS1 | GND |
| P2-2 SCL | Pin 5 (SCL) |
| P2-3 SDO | GND เพื่อเลือก Address 0x28 |
| P2-4 SDA | Pin 3 (SDA) |
Physical Wiring Diagram
ภาพการเชื่อมต่อที่ประกอบเสร็จ
ตรวจตำแหน่ง GPIO Pinout
ควรเปิด Bosch Shuttle Board 3.0 Flyer PDF ควบคู่กับ Diagram เพื่อตรวจการระบุขา P1/P2 ก่อนจ่ายไฟ
Step 2: ตั้งค่า I²C และ Python Environment
ผู้สร้างใช้งาน Raspberry Pi แบบ Headless ผ่าน SSH เริ่มจากเปิด I²C แล้วติดตั้งเครื่องมือสำหรับตรวจสอบการสื่อสารกับ BNO055
เมื่อใช้ i2cdetect -y 1 หากเห็น Address 28 ในตาราง แสดงว่ามีอุปกรณ์ตอบสนองที่ตำแหน่งนี้ แต่ยังต้องตรวจ CHIP_ID อีกครั้งเพื่อยืนยันว่าเป็น BNO055
การติดตั้ง Python ใช้เครื่องมือ uv ตามขั้นตอนของผู้สร้าง โดยควรตรวจคำสั่งดาวน์โหลดสคริปต์จากแหล่งภายนอกก่อนรันบนเครื่องทุกครั้ง
Step 3: ทดสอบ BNO055 ด้วย NDOF Mode
ก่อนเริ่ม Kalman Filter ผู้สร้างใช้ไฟล์ bno055_bringup.py ตรวจการสื่อสาร โดยอ่าน CHIP_ID ที่ Register 0x00 และคาดหวังค่า 0xA0
จากนั้นสคริปต์ใช้ NDOF Mode ซึ่ง BNO055 ทำ Sensor Fusion ภายในชิปอยู่แล้ว เพื่อดู Euler Angle และ Calibration Status
ดาวน์โหลดไฟล์เต็มได้จาก bno055_bringup.py ที่ Hackster
Step 4: อ่านข้อมูลดิบด้วย AMG Mode และสร้าง Kalman Filter
ไฟล์ imu_fusion_server.py เปลี่ยน BNO055 เป็น AMG Mode โดยใช้ค่า 0x07 เพื่ออ่านข้อมูล Accelerometer, Magnetometer และ Gyroscope แบบดิบ
โค้ดอ่านข้อมูลเป็นบล็อก 18 ไบต์จาก I²C แล้วแยกค่า Accelerometer และ Gyroscope มาคำนวณ Roll/Pitch ด้วย Kalman Filter แบบ 2-State
| ตัวแปร | หน้าที่ในโค้ด |
|---|---|
ADDR = 0x28 |
I²C Address |
MODE_AMG = 0x07 |
อ่าน Raw Sensor Data |
SAMPLE_HZ = 100 |
ค่ากำหนดรอบ Sensor / Filter |
BROADCAST_HZ = 60 |
ค่ากำหนดรอบ WebSocket |
Kalman1D |
ประมาณ Angle และ Gyro Bias สำหรับ Roll/Pitch |
Kalman1D คำนวณอย่างไร?
Predict ใช้ข้อมูลอัตราการหมุนหลังหัก Bias ส่วน Update ใช้มุมจาก Accelerometer เพื่อช่วยปรับค่าประมาณและเรียนรู้ Bias ของ Gyroscope
ดูโค้ดทั้งหมดได้จาก imu_fusion_server.py บน GitHub ของผู้สร้าง
Step 5: แสดงผลผ่าน Web Dashboard แบบ 3D
Raspberry Pi ทำหน้าที่เป็น Web Server และส่งข้อมูลผ่าน WebSocket ให้หน้าเว็บที่ใช้ Three.js แสดงบอร์ด 3D สองฝั่งโดยอาศัยข้อมูลจากเซนเซอร์ตัวเดียวกัน
มุมจากการสะสมค่าของ Gyroscope โดยไม่แก้ Bias ด้วย Accelerometer
มุมจากการรวมข้อมูล Gyroscope และ Accelerometer สำหรับ Roll/Pitch
ปุ่ม Align raw ใช้จัดแนวของบอร์ด Raw ให้เริ่มต้นตรงกับฝั่ง Kalman อีกครั้ง ส่วน Zero yaw ใช้รีเซ็ต Heading ของทั้งสองฝั่ง
หน้า Dashboard เปิดศึกษาซอร์สได้ที่ index.html ของโปรเจกต์บน GitHub
Step 6: รันระบบและทดลองสังเกต Gyro Drift
หลังเตรียมโฟลเดอร์ ~/imu-cube และคัดลอกไฟล์ imu_fusion_server.py กับ index.html ลงในโฟลเดอร์เดียวกัน ให้เปิด Python Environment และรัน Server
ตรวจ IP ของ Raspberry Pi ด้วย hostname -I จากนั้นเปิดหน้าเว็บในรูปแบบ http://<pi-ip>:8080 จากคอมพิวเตอร์ที่อยู่เครือข่ายเดียวกัน
ทดลองเอียงเซนเซอร์เพื่อดูการหมุนของทั้งสองฝั่ง แล้วกด Align raw และวางเซนเซอร์นิ่งเพื่อสังเกตว่าค่า Raw Gyro กับ Kalman Filter เปลี่ยนแปลงต่างกันอย่างไร
- บอร์ดทั้งสองฝั่งตอบสนองเมื่อเอียงเซนเซอร์
- Raw Gyro อาจค่อย ๆ Drift แม้หยุดเคลื่อนไหว
- Kalman Filter ใช้ข้อมูล Accelerometer ช่วยแก้ Roll/Pitch
- ค่า Gyro Bias ใน Dashboard เปลี่ยนตามการประมาณของ Filter
bno055_bringup.py พร้อมกับ imu_fusion_server.py เพราะทั้งสองโปรแกรมจะพยายามเข้าถึงเซนเซอร์ตัวเดียวกัน และอาจทำให้การอ่านค่าผิดพลาดได้วิดีโอเสริม: การ Calibration BNO055 จาก Bosch Sensortec
ต้นฉบับของ Iloke ไม่ได้ฝังวิดีโอสาธิต Kalman Filter ไว้ แต่มีวิดีโออย่างเป็นทางการจาก Bosch Sensortec ที่อธิบายการ Calibration ของ BNO055 ซึ่งเหมาะสำหรับศึกษา Sensor Fusion ภายในชิปเพิ่มเติม
Video Source: Bosch Sensortec: How to Calibrate the Absolute Orientation Sensor BNO055
วิดีโอนี้เป็นคู่มือจากผู้ผลิต ไม่ใช่วิดีโอทดสอบของ Iloke และไม่ได้ใช้แทนผลลัพธ์ Kalman Filter ในโปรเจกต์นี้
Troubleshooting: ปัญหาที่ผู้สร้างพบ
| อาการ | สิ่งที่ควรตรวจสอบ |
|---|---|
/dev/i2c-1 ไม่พบ |
ตรวจว่าเปิด I²C แล้ว และ Reboot ระบบ |
Remote I/O error |
ตรวจ VDDIO, PS0, PS1, SDO และสาย GND |
i2cdetect พบ 0x29 |
ตรวจ SDO ซึ่งชุดต้นแบบต่อ GND เพื่อเลือก 0x28 |
Permission denied |
ตรวจสิทธิ์ผู้ใช้สำหรับ I²C ตามคู่มือต้นฉบับ |
| บอร์ดบน Dashboard หมุนผิดทิศ | ตรวจตัวเลือก Invert Axis |
| SCP แจ้งว่าไม่พบไฟล์ | ตรวจเส้นทางไฟล์และตำแหน่ง Destination |
| หน้า Dashboard ไม่ตอบสนอง | ตรวจสถานะ Python Server และการอ่านข้อมูลจาก BNO055 |
อ่านรายละเอียดปัญหาอื่น ๆ ได้จาก Step 8: Troubleshooting ของบทความต้นฉบับ
Source Code และไฟล์ดาวน์โหลดที่เกี่ยวข้อง
โปรเจกต์นี้มี Source Code หลักบน GitHub และมี Bring-up Script ที่ผู้สร้างแนบไว้ใน Hackster แยกจาก Repository ส่วนเอกสาร Bosch ช่วยตรวจรายละเอียด Hardware, Pinout และ Operating Mode
โปรเจกต์นี้ไม่มีไฟล์ STL หรือ Gerber ที่ยืนยันว่าเป็นส่วนหนึ่งของการสร้างระบบ Kalman Filter จึงไม่เพิ่มลิงก์ดาวน์โหลดที่ไม่เกี่ยวข้อง
FAQ: คำถามที่พบบ่อยเกี่ยวกับ Kalman Filter และ BNO055
1. BNO055 คืออะไร?
BNO055 เป็น Smart Sensor ที่มี Accelerometer, Gyroscope, Magnetometer และ Sensor Fusion ภายในชิป
2. ทำไม BNO055 มี Fusion ในตัวแล้ว แต่ยังต้องเขียน Kalman เอง?
โปรเจกต์นี้มุ่งสาธิตแนวคิด Sensor Fusion โดยตรง จึงอ่าน Raw Data ใน AMG Mode แล้วทำ Kalman Filter ด้วย Python
3. Raspberry Pi 5 ทำหน้าที่อะไร?
ทำหน้าที่รับข้อมูล I²C ประมวลผล Python และเปิด Web Server สำหรับ Dashboard
4. ทำไมต้องใช้ Shuttle Board 3.0 ตามต้นฉบับ?
ผู้สร้างใช้บอร์ดรุ่นนี้ในการทดลอง และ Wiring ที่เผยแพร่เป็น Pinout ของ Shuttle Board 3.0 ไม่ใช่ BNO055 Breakout Board ทุกรุ่น
5. ทำไม Address ของ BNO055 เป็น 0x28?
ชุดต้นแบบต่อ SDO ลง GND เพื่อเลือก I²C Address 0x28
6. NDOF Mode ต่างจาก AMG Mode อย่างไร?
NDOF ใช้ Sensor Fusion ภายใน BNO055 ส่วน AMG ให้ข้อมูลเซนเซอร์ดิบเพื่อให้ Python ประมวลผลเอง
7. Kalman Filter ในโปรเจกต์แก้ Drift ได้ครบ 3 แกนไหม?
ไม่ครบ โค้ดนี้แก้ Roll และ Pitch ส่วน Yaw ยังไม่ได้ใช้ Magnetometer Correction ตามที่ผู้สร้างระบุ
8. ต้องต่อจอกับ Raspberry Pi ตลอดหรือไม่?
ไม่จำเป็น ผู้สร้างใช้งานแบบ Headless และเปิดหน้า Dashboard จาก Laptop ผ่านเครือข่ายเดียวกัน
9. ใช้ Python Library อะไร?
ผู้สร้างใช้ smbus2 สำหรับ I²C และ aiohttp สำหรับ Web Server และ WebSocket
10. Web Dashboard ใช้อะไรสร้าง 3D?
ใช้ Three.js ร่วมกับ WebSocket เพื่อแสดงการเคลื่อนที่ของบอร์ดจำลอง
11. Sampling Rate เท่าไร?
Source Code ตั้งค่า Sensor/Filter Loop เป็น 100 Hz และ WebSocket Broadcast เป็น 60 Hz ตัวเลขนี้เป็นค่าที่กำหนดในโค้ด ไม่ใช่ค่าประสิทธิภาพที่ทดสอบรับประกัน
12. ผล Drift 90° และ 0.1° มาจาก BNO055 จริงหรือไม่?
ไม่ใช่ เป็นการทดสอบอัลกอริทึมด้วยข้อมูลจำลองที่ผู้สร้างอธิบายไว้
13. ถ้า i2cdetect ไม่พบ 0x28 ต้องทำอย่างไร?
ตรวจการเปิด I²C, VDDIO, PS0, PS1, SDO และการเชื่อมต่อ Connector ตาม Wiring ต้นฉบับ
14. มีวิดีโอของโปรเจกต์ให้ดูไหม?
ไม่พบวิดีโอที่ Iloke แนบไว้ใน Story แต่มีวิดีโอ Calibration ของ Bosch Sensortec เป็นแหล่งข้อมูลเสริม
สรุป: Kalman Filter ทำให้เข้าใจ Sensor Fusion ผ่านการทดลองจริง
จุดเด่นของโปรเจกต์นี้คือการนำ BNO055 กับ Raspberry Pi 5 มาทดลองเปรียบเทียบ Raw Gyro และ Kalman Filter โดยใช้ข้อมูลเดียวกัน เพื่อให้เห็นว่าการชดเชย Bias และการรวมข้อมูลจาก Accelerometer ช่วยเปลี่ยนพฤติกรรมของค่ามุม Roll/Pitch อย่างไร
สิ่งที่ได้เรียนรู้ครอบคลุมการเชื่อมต่อ I²C, การตั้งค่า Sensor Mode, การทำ Kalman Filter ด้วย Python และการแสดงผลผ่าน Web Dashboard ซึ่งเป็นพื้นฐานที่นำไปศึกษาต่อยอดด้าน Robotics และ Embedded Systems ได้
โปรเจกต์มีรายละเอียด Wiring และ Software หลายส่วน แนะนำให้อ่าน Tutorial ฉบับเต็มจาก Hackster พร้อมกับ Source Code บน GitHub ของผู้สร้าง ก่อนลงมือประกอบจริง
References / แหล่งข้อมูลต้นฉบับ
- Hackster: Set Up a Kalman Filter on a BNO055 With a Raspberry Pi 5
- GitHub: BNO055-Kalman_Filter โดย Iloke Alusala
- Bosch Sensortec: BNO055 Datasheet
- Bosch Sensortec: BNO055 Shuttle Board Flyer
- Astral: uv Documentation
- Embedder: เครื่องมือที่ผู้สร้างระบุว่าใช้
- Bosch Sensortec: BNO055 Calibration Tutorial
ต่อยอดโปรเจกต์ Raspberry Pi และ Sensor กับ GlobalByte
สนใจศึกษา Embedded Python, Robotics หรือ Sensor Fusion สามารถสอบถามทีม GlobalByte เกี่ยวกับ Raspberry Pi, Development Board, IMU Sensor และ Maker Accessories ที่เหมาะกับโปรเจกต์ของคุณได้ โดยควรตรวจ Pinout และความเข้ากันได้ของอุปกรณ์แต่ละรุ่นก่อนเลือกใช้งาน