ماژول شتاب سنج و ژیروسکوپ MPU-6050 می تواند شتاب خطی را در سه محور و شتاب زاویه ای را نیز در سه محور اندازه گیری کند. قصد داریم این مقادیر را به کمک برد میکروکنترلری رزبری پای پیکو و مایکروپایتون بخوانیم و نمایش دهیم.

این ماژول برای ارتباط با میکروکنترلر از I2C استفاده می کند. برای تغذیه مدار می توانیم طبق شکل پایه VCC را به خروجی 3.3 ولت رزبری پای پیکو متصل کنیم و GND را هم به یکی از پایه های زمین پیکو متصل نماییم. همان طور که می بینید از کانال I2C شماره 0 پیکو و از پایه های GPIO0 و GPIO1 نیز برای اتصال I2C استفاده کرده ایم.

mpu6050
mpu6050 – raspberry pi pico

برنامه به این صورت و بدون استفاده از ماژول ها و کتابخانه های آماده نوشته شده است:

from machine import Pin, I2C
import time

# MPU6050 registers
MPU6050_ADDR = 0x68
MPU6050_PWR_MGMT_1 = 0x6B
MPU6050_ACCEL_XOUT_H = 0x3B
MPU6050_GYRO_XOUT_H = 0x43

#Accelerometer's LSB/g (least significant bits per gravitational force) sensitivity
MPU6050_LSBG = 16384.0

#Gyroscope's LSB/g sensitivity
MPU6050_LSBDS = 131.0 

# Create an I2C object
i2c = I2C(0, scl=Pin(1), sda=Pin(0))

# Wake up the MPU-6050
i2c.writeto_mem(MPU6050_ADDR, MPU6050_PWR_MGMT_1, bytearray([0]))

while True:
    # Read acceleration data
    accel_x = i2c.readfrom_mem(MPU6050_ADDR, MPU6050_ACCEL_XOUT_H, 2)
    accel_y = i2c.readfrom_mem(MPU6050_ADDR, MPU6050_ACCEL_XOUT_H + 2, 2)
    accel_z = i2c.readfrom_mem(MPU6050_ADDR, MPU6050_ACCEL_XOUT_H + 4, 2)

    # Read gyroscope data
    gyro_x = i2c.readfrom_mem(MPU6050_ADDR, MPU6050_GYRO_XOUT_H, 2)
    gyro_y = i2c.readfrom_mem(MPU6050_ADDR, MPU6050_GYRO_XOUT_H + 2, 2)
    gyro_z = i2c.readfrom_mem(MPU6050_ADDR, MPU6050_GYRO_XOUT_H + 4, 2)

    # Combine high and low bytes
    accel_x = (accel_x[0] << 8) | accel_x[1]
    accel_y = (accel_y[0] << 8) | accel_y[1]
    accel_z = (accel_z[0] << 8) | accel_z[1]

    gyro_x = (gyro_x[0] << 8) | gyro_x[1]
    gyro_y = (gyro_y[0] << 8) | gyro_y[1]
    gyro_z = (gyro_z[0] << 8) | gyro_z[1]

    # Convert to signed values if necessary
    if accel_x > 32767:
        accel_x -= 65536
    if accel_y > 32767:
        accel_y -= 65536
    if accel_z > 32767:
        accel_z -= 65536

    if gyro_x > 32767:
        gyro_x -= 65536
    if gyro_y > 32767:
        gyro_y -= 65536
    if gyro_z > 32767:
        gyro_z -= 65536
        
    ax=accel_x/MPU6050_LSBG
    ay=accel_y/MPU6050_LSBG
    az=accel_z/MPU6050_LSBG
    gx=gyro_x/MPU6050_LSBDS
    gy=gyro_y/MPU6050_LSBDS
    gz=gyro_z/MPU6050_LSBDS
    
    print("Acceleration: X:{}, Y:{}, Z:{}".format(ax, ay, az))
    print("Gyroscope: X:{}, Y:{}, Z:{}".format(gx, gy, gz))

    # Wait for 1 second before the next reading
    time.sleep(1)

ابتدا با نوشتن در رجیستر PWR_MGMT_1 سنسور را بیدار می کنیم. سپس در یک حلقه داده های شتاب را از رجیسترهای ACCEL_XOUT_H، ACCEL_YOUT_H و ACCEL_ZOUT_H و داده های ژیروسکوپ از GYRO_XOUT_H، GYRO_YOUT_H، و GYRO_ZOUT_H می خوانیم. این مقادیر را هر ثانیه یک بار خوانده و نمایش می دهیم.

در برنامه باید در نظر بگیریم که داده های خام دارای علامت + و – نیستند و باید آنها را در صورت لزوم منفی کنیم.

سنسور MPU-6050 شتاب را بر حسب واحد گرانش (g) و داده های ژیروسکوپ را بر حسب درجه بر ثانیه (°/s) اندازه گیری می کند.

اما، داده های خوانده شده از رجیسترهای سنسور خام هستند و باید تبویل شوند. محدوده تمام مقیاس برای شتاب می تواند 2g±±4g, ±8g,  یا  ±16g باشد، و برای ژیروسکوپ، می تواند 250 ±، 500 ±، 1000 ± یا 2000 ± درجه بر ثانیه باشد.

برای تبدیل داده های خام به واحدهای واقعی (g and °/s)، باید ضریب مقیاس حساسیت را بدانیم. به عنوان مثال، اگر محدوده شتاب سنج در مقیاس کامل 2g± باشد ( که در حالت پیش فرض همین مقدار است)، ضریب مقیاس حساسیت 16384 LSB/g است. و اگر محدوده مقیاس کامل ژیروسکوپ 250±  درجه بر ثانیه باشد ( که در حالت پیش فرض همین مقدار است)، ضریب مقیاس حساسیت 131 LSB/(°/s1) است.

این برنامه داده های شتاب و ژیروسکوپ X، Y و Z را از سنسور MPU-6050 می خواند. داده ها به صورت دو بایت برای هر محور خوانده می شوند زیرا MPU-6050 داده های 16 بیتی را برای هر محور ارائه می دهد. سپس دو بایت برای هر خروجی  در برنامه ترکیب می شوند تا داده های شتاب 16 بیتی کامل آن خروجی را تشکیل دهند.