Wednesday, March 26, 2014

Giao tiếp MSP430G2553 và cảm biến MPU6050

MPU6050 là IC tích hợp cảm biến tích gia tốc kế và cảm biến từ trường,từ cảm biến này có thể đo được tốc độ góc theo 3 chiều không gian(gyro),và hình chiếu vector trọng trường lên 3 trục trong không gian(Accelrometer).Ngoài ra  từ các giá trị này,người ta cho đi qua các bộ lọc số (chẳng hạn như AHRS Kalman...)để thu được giá trị đã loại bỏ nhiễu,các giá trị này tiếp tục được dùng để xác định các giá trị thứ cấp như tốc độ dài,tọa độ không gian.

Module MPU6050


MPU6050 và Giao Tiếp I2C.
a)    MPU6050
·        MPU6050 là chip tích hợp 2 cảm biến: vận tốc góc (gyroscope) và gia tốc góc (accelerometer).
·        MPU6050 cho biết vận tốc và gia tốc góc, từ đó xác định được hướng của vật trong không gian 3 chiều.
·        Dải điện áp hoạt động : 2,375V – 3,46V.
·        Nhiệt độ hoạt động tốt nhất 25°C.
·        Dải nhiệt hoạt đông:-40 đến +85°C.
·        Sơ đồ khối:

·        Hoạt động với 3 tần số xung clock:
Ø  Xung clock nội : CLK SEL = 0,1,2,3 .
Ø  Xung clock ngoài 32,768kHz : CLK_SEL = 4 .
Ø  Xung clock ngoài 19,2MHz : CLK_SEL = 5
·        Đầu ra là tín hiệu số về độ dịch góc của 3 trục X Y Z với đọ rộng thang đo ±250, ±500, ±1000, ±2000°/s .
·        Tín hiệu đồng hồ ngoài kết nối vào chân FSYNC hỗ trợ đồng bộ ảnh,video,GPS.
·        Tích hợp bộ chuyển đổi ADC 16bit lấy mẫu tốc độ góc cùng lúc.
·        Cho phép sử dụng chương trình ngắt.
·        Giao thức I2C : ở chế độ cơ bản là 100kHz - ở chế độ nhanh là 400kHz.
Ø  Bao gồm các dữ liệu nối tiếp tín hiệu (SDA) và đồng nối tiếp (SCL).
Ø  Khi kết nối với vi điều khiển MPU6050 đóng vai trò là slave. Địa chỉ Slave là b110100X.
Ø  I2C truyền dữ liệu theo từng byte, mỗi byte được gửi theo sau 1 tín hiệu ack
b)    Giao Tiếp I2C.
·        Giới thiệu sơ lược về I2C
Ø  I2C là một  loại bus ngoại vi được phát triển bởi hãng Philip
Ø  Nguồn cung cấp cho giao tiếp I2C thường la 5v hoặc 3.3v

