Đăng vào

Giao tiếp I2C đọc tín hiệu MPU6050 dùng PIC CCS-C

Giới thiệu về MPU6050.

MPU-6050 là cảm biến của hãng InvenSense. MPU-6050 là một trong những giải pháp cảm biến chuyển động đầu tiên trên thế giới có tới 6 (mở rộng tới 9) trục cảm biến tích hợp trong 1 chip duy nhất. MPU-6050 sử dụng công nghệ độc quyền MotionFusion của InvenSense có thể chạy trên các thiết bị di động, tay điều khiển... MPU-6050 tích hợp 6 trục cảm biến bao gồm: + con quay hồi chuyển 3 trục (3-axis MEMS gyroscope) + cảm biến gia tốc 3 chiều (3-axis MEMS accelerometer)

MPU 6050

Ngoài ra, MPU-6050 còn có 1 đơn vị tăng tốc phần cứng chuyên xử lý tín hiệu (Digital Motion Processor - DSP) do cảm biến thu thập và thực hiện các tính toán cần thiết. Điều này giúp giảm bớt đáng kể phần xử lý tính toán của vi điều khiển, cải thiện tốc độ xử lý và cho ra phản hồi nhanh hơn. Đây chính là 1 điểm khác biệt đáng kể của MPU-6050 so với các cảm biến gia tốc và gyro khác. MPU-6050 có thể kết hợp với cảm biến từ trường (bên ngoài) để tạo thành bộ cảm biến 9 góc đầy đủ thông qua giao tiếp I2C. Các cảm biến bên trong MPU-6050 sử dụng bộ chuyển đổi tương tự - số (Anolog to Digital Converter - ADC) 16-bit cho ra kết quả chi tiết về góc quay, tọa độ... Với 16-bit bạn sẽ có 2^16 = 65536 giá trị cho 1 cảm biến. Tùy thuộc vào yêu cầu của bạn, cảm biến MPU-6050 có thể hoạt động ở chế độ tốc độ xử lý cao hoặc chế độ đo góc quay chính xác (chậm hơn). MPU-6050 có khả năng đo ở phạm vi: + con quay hồi chuyển: ± 250 500 1000 2000 dps + gia tốc: ± 2 ± 4 ± 8 ± 16g Hơn nữa, MPU-6050 có sẵn bộ đệm dữ liệu 1024 byte cho phép vi điều khiển phát lệnh cho cảm biến, và nhận về dữ liệu sau khi MPU-6050 tính toán xong.

Các lấy dữ liệu từ cảm biến.

MPU6050 chỉ hỗ trợ chuẩn giao tiếp I2C để xuất giá trị đo sang thiết bị khác (Master) hoặc chính nó lại là nơi xử lý, lưu trữ tín hiệu từ các thiết bị khác kết nối vào. Đầu tiên ta cần nắm được Protocol của chuẩn I2C

I2C Protocol

Slaver Address của MPU6050 mặc định là 0x68 = 0b1101000 Quá trình truyền hoặc nhận dữ liệu được bắt đầu khi có tín hiệu "Start" và kết thúc bởi tín hiệu "Stop", trong CCS-C đã có sắn hàm khởi tạo điều kiện Start và Stop:

i2c_start();

i2c_stop();

Một khi đã có điều kiện "start" thì Master phải truyền địa chỉ của thanh ghi cần tác động và hành động tương ứng(read/write ) Đối với MPU6050 quy luật truyền do nhà sản xuất đưa ra: Quá trình đưa dữ liệu từ vi điều khiển xuống cảm biến (chính là việc cài đặt cấu hình cho cảm biến) Write:

I2C Write

Đoạn code truyền 1 byte xuống MPU6050

// Ham viet truyen 1 byte xuong MPU6050
void Write2Mpu6050(unsigned int8 RegAddr,unsigned int8 data)
{
   i2c_start();    // Start condition
   i2c_write(MPU6050_ADDRESS_WRITE);// Device address write:
                                    //MPU6050_ADDRESS_WRITE = 0b11010000
   i2c_write(RegAddr);// Regiter address
   i2c_write(data);// data send
   i2c_stop();     // Stop condition
}

Trong đó thì: Masterchính là vi điều khiển của bạn. Slaver chính là cảm biến MPU6050. Quá trình nhận dữ liệu (chính là việc đọc dữ liệu từ cảm biến) Read:

I2C Read

Đoạn code đọc 1 byte từ 1 thanh ghi có địa chỉ Regadd

