You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用MicroPython实现RPI PICO与MPU6050通信失败求助

Raspberry Pi Pico与MPU6050 I2C通信OSError: [Errno 5] EIO问题解决

问题背景

使用MicroPython驱动Raspberry Pi Pico与MPU6050进行I2C通信时,Thonny IDE抛出OSError: [Errno 5] EIO错误,更换Pico开发板和MPU6050模块后问题依旧。

原代码

import machine
import utime

MPU6050_ADDR = 0x68  # MPU6050 I2C address

def read_i2c_word(i2c, address):
    # Read a 16-bit word from the specified I2C address
    return (i2c.readfrom_mem(address, 0x3B, 2)[0] << 8) | i2c.readfrom_mem(address, 0x3C, 2)[1]

def read_accel_gyro(i2c):
    # Read accelerometer and gyroscope data
    accel_x = read_i2c_word(i2c, MPU6050_ADDR)
    accel_y = read_i2c_word(i2c, MPU6050_ADDR + 2)
    accel_z = read_i2c_word(i2c, MPU6050_ADDR + 4)

    gyro_x = read_i2c_word(i2c, MPU6050_ADDR + 8)
    gyro_y = read_i2c_word(i2c, MPU6050_ADDR + 10)
    gyro_z = read_i2c_word(i2c, MPU6050_ADDR + 12)

    return (accel_x, accel_y, accel_z, gyro_x, gyro_y, gyro_z)

def main():
    i2c = machine.I2C(0, sda=machine.Pin(0), scl=machine.Pin(1), freq=400000)  # I2C bus on Pico

    while True:
        accel_data = read_accel_gyro(i2c)
        print("Accelerometer (X, Y, Z):", accel_data[:3])
        print("Gyroscope (X, Y, Z):", accel_data[3:])
        print("")

        utime.sleep(1)  # Sleep for 1 second

if __name__ == "__main__":
    main()

报错信息

Traceback (most recent call last): 
File "<stdin>", line 34, in <module>
File "<stdin>", line 26, in main
File "<stdin>", line 13, in read_accel_gyro
File "<stdin>", line 8, in read_i2c_word OSError: [Errno 5] EIO

错误原因分析

  1. I2C设备地址误用:read_accel_gyro中给MPU6050_ADDR加偏移(如MPU6050_ADDR + 2)完全错误,I2C设备地址是固定的0x68,需要偏移的是寄存器地址,而非设备地址。
  2. 寄存器读取逻辑错误:read_i2c_word中重复读取相邻寄存器且长度错误,MPU6050的16位数据存储在连续的两个寄存器(高字节+低字节),应一次读取2字节,而非分两次读取。
  3. 未唤醒MPU6050:MPU6050默认处于休眠状态,必须先写入PWR_MGMT_1寄存器(0x6B)唤醒设备,否则无法正常通信。

修复方案

步骤1:修正数据读取逻辑

重新实现read_i2c_word函数,从指定设备的目标寄存器读取完整的16位数据。

步骤2:唤醒MPU6050

添加初始化函数,向PWR_MGMT_1寄存器写入0x00唤醒设备。

步骤3:添加I2C设备扫描(可选但推荐)

扫描I2C总线确认MPU6050设备存在,排除硬件连接问题。

完整修复代码

import machine
import utime

MPU6050_ADDR = 0x68  # MPU6050 I2C设备地址
# 寄存器地址定义
ACCEL_XOUT_H = 0x3B
ACCEL_YOUT_H = 0x3D
ACCEL_ZOUT_H = 0x3F
GYRO_XOUT_H = 0x43
GYRO_YOUT_H = 0x45
GYRO_ZOUT_H = 0x47
PWR_MGMT_1 = 0x6B

def read_i2c_word(i2c, dev_addr, reg_addr):
    # 从指定设备的指定寄存器读取16位数据
    data = i2c.readfrom_mem(dev_addr, reg_addr, 2)
    return (data[0] << 8) | data[1]

def init_mpu6050(i2c):
    # 唤醒MPU6050(默认休眠状态)
    i2c.writeto_mem(MPU6050_ADDR, PWR_MGMT_1, b'\x00')
    utime.sleep_ms(100)  # 等待初始化完成

def read_accel_gyro(i2c):
    # 读取加速度计和陀螺仪数据
    accel_x = read_i2c_word(i2c, MPU6050_ADDR, ACCEL_XOUT_H)
    accel_y = read_i2c_word(i2c, MPU6050_ADDR, ACCEL_YOUT_H)
    accel_z = read_i2c_word(i2c, MPU6050_ADDR, ACCEL_ZOUT_H)

    gyro_x = read_i2c_word(i2c, MPU6050_ADDR, GYRO_XOUT_H)
    gyro_y = read_i2c_word(i2c, MPU6050_ADDR, GYRO_YOUT_H)
    gyro_z = read_i2c_word(i2c, MPU6050_ADDR, GYRO_ZOUT_H)

    # 转换为16位有符号数值
    def twos_complement(val):
        return val - 0x10000 if val >= 0x8000 else val

    return (
        twos_complement(accel_x), twos_complement(accel_y), twos_complement(accel_z),
        twos_complement(gyro_x), twos_complement(gyro_y), twos_complement(gyro_z)
    )

def main():
    # 初始化I2C总线
    i2c = machine.I2C(0, sda=machine.Pin(0), scl=machine.Pin(1), freq=400000)
    
    # 扫描I2C设备,确认MPU6050连接正常
    devices = i2c.scan()
    if MPU6050_ADDR not in devices:
        print(f"未找到MPU6050,扫描到的I2C设备:{[hex(d) for d in devices]}")
        return
    
    # 初始化MPU6050
    init_mpu6050(i2c)
    
    while True:
        accel_data = read_accel_gyro(i2c)
        print("加速度计(X, Y, Z):", accel_data[:3])
        print("陀螺仪(X, Y, Z):", accel_data[3:])
        print("")
        utime.sleep(1)

if __name__ == "__main__":
    main()

额外硬件检查点

  • 供电与接地:MPU6050需接3.3V供电,不可接5V;确保Pico与MPU6050共地。
  • 上拉电阻:若MPU6050模块无自带上拉电阻,需在SDA、SCL线路各接一个4.7kΩ电阻到3.3V。
  • I2C速率:若仍有通信问题,可将I2C频率降至100000(标准速率)尝试。

内容的提问来源于stack exchange,提问作者Abhijith Ravindran

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 02:44:55