Ø  I2C là giao tiếp được thực hiện trên hai đường dây: SCL và SDA
-  SCL:Dây truyền xung clock từ master đến slave.
-  SDA:Dây truyền dữ liệu theo 2 chiều.
Ø  Do trên bus i2c chỉ có 2 dây mà có thể gắn kết nhiều thiết bị nên cần phân biệt các thiết bị bằng địa chỉ
·        Phân loại thiết bị trên I2C
Ø  Các thiêt bị gắn trên bus i2c được chia ra làm 2 thành phần chính là master hoặc slave.
-  Thông thường trên bus i2c chúng ta sẽ có một chip vi điều khiển đóng vai trò master(đóng vai trò điều phối thông tin).
-  Trên bus i2c các cảm biến, bộ nhớ ngoài,adc,…. thường đóng vai trò là slave,trên bus i2c có thể co nhiều con slave
·        Cách đặt địa chỉ cho thiết bị có kết nối I2C
Ø  Ở đây ta chỉ quan tâm cách đặt địa chỉ 7 bit
Ø  Có thể có 128 thiết bị trên đường truyền,do có 16 địa chỉ được dự trữ nên chỉ có tối da 112 thiết bị trên đương truyền
Ø  Trên bus i2c ko thể kết nối 2 thiết bị có cùng địa chỉ.
·        Chế độ và tốc độ hoạt động
Ø  Chế độ hoạt động:
-   Một master – Một slave.
-   Một master – Nhiều slave.
-   Nhiều master – Nhiều slave. 
Ø  Tốc độ hoạt động:
-  Chế độ chậm: 10 kbit/s.
-  Chế độ cơ bản: 100 kbit/s.
-  Chế độ nhanh 1: 400 kbit/s.
-  Chế độ nhanh 2: 1 Mbit/s.
-  Chế độ tốc độ cao: 3.4 Mbit/s.
·        Vai trò của master và slave trong giao tiếp I2C
Ø  Vai trò của master.
-  Giữ vai trò điều khiển Bus I2C.
-  Tạo xung Clock ( SCL) trong suốt quá trình giao tiếp.
-  Tạo các tín hiệu Start bắt đầu quá trình truy xuất.
-  Phát địa chỉ của thiết bị Slave cần truy xuất.
-  Gửi tín hiệu R/W tới Slave.
- Truyền dữ liệu tới thiết bị Slave.
- Nhận dữ liệu từ Slave.
-  Tạo tín hiệu Not-ACK khi kết thúc nhận từ Slave.
-  Tạo tín hiệu Stop kết thúc quá trình truy xuất.
Ø  Vai trò cua slave
-  Nhận địa chỉ và bit R/W từ Master (Chỉ “Hồi đáp” khi đúng địa chỉ của Slave) .
-  Nhận dữ liệu từ Master gửi bit ACK sau mỗi 8 Clock.
- Thực hiện chức năng chuyên dụng của khối thiết bị ngoại vi ( RAM, EEPROM, ADC,DAC ngoài…).



·        Quá trình truyền dữ liệu trên bus i2c
Ø  Chế độ truyền dữ liệu:
- Để bắt đầu truyền dữ liệu master kéo dây SDA xuống mức 0 trong khi SCL ở mức 1.
- Sau khi SDA xuống mức 0 một khoảng thời gian ngắn thì SCL cũng xuống mức 0 và bắt đầu quá trình truyền dữ liệu.
-  Dữ liệu được truyền trên bus I2C theo từng bit  tại mỗi cạnh lên của xung Clock.



-  Để kết thúc truyền dữ liệu master kéo dây SDA xuống mức 0 trong khi SCL ở mức 1.
·        Quá trình đọc dữ liệu trên bus i2c
 Khung truyền 

Giải thích khung truyền :
-  Master gửi tín hiệu start.
-  Master gửi 7 bit địa chỉ thiết bị slave và bit write(bit 0) cuối cùng.
-  Slave nhận được 8 bit ở trên thi gửi trả tin hiệu AK(bit 0)
-  Master nhận được tín hiệu AK thì master gửi di 8 bit địa chỉ của thanh ghi có trong con slave.
-  Sau khi nhận 8 bit địa chỉ thi slave gửi trả                bit AK
-  Sau khi nhận bit AK master gửi tin hiệu restart rồi gửi lại địa chỉ thiết bị một lần nữa cùng bit read(bit 1).
-  Sau khi nhận 8 bit trên thi slave gửi trả bit AK và ngay sau đó gửi 8 bit data.
-  Nếu master muốn đọc tiếp dữ liệu thì sẽ gửi tiếp bit AK và slave se gửi tiếp 8 bit luôn mà ko cần tín hiệu AK ở trước nữa.
- Nêu ko muốn đọc dữ liệu nữa thì master sẽ gửi bit NAK(bit 1)sau đó gửi tín hiệu stop.
·        Quá trình ghi dữ liệu trên bus i2c