// Ham doc 1 byte tu 1 thanh ghi cua MPU6050
unsigned int8 ReadMpu6050(unsigned int8 RegAddr)
{
   unsigned int8 value;
   i2c_start();
   i2c_write(MPU6050_ADDRESS_WRITE);
   i2c_write(RegAddr);
   i2c_start();
   i2c_write(MPU6050_ADDRESS_READ);// Device address read
   value = i2c_read(0);
   //i2c_read(0);
   i2c_stop();
   return value;
}
I2C Table

Lấy giá trị vận tốc góc và gia tốc từ cảm biến

Giá trị vận tốc góc và gia tốc là số nguyên có dấu, mỗi giá trị được lưu trữ trong 2 thanh ghi:

ωx;;;LSB//s;;;{\omega }_{x};;; LSB/^{\circ}/s ;;; : GYROXOUT_H | GYRO_XOUT_L ωy;;;LSB//s;;;{\omega }*{y};;; LSB/^{\circ}/s ;;; : GYROYOUT_H | GYRO_YOUT_L ωz;;;LSB//s;;;{\omega }*{z};;; LSB/^{\circ}/s ;;; : GYROZOUT_H | GYRO_ZOUT_L gx;;;LSB/g;;;{g}*{x};;; LSB/g ;;; : ACCELXOUT_H | ACCEL_XOUT_L gy;;;LSB/g;;;{g}*{y};;; LSB/g ;;; : ACCEL*YOUT_H | ACCEL_YOUT_L gz;;;LSB/g;;;{g}*{z};;; LSB/g ;;; : ACCEL_ZOUT_H | ACCEL_ZOUT_L

Sau đây là hàm lấy giá trị 16 bit có dấu

signed int16 GetdataMpu6050(unsigned int8 RegAddr)
{
 unsigned int8 LSB;
 unsigned int8 MSB;
 MSB=ReadMpu6050(RegAddr);
 LSB=ReadMpu6050(RegAddr+1);
 return (make16(MSB,LSB));
 }

Cài đặt các giá trị ban đầu cho cảm biến

// Ham khoi tao gia tri ban dau cho Mpu6050
void InitMpu6050()
{
   Write2Mpu6050(MPU6050_RA_PWR_MGMT_1, 0x80);
   Write2Mpu6050(MPU6050_RA_PWR_MGMT_1, 0x08); // internal 8MHz, disabled SLEEP mode, disable CYCLE mode
   //Sets sample rate to 8000/(1+7) = 1000Hz
   Write2Mpu6050(MPU6050_RA_SMPLRT_DIV, 0x07);
   //Disable FSync, 256Hz DLPF
   Write2Mpu6050(MPU6050_RA_CONFIG, 0x06); //DLPF disable 0x06
   //Disable sensor output to FIFO buffer
   Write2Mpu6050(MPU6050_RA_FIFO_EN, 0x00);
   Write2Mpu6050(MPU6050_RA_GYRO_CONFIG, 0x00); //full scale range mode 0 +-250do/s
   Write2Mpu6050(MPU6050_RA_ACCEL_CONFIG, 0x00); //full scale range mode 0 +-2g
}

Từ các code cơ bản trên, chúng ta sẽ viết cho riêng mình 1 cái thư viện CCS của MPU6050 đặt tên là functionmpu6050.c và sẽ include nó vào code main, file mpu6050.h download tại đây

Demo một chương trình

#include <16f887.h>
#include #include #fuses hs, nowdt, noprotect, nolvp, put, brownout
#use delay(clock=20000000)
#use rs232(stream=com1,baud=19200,parity=N,xmit=PIN_C6, rcv=PIN_C7,bits=8)
#use i2c(MASTER,SCL=PIN_C3,SDA=PIN_C4)
#include // phan rs232 dung de sau nay minh truyen len may tinh ve do thi goc quay
void main()
{
   float32 Xangle_acc;
   signed int16 y_accel,z_accel;
   char value[20];
   InitMpu6050();// Khoi tao dieu kien ban dau
   while(TRUE)
   {
      y_accel = GetdataMpu6050(MPU6050_RA_ACCEL_YOUT_H)-MPU6050_OFFSET_ACCEL_Y;
      z_accel = GetdataMpu6050(MPU6050_RA_ACCEL_ZOUT_H)-MPU6050_OFFSET_ACCEL_Z;
    //Minh tinh goc lech theo truc X bang gia tri gia toc
    //Chua co loc nhieu gi het
      Xangle_acc=atan2(y_accel,z_accel)* 57.296;// goc lech
      sprintf(value,"%5.2fa31y78zrn",Xangle_acc);
      fprintf(com1,value);// Truyen du lieu len PC
   }
}// EOF