Chia sẻ Đọc dữ liệu từ cảm biến MPU6050 dùng bộ lọc Kalman (code for PIC)

Thảo luận trong 'Robot'

Đang xem chủ đề này ( Thành viên: 0, Khách: 1)

  1. tam762410

    tam762410 Sinh viên đại học

    Tham gia ngày:
    20/2/13
    Bài viết:
    45
    Đã được thích:
    31
    Điểm thành tích:
    18
    Giới tính:
    Nam
    :D.. đơn giản lắm bạn ạ.. trong con MPU có chức năng lựa chọn tần số cập nhật giá trị đấy... mình sử dụng thế này...
    Cấu hình cho con MPU cập nhật giá trị mới là 10ms (tùy vào con MCU mà bạn chọn nếu đủ mạnh và giải thuật sử lí không cần gì nhiều thì bạn có thể cấu hình cho nó hoạt động nhanh hơn như 1ms, 2ms... chẳn hạn ).. tiếp tục Cấu hình cho MPU sinh ra cờ ngắt nếu cập nhật giá trị xong ( có 2 trường hợp 1 cấu hình đưa ra tín hiệu phản hồi ra chân INT của MPU hoặc chỉ set cờ trạng thái trong thanh ghi)//... Trên module MPU có 1 châ báo hiệu khi dữ liệu chuyển đổi xong bạn có thể cho vào bộ ngắt ngoài, hoặc trong thanh ghi của MPU có 1 bit cờ báo hiệu .. Bạn có thể đọc cờ đó khi nào cờ đó lên 1 thì bạn lấy giá trị gyro và acc.. và deltat = 10ms chính là thời gian bạn cấu hình cho MPU... Lưu ý nếu dùng timer và cách đọc thanh ghi cờ ngắt của MPU thì tần số hoạt động của timer > 2 lần tần số MPU tức < 5ms.. Để không bỏ só dữ liệu. Thân chào bạn...
     
  2. tam762410

    tam762410 Sinh viên đại học

    Tham gia ngày:
    20/2/13
    Bài viết:
    45
    Đã được thích:
    31
    Điểm thành tích:
    18
    Giới tính:
    Nam
    bộ lọc bù bạn có thể tìm tren mạng nhiều lắm nó có tên gọi là
    Complementary filter......

    bạn tham khảo tại đây nhé
    Kalman filter vs Complementary filter
    hoặc tốt hơn bạn hãy sử dụng bộ lọc madgwick của sư huynh madgwick chế ra... nó tính toán hơi phức tạp nhưng đừng lo sư huynh madgwick rất tốt viết ra luôn bộ lọc ấy bằng C. Nếu không thích bạn có thể viết lại theo quy trình được nêu trong bài báo chủ yếu tính toán ma trận thôi.. bạn có thể sữ dụng bất kì con MCU nào.
    Nó có thể sử dụng lẩn cho bộ 6 trục hoặc 9 trục nếu thêm con la bàn.. nếu dùng bộ 6 trrucj thì không sao nhưng lưu ý nếu bạn ghép thêm con la bàn cho ra bộ 9 trục thì con la bàn bạn phải calib thật kỉ nếu không sẽ có sai số... Bạn có thể tìm thư viện ấy tại đây.
    Open source IMU and AHRS algorithms | x-io Technologies
    thân chào bạn....
     
  3. quanvanbinh

    quanvanbinh Học sinh phổ thông

    Tham gia ngày:
    31/12/14
    Bài viết:
    2
    Đã được thích:
    0
    Điểm thành tích:
    1
    Giới tính:
    Nam
    các bạn cho mình hỏi chút xíu.
    trong đoạn code của chủ thớt viết:
    int16 GetData(unsigned char address)
    {
    int16 H=0,L=0;
    //================================//
    i2c_start(); // start condition
    i2c_write(mpu6050); // Truyen/ghi dia chi den MPU6050
    i2c_write(address); // Chon dia chi thanh ghi address cua MPU6050
    i2C_start(); // Khoi dong lai I2C
    i2C_write(mpu6050|1); // Set MPU6050 truyen du lieu ve Master
    H=i2C_read(); // Doc du lieu tu MPU6050 ve Master (8 bit cao)
    L=i2C_read(0); // Doc du lieu tu MPU6050 ve Master (8 bit cao)
    i2c_stop(); // Ngung truyen nhan I2C
    //==================================================//
    //! H=Mpu6050_Read(address);
    //! L=Mpu6050_Read(address+1);
    return (H<<8)|L;
    }

    mình ko hiểu khúc này:
    H=i2C_read(); // Doc du lieu tu MPU6050 ve Master (8 bit cao)
    L=i2C_read(0); // Doc du lieu tu MPU6050 ve Master (8 bit cao)

    trong hàm main, bạn ấy chỉ gọi địa chỉ thanh ghi 8 bit cao để nạp vô hàm getdata:
    accY = GetData(ACCEL_YOUT_H);
    accZ = GetData(ACCEL_ZOUT_H);

    vậy làm sao lấy được 8 bit thấp????
    .
    .
    một điều hơi khó hiểu nữa là trong hàm main, chủ thớt viết chỉ lấy dữ liệu trục Y và Z để suy ra X. hack não như vậy liệu có đc ko?? chuẩn ko?? hay cứ lấy dữ liệu cả 3 trục luôn???
     
  4. tam762410

    tam762410 Sinh viên đại học

    Tham gia ngày:
    20/2/13
    Bài viết:
    45
    Đã được thích:
    31
    Điểm thành tích:
    18
    Giới tính:
    Nam
    coi lại I2C đi bạn.... trong trường hợp đó liên tục nhiều thanh ghi đó... Chủ thớt chỉ cần xác định thanh ghi cao là được rồi đọc liên tục 2 byte mà.... khi nào đọc xong mới Stop i2c đấy
     
  5. quanvanbinh

    quanvanbinh Học sinh phổ thông

    Tham gia ngày:
    31/12/14
    Bài viết:
    2
    Đã được thích:
    0
    Điểm thành tích:
    1
    Giới tính:
    Nam
    ok, thank bạn tam762410
    mình còn câu hỏi này các bạn trả lời dùm với ^_^
    DOUBLE gyroXrate = (double) gyroX / 131.0;
    vì sao lại chia cho 131???
     
  6. tam762410

    tam762410 Sinh viên đại học

    Tham gia ngày:
    20/2/13
    Bài viết:
    45
    Đã được thích:
    31
    Điểm thành tích:
    18
    Giới tính:
    Nam
    Chủ thớt chia theo thang đo mà bạn ấy đã sử dụng... chủ thớt cấu hình mpu với thang đo 250 o /s nên chia 131., 500 chia 65.5 , 1000 thì chia 32.8 , 2000 thì chia 16.4........ bạn coi lại datasheet của nó để hiểu rỏ thêm....
     
    asde thích bài này.
  7. thanhtao137

    thanhtao137 Học sinh phổ thông

    Tham gia ngày:
    20/11/15
    Bài viết:
    13
    Đã được thích:
    0
    Điểm thành tích:
    1
    timer =getstick();
    là gì v bạn ơi
    mình là người mới
    help mình chút xíu với
     
  8. phingocanhbk

    phingocanhbk Học sinh phổ thông

    Tham gia ngày:
    8/8/15
    Bài viết:
    18
    Đã được thích:
    0
    Điểm thành tích:
    1
    Giới tính:
    Nam
    cho mình xin hàm set_tick với get_tick với. mình mới học mong mọi người chỉ giúp, tks!
     
  9. naruto_95

    naruto_95 Học sinh phổ thông

    Tham gia ngày:
    1/2/15
    Bài viết:
    11
    Đã được thích:
    0
    Điểm thành tích:
    1
    Giới tính:
    Nam
    Bạn chia sẻ cách tính góc theo các trục x,y,z sử dụng chương trình của bạn được k
     
  10. huongvub

    huongvub Học sinh phổ thông

    Tham gia ngày:
    2/4/17
    Bài viết:
    1
    Đã được thích:
    0
    Điểm thành tích:
    1
    Giới tính:
    Nữ
    Chào bạn Dang123456,
    Mình đã đọc chương trình của bạn viết, cũng đọc file data sheet của 6050 nhưng vẫn còn chưa rõ cách quy đổi từ giá trị nhị phân đọc trực tiếp từ data registers của sensor sang radian hoặc độ. phần setting cho 6050 giả sử đặt -/+ 250 deg/s nghĩa là thang đo của sensor max min được giá trị đó, và mỗi độ thì được count 131. nếu mình có lệnh này gyroX = GetData(GYRO_XOUT_H); thì gyroX/131 là ra gyroX theo đơn vị góc là (độ/s). vận tốc góc đọc được không bao giờ quá +-250;
    accY = GetData(ACCEL_YOUT_H); thì muốn tính accY (trục Y) theo đơn vị g, accY/16384 (g) g có phải là degree không? muốn tính accY, accX, accZ theo g hoặc theo radian thì nhân chia với hằng số nào?
    accXangle = (atan2(accY,accZ)+PI)*RAD_TO_DEG; công thức này tính ra góc hay vẫn gia tốc góc.

    Post này từ lâu lắm rồi nhưng hy vọng là các bạn có thể nhận được và giải đáp giúp mình nhé. Cảm ơn bạn nhiều
     

Chia sẻ trang này