Giải thích khung truyền :
-  Master gửi tín hiệu start.
-  Master gửi 7 bit địa chỉ thiết bị slave và bit write(bit 0) cuối cùng.
-  Slave nhận được 8 bit ở trên thi gửi trả tin hiệu AK(bit 0)
-  Master nhận được tín hiệu AK thì master gửi di 8 bit địa chỉ của thanh ghi có trong con slave.
-  Sau khi nhận 8 bit địa chỉ thi slave gửi trả                bit AK.
-  Sau khi nhận bit AK master gửi đi 8 bit dữ liều cần ghi.
-  Sau khi nhận 8 bit dữ liệu slave sẽ gửi lại bit AK để xác định đã nhận dữ liệu.
- Nếu muốn ghi tiếp thi master gửi tiếp 8 bit, còn nếu muốn kết thúc thì master gửi tín hiệu stop(SP).
c)     Bộ Lọc

                       M = N = 12
                       fc = 10 
                       fs = 500

·        Tính toán hệ số của bộ lọc :
-  Wc = 0.1256=0.04
-  W[n] = {0.00006,0.065478,0.244205, 0.48835,0.732495,0.911222,0.97664,0.911222,                 0.732495,0.48835,0.244205,0.065478,0.00006}
-  Hd[n]= {0.026473,0.028424,0.030273,0.032001,0.03359,0.035037,0.036316,0.037419,0.038336,0.039059,0.03958,0.03989,0.04}
-  h[n]= {1.58*10^-6,1.86*10^-3,7.4*10^-3,0.0156,0.02460,0.031926,0.354676,0.034049,0.028098,0.01907,9.6*10^-3,2.6*10^-3,2.4*10^-6}

 Kết quả hiển thị trên gCOM.


Các bạn có thể download phần mềm vẽ đồ thị từ dữ liệu cổng UART tại đây
Code tham khảo các bạn có thế download tại đây,Giao diện chương trình rất đơn giản,MSP430G2553 nối với MPU6050 qua chân SCL-P1.6 và SDA-P1.7 .Và giao tiếp UART với máy tính tần số 9600.
Code MSP430 và MPU6050
Một số tài liệu tham khảo và file báo cáo : Tài liệu tham khảo
Để xem kết quả bạn có thể sử dụng phần mềm :Hiển thị kết quả đọc cảm biến

