ผู้เริ่มต้น
สร้างเข็มทิศดิจิทัลและจอแสดงผลการเอียง
เซ็นเซอร์จอแสดงผล
ชี้แล้วดูทิศที่แท้จริงแบบเรียลไทม์บนหน้าจอ การรับรู้การวางแนวที่แท้จริง เซ็นเซอร์ประเภทเดียวกับที่อยู่เบื้องหลังเข็มทิศและการหมุนอัตโนมัติของโทรศัพท์
รวมชิ้นส่วนจริง 3 รายการ
ราคารวมชุดนี้: 1,170.00 ฿
ยังไม่รวมส่วนลดคำสั่งซื้อที่คุณอาจได้รับตอนชำระเงิน
สิ่งที่คุณต้องใช้
เป้าหมายของโปรเจกต์
โปรเจกต์นี้สร้างหน้าจอแสดงทิศทางที่แท้จริง: เอียงหรือหมุนเซ็นเซอร์แล้วดูหน้าจอแสดงผลตามแบบเรียลไทม์ ซึ่งเป็นเทคโนโลยีการตรวจจับพื้นฐานเดียวกันกับระบบหมุนหน้าจออัตโนมัติของโทรศัพท์และการรักษาสมดุลการบินของโดรนทุกเครื่อง เพียงแต่แสดงผลบนหน้าจอขนาดเล็กแทนที่จะซ่อนอยู่ภายในอุปกรณ์ที่ใหญ่กว่า
คอนโทรลเลอร์ทำอะไร
มันอ่านค่าการเคลื่อนไหวดิบของเซ็นเซอร์อย่างต่อเนื่อง แปลงค่าเหล่านั้นให้เป็นค่าความเอียงหรือทิศทางที่ใช้งานได้ และอัปเดตการแสดงผลหลายสิบครั้งต่อวินาที เพื่อให้การอ่านค่ารู้สึกเหมือนจริงและไม่ล่าช้า
IMU ทำอะไร
มันรวมเอาตัววัดความเร่ง (accelerometer) ซึ่งตรวจจับทิศทางของแรงโน้มถ่วง เข้ากับไจโรสโคป (gyroscope) ซึ่งตรวจจับความเร็วในการหมุน ทำให้คอนโทรลเลอร์มีทุกสิ่งที่จำเป็นในการคำนวณทิศทางและการเคลื่อนไหวแบบเรียลไทม์ผ่านอินเทอร์เฟซ I2C แบบง่าย
จอแสดงผลทำอะไร
มันแสดงค่าความเอียงหรือทิศทางปัจจุบัน ไม่ว่าจะเป็นตัวเลขดิบ หรือหากใช้โค้ดเพิ่มเล็กน้อย ก็สามารถแสดงเป็นตัวบ่งชี้ภาพที่เรียบง่าย เช่น เส้นขอบฟ้าหรือแท่งเอียง
แนวคิดซอฟต์แวร์และไลบรารี
เริ่มต้นด้วยการพิมพ์ค่า accelerometer และ gyroscope ดิบเพื่อยืนยันว่าเซ็นเซอร์เชื่อมต่อสายและสื่อสารได้อย่างถูกต้อง จากนั้นจึงค่อยทำงานกับการรวมค่าเหล่านั้นเข้ากับมุมเอียงที่เสถียรก่อนที่จะกังวลเรื่องการแสดงผลใดๆ
การทดสอบและการแก้ไขปัญหา
- ค่าที่อ่านได้จะค่อยๆ คลาดเคลื่อนไปตามเวลาแม้ว่าเซ็นเซอร์จะอยู่นิ่งสนิท นี่คือลักษณะปกติของไจโรสโคป ให้ลองใช้ตัวกรองแบบ complementary หรือ Kalman แบบง่ายที่รวมเซ็นเซอร์ทั้งสองเข้าด้วยกันแทนที่จะเชื่อถือไจโรสโคปเพียงอย่างเดียว
- เซ็นเซอร์ไม่อ่านค่าใดๆ เลย หรืออ่านค่าคงที่ ให้ตรวจสอบสายไฟและที่อยู่ I2C ซ้ำอีกครั้ง และยืนยันว่าไม่มีอุปกรณ์ I2C อื่นบนบัสเดียวกันใช้ที่อยู่ที่ขัดแย้งกัน
- ค่ามีการกระโดดไปมาเมื่อหยุดนิ่ง เซ็นเซอร์อาจต้องการขั้นตอนการสอบเทียบสั้นๆ ตอนเริ่มต้น โดยการอ่านและหาค่าเฉลี่ยของค่าที่หยุดนิ่งก่อนที่จะใช้เป็นค่าอ้างอิง
การอัปเกรดเสริม
เพิ่มออดจากกล่องอะไหล่เพื่อส่งเสียงเตือนหากมุมเอียงเกินเกณฑ์ ซึ่งเป็นสัญญาณเตือนระดับทางกายภาพแบบง่ายๆ ที่สร้างขึ้นจากเซ็นเซอร์เดียวกัน
การเชื่อมต่อสาย
- MPU6050 VCC → ESP32-C3 3.3V
- MPU6050 GND → ESP32-C3 GND
- MPU6050 SDA → ESP32-C3 GPIO8 (I2C เริ่มต้น)
- MPU6050 SCL → ESP32-C3 GPIO9 (I2C เริ่มต้น)
- OLED VCC → ESP32-C3 3.3V
- OLED GND → ESP32-C3 GND
- OLED SDA → ESP32-C3 GPIO8 (บัสร่วมกับ MPU6050)
- OLED SCL → ESP32-C3 GPIO9 (บัสร่วมกับ MPU6050)
จงซื่อสัตย์กับตัวเองว่าโปรเจกต์นี้คืออะไร: MPU6050 เป็นแค่ accelerometer + gyroscope เท่านั้น — ไม่มี magnetometer ดังนั้นมันไม่สามารถตรวจจับทิศเหนือแม่เหล็กได้จริงและไม่สามารถสร้างทิศทางเข็มทิศที่แท้จริงได้ สิ่งที่อยู่ด้านล่างนี้คือการแสดงผลความเอียง/ระดับที่แท้จริงโดยใช้ accelerometer pitch และ roll ซึ่งแม่นยำเมื่ออยู่นิ่งหรือเคลื่อนที่ช้าๆ เข็มทิศแม่เหล็กที่แท้จริงจะต้องมี magnetometer เพิ่มเติม (เช่น HMC5883L หรือ QMC5883L) ซึ่งไม่ได้อยู่ในรายการชิ้นส่วนนี้
แผนภาพการต่อสาย
โค้ดเริ่มต้น
#include <Wire.h>
#include <Adafruit_MPU6050.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
// --- ESP32-C3 SuperMini default I2C pins - adjust if your board differs ---
#define SDA_PIN 8
#define SCL_PIN 9
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_ADDR 0x3C
Adafruit_MPU6050 mpu;
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
void setup() {
Serial.begin(115200);
Wire.begin(SDA_PIN, SCL_PIN);
if (!display.begin(SSD1306_SWITCHCAPVCC, OLED_ADDR)) {
Serial.println("OLED init failed");
while (true) delay(1000);
}
if (!mpu.begin()) {
Serial.println("MPU6050 not found - check wiring/address");
while (true) delay(1000);
}
mpu.setAccelerometerRange(MPU6050_RANGE_8_G);
mpu.setGyroRange(MPU6050_RANGE_500_DEG);
mpu.setFilterBandwidth(MPU6050_BAND_21_HZ);
display.clearDisplay();
display.setTextColor(SSD1306_WHITE);
}
void loop() {
sensors_event_t accel, gyro, temp;
mpu.getEvent(&accel, &gyro, &temp);
// Pitch/roll from the accelerometer's gravity vector - valid at rest / slow motion
float pitch = atan2(accel.acceleration.y,
sqrt(accel.acceleration.x * accel.acceleration.x +
accel.acceleration.z * accel.acceleration.z)) * 180.0 / PI;
float roll = atan2(-accel.acceleration.x, accel.acceleration.z) * 180.0 / PI;
display.clearDisplay();
display.setTextSize(1);
display.setCursor(0, 0);
display.println("Tilt Display");
display.setCursor(0, 16);
display.print("Pitch: ");
display.print(pitch, 1);
display.println((char)247);
display.setCursor(0, 28);
display.print("Roll: ");
display.print(roll, 1);
display.println((char)247);
// simple bubble-level dot
int cx = 64, cy = 52;
int dotX = constrain(cx + (int)roll, 20, 108);
int dotY = constrain(cy + (int)pitch, 40, 63);
display.drawCircle(cx, cy, 12, SSD1306_WHITE);
display.fillCircle(dotX, dotY, 2, SSD1306_WHITE);
display.display();
delay(100);
}
ไม่แน่ใจขั้นตอนไหน?
ถามเรา