37 comments:

  1. Em ơi, em đã giao tiếp thành công msp430 với MPU6050 chưa?

    ReplyDelete
    Replies
    1. Em làm được rồi đấy ạ,có thư viện chung cho Module USCI I2C và MPU6050 ở link download trên rồi đấy ạ,chỉ cần add vào project,chân cắm như bình thường của giao thức I2C(ở đây là nối với module UCB của MSP540G2553,nối với P1.6 P1.7)

      Delete
  2. CHÀO BẠN.
    MÌNH CŨNG ĐANG NGHIÊN CỨU VỀ CÁI NÀY.
    BẠN CÓ THỂ ĐƯA SƠ ĐỒ NGUYÊN LY MÌNH XEM VỚI.
    VỚI BẠN DÙNG CCS HAY IAR VẬY

    ReplyDelete
    Replies
    1. Mình dùng CCS bạn ạ,Sơ đồ nguyên lý thì không có gì đâu,chỉ có chân SCL-P1.6 SDA-P1.7 thôi

      Delete
    2. bạn ơi có sơ đồ nguyên lí của MPU 6050 chưa, tớ xin với ak. Thanhks

      Delete
    3. Hình thứ 2 chính là sơ đồ khối của MPU đó bạn,còn module MPU6050 thì bạn chỉ cần quan tâm đến 4 chân đầu tiên là VCC GND SCL và SDA (của giao tiếp I2C ) thôi

      Delete
  3. Bạn ơi cho mình hỏi là hàm Set_PWM() mà bạn viết trong đó là để điều khiển motor hả bạn, nếu mình chỉ cần xuất ra UART thì bỏ phần đó được ko. Cảm ơn bạn đã chia sẻ.

    ReplyDelete
    Replies
    1. Uh cái này là mình share code trong đồ án của mình,chưa chỉnh lại gì,bạn cứ bỏ đi

      Delete
  4. Bạn có thể cho mình xin tài liệu tham khảo cách chuyển đổi data nhận được thành vận tốc góc, gia tốc góc được ko?

    ReplyDelete
    Replies
    1. Giá trị nhận dc là 16bit,còn tùy vào việc cài đặt tỷ lệ nữa,vd code của mình để tỷ lệ gia tốc trọng trường 65536-16g,chi tiêt bạn có thể xem trong datasheet MPU-6000A thanh ghi 27-28 ở link tài liệu tham khảo ở trên

      Delete
  5. Mình đã sửa lại code xóa các phần không cần thiết rồi nhé,chỉ còn đọc cảm biến hiển thị UART tần số 9600 . Module MPU6050 các bạn chỉ cần nối 2 chân SDA,SCL vào thôi,VCC có thể nối 3.3V hoặc 5V và chân GND là có thể chạy dc

    ReplyDelete
    Replies
    1. Bạn cho mình hỏi 3 biến ra 3 góc cuối cùng là 3 biến nào vậy bạn.
      thanks

      Delete
    2. Code này mình hầu như chưa xử lý gì đâu bạn ạ.Các biến GYRO_XOUT,GYRO_YOUT,GYRO_ZOUT,ACCEL_XOUT,ACCEL_YOUT,ACCEL_ZOUT là 6 giá trị lấy trực tiếp từ MPU6050,nó chính là giá trị của gyroscopt và accerometer

      Delete
    3. Chào anh, Anh có thể giúp em xóa bớt những phần để code đơn giản hơn ko ạ, em chỉ cần code mới bao gồm đọc và nhận giá trị từ MPU6050 và hiển thị 6 giá trị này lên LCD. em đang tim hiểu về I2c nên chưa biết nhiều, mong anh thông cảm.
      Mà hình như code mới này anh chưa include file LCD.h

      Delete
    4. Uh code mình gởi dữ liệu lên UART thôi

      Delete
  6. This comment has been removed by the author.

    ReplyDelete
    Replies
    1. Góc lệch thì có thể tính được nhưng nếu dùng chip ko hỗ trợ nhân 32bit thì rất lâu vì nó dùng đến argtan.Ví dụ tính góc nghiêng trục Ox =argtan(AccelX/AccelZ)

      Delete
    2. chào bạn, bạn có thể share code phần tính toán góc nghiêng để mình tham khảo được không , thanks bạn !!

      Delete
    3. ACCEL_XANGLE =(int)( 57.296 * (float)atan((float)ACCEL_YOUT/(float)ACCEL_ZOUT));
      ACCEL_YANGLE = 57.296*atan((float)- ACCEL_XOUT/ sqrt(pow((float)ACCEL_ZOUT,2)+pow((float)ACCEL_YOUT,2)));
      Nhưng mình nói luôn là tính kiểu này trình dịch nó báo full bộ nhớ ngay đấy,ít nhất thì cậu phải viết lại hàm atan giản lược đi để giảm code,chứ hàm atan có sẵn trong C nặng lắm

      Delete
  7. Cảm ơn cậu, à cho mình hỏi ngu cái nữa là gyro đọc về vận tốc góc, nhưng theo code của cậu, khi mình để yên thì nó vẫn có giá trị. mình chưa hiểu chỗ đó

    ReplyDelete
    Replies
    1. Vì cảm biến nào thì cũng bị tình trạng sai lệch tĩnh và lại cảm biến còn bị nhiễu nữa nên thường nó sẽ giao động quanh 1 khoảng giá trị nào đấy.Để giải quyết việc này thì ít nhất là phải hiệu chỉnh lại thông số của cảm biến(Người ta gọi là chỉnh không đấy,tức là chỉnh giá trị khi cảm biến đứng yên.Nhưng mà để chạy dc ổn thì bạn nên tìm hiểu thêm về các bộ lọc Kalman hay Ahrs.Cái này thì mình vẫn chưa làm được

      Delete
  8. ok, thanks bạn rất nhiều :)

    ReplyDelete
  9. bạn ơi cho mình hỏi là sao làm sao để xem được giá trị của x y z vậy? mình chạy chương trình trên ccs nhưng không thấy kết quả ở đâu?

    ReplyDelete
    Replies
    1. Mình gởi kết quả qua UART,bạn có thể xem bằng phần mềm sau :http://thuanbk55.blogspot.com/2014/04/phan-mem-ho-tro-giao-tiep-uart.html

      Delete
    2. bạn ơi mình vẫn chạy phần mềm kia rồi làm theo hướng dẫn nhưng lúc open xong chỉ thấy có thông báo Serial port COM5 opened, không thấy giá trị nào nữa. SCL mình nối p1.6, SDA nối p1.7, jump p1.6 nối với led thông báo mình rút ra, jump Rx Tx cắm như bạn hướng dẫn. mình không biết là mình còn sai ở chỗ nào nữa mà nó ko hiển thị đc kết quả. :(

      Delete
    3. Mình đoán hoặc là cổng UART trên máy bạn bị treo hoặc cảm biến treo,mình chạy bị như thế thì thường ngắt hết nguồn chạy lại từ đầu thì được,hoặc bạn chọn sai cổng COM,có nhiều nguyên nhân lắm,bạn phải chạy debug để biết msp bị treo ở chỗ nào,nếu không đọc được cảm biến thì nó sẽ treo ở hàm đọc I2C

      Delete
  10. Với module này thì làm sao tính ra vận tốc vậy?

    ReplyDelete
  11. Bạn phải lọc được tín hiệu đã,sau đó có thể dùng tích phân để tính vận tốc dài từ vector gia tốc trọng trường

    ReplyDelete
  12. Mình hỏi chút, mình đọc dữ liệu góc từ FIFO, mà mình chưa hiểu lắm tốc độ phát dữ liệu từ các bộ phát góc bằng nào, vì có vẻ như tốc độ lấy dữ liệu từ FIFO vào thiết bị của mình chậm hơn nên xảy ra chuyện FIFO bị tràn. Giúp mình với

    ReplyDelete
    Replies
    1. Chế độ FIFO thì mình chưa thử bạn ạ :3 ,nhưng mình có tham khảo trước đâu thì FIFO chủ yếu được dùng khi dùng MPU6050 làm master,tức là dùng nó để điều khiển vài cảm biến khác như cảm biến từ trường chẳng hạn :3

      Delete
    2. Vấn đề của mình thì mình dùng chương trình sử dụng cho Arduino, nhưng mình lại không dùng kit Arduino ma mình dùng Rasp berry Pi để đọc dữ liệu, vì thế nên gặp vấn đề như vậy.

      Delete
  13. This comment has been removed by the author.

    ReplyDelete
    Replies
    1. Accel nó cũng như 1 con lắc ý,nó bị tác động của gia tốc dài nữa em ạ,vì thế mà từ gyro có thể tính được gia tốc dài.Khi quay đột ngột thì gia tốc sẽ ảnh hưởng đến accel làm sai giá trị đi

      Delete
    2. vậy là có cách nào khắc phục được không anh, vì khi em đưa vào kalman, hay complementary thì giá trị accel bàn đầu quyết định lớn hơn :(

      Delete
    3. Anh chưa làm nhưng mà anh tìm hiểu trước đây thì phải kết hợp cả gyro và accel,cho vào mấy bộ Kalman hay AHRS gì đấy mới triệt được.Bản thân gyro không bị ảnh hưởng của gia tốc dài mà chỉ ảnh hưởng bởi gia tốc góc

      Delete
  14. anh ơi ,làm sao tính thời gian lấy mẫu vậy ạ.với lại mấy bộ lọc ban đầu G,gyro,accel là gì vậy ạ

    ReplyDelete
  15. cho mình hỏi có phần kết nối msp430g2553 giao tiếp i2c hiển thị lcd không ạ , em xin tham khảo với ạ. em là newbie

    ReplyDelete

END COMMENT FACEBOOK-->