【ELF2学习开发板】Linux 命令行读取 MPU6050 传感器数据(I2C 总线)实战

目录

前言

环境准备

硬件信息

[安装 I2C 工具集](#安装 I2C 工具集)

确认传感器连接

[扫描 I2C 总线](#扫描 I2C 总线)

验证传感器通信

[Shell 脚本读取传感器数据](#Shell 脚本读取传感器数据)

完整脚本(readmpu.sh)

脚本执行步骤

输出结果示例

关键知识点说明

数据换算规则

[16 位有符号数转换](#16 位有符号数转换)

容错处理

总结


前言

MPU6050 是常用的六轴传感器(三轴加速度计 + 三轴陀螺仪),本文详细介绍如何在 Linux 系统下通过命令行(I2C 工具)读取 MPU6050 的原始数据,并换算为物理单位(g、°/s),全程基于纯 Shell 脚本实现,无需编译代码,适合嵌入式 Linux 开发调试。

环境准备

硬件信息

传感器:MPU6050(I2C 地址默认 0x68)

ELF 2 的 40Pin 2.54mm 连接器兼容树莓派 40Pin 连接器。包含了 I2C 、 SPI 、 UART 和若干 GPIO ,其原理图如下:

在40pin中,提供了I2C4和I2C7。

按如下对应关系连接 ELF 2 开发板与 MPU-6050 模块(如果使用的不是ELF 2,请查询原理图获得正确的连接关系):

|---------------------------|---------------------------|---------------------|--------------|
| ELF 2 开发板40pin 编号 | RK3588 引脚 | MPU-6050 引脚 | 功能说明 |
| 1 | 3.3V | VCC | 供电(禁止接 5V) |
| 6 | GND | GND | 共地 |
| 3 | I2C4_SDA | SDA | 数据信号线 |
| 5 | I2C4_SCL | SCL | 时钟信号线 |

I2C 总线:本文中传感器挂载在 I2C 总线 4。

系统:Linux(本文以 Ubuntu 为例)。

安装 I2C 工具集

MPU6050 通过 I2C 总线通信,需先安装i2c-tools工具(ELF2 自带这个工具,可以跳过此步骤):

bash 复制代码
apt update && apt install -y i2c-tools

确认传感器连接

扫描 I2C 总线

使用i2cdetect扫描总线 4,确认 MPU6050 的地址(默认 0x68):

bash 复制代码
i2cdetect -y 4

正常输出如下(0x68 位置显示设备):

bash 复制代码
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:                         -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- 68 -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --

验证传感器通信

MPU6050 的WHO_AM_I寄存器(0x75)默认值为 0x68,读取该寄存器验证通信:

bash 复制代码
i2cget -y 4 0x68 0x75

返回0x68表示传感器通信正常;若返回--,需检查硬件连接或总线配置。

Shell 脚本读取传感器数据

完整脚本(readmpu.sh

脚本功能:唤醒 MPU6050→读取加速度计 / 陀螺仪原始数据→转换为 16 位有符号数→换算为物理单位(g、°/s):

bash 复制代码
#!/bin/bash
# 读取MPU6050数据(I2C总线4,地址0x68)
# 功能:读取加速度计(±2g)和陀螺仪(±250°/s)数据,转换为物理单位

# 1. 唤醒传感器(MPU6050上电默认休眠,写入电源管理寄存器0x6B)
i2cset -y 4 0x68 0x6B 0x00 > /dev/null 2>&1

# 核心函数1:读取单个寄存器并转为十进制(处理读取失败场景)
read_mpu_reg() {
    local bus=$1
    local addr=$2
    local reg=$3
    # 读取寄存器,失败时返回0
    local val=$(i2cget -y $bus $addr $reg 2>/dev/null)
    if [[ $val != 0x* ]]; then
        echo 0
        return
    fi
    # 去掉0x前缀,转为十进制
    echo $((16#${val:2}))
}

# 核心函数2:拼接高低字节为16位有符号数(补码转换)
combine_16bit() {
    local high=$1
    local low=$2
    # 拼接为16位无符号数
    local unsigned=$(( (high << 8) | low ))
    # 转换为有符号补码(处理负数)
    if (( unsigned & 0x8000 )); then
        echo $(( unsigned - 0x10000 ))
    else
        echo $unsigned
    fi
}

# ========== 读取加速度计数据(±2g量程,分辨率16384 LSB/g) ==========
echo "加速度计数据:"
# 读取加速度计三轴高低字节(寄存器0x3B-0x40)
AX_H=$(read_mpu_reg 4 0x68 0x3C)
AX_L=$(read_mpu_reg 4 0x68 0x3B)
AY_H=$(read_mpu_reg 4 0x68 0x3E)
AY_L=$(read_mpu_reg 4 0x68 0x3D)
AZ_H=$(read_mpu_reg 4 0x68 0x40)
AZ_L=$(read_mpu_reg 4 0x68 0x3F)

# 拼接为16位有符号数
AX=$(combine_16bit $AX_H $AX_L)
AY=$(combine_16bit $AY_H $AY_L)
AZ=$(combine_16bit $AZ_H $AZ_L)

# 换算为物理单位(g)
AX_G=$(echo "scale=3; $AX/16384" | bc -l)
AY_G=$(echo "scale=3; $AY/16384" | bc -l)
AZ_G=$(echo "scale=3; $AZ/16384" | bc -l)

echo "X轴: $AX (≈ $AX_G g)"
echo "Y轴: $AY (≈ $AY_G g)"
echo "Z轴: $AZ (≈ $AZ_G g)"

# ========== 读取陀螺仪数据(±250°/s量程,分辨率131 LSB/(°/s)) ==========
echo -e "\n陀螺仪数据:"
# 读取陀螺仪三轴高低字节(寄存器0x43-0x48)
GX_H=$(read_mpu_reg 4 0x68 0x44)
GX_L=$(read_mpu_reg 4 0x68 0x43)
GY_H=$(read_mpu_reg 4 0x68 0x46)
GY_L=$(read_mpu_reg 4 0x68 0x45)
GZ_H=$(read_mpu_reg 4 0x68 0x48)
GZ_L=$(read_mpu_reg 4 0x68 0x47)

# 拼接为16位有符号数
GX=$(combine_16bit $GX_H $GX_L)
GY=$(combine_16bit $GY_H $GY_L)
GZ=$(combine_16bit $GZ_H $GZ_L)

# 换算为物理单位(°/s)
GX_DPS=$(echo "scale=3; $GX/131" | bc -l)
GY_DPS=$(echo "scale=3; $GY/131" | bc -l)
GZ_DPS=$(echo "scale=3; $GZ/131" | bc -l)

echo "X轴: $GX (≈ $GX_DPS °/s)"
echo "Y轴: $GY (≈ $GY_DPS °/s)"
echo "Z轴: $GZ (≈ $GZ_DPS °/s)"

脚本执行步骤

保存脚本并添加执行权限:

bash 复制代码
chmod +x readmpu.sh

运行脚本:

bash 复制代码
./readmpu.sh

输出结果示例

bash 复制代码
加速度计数据:
X轴: 2 (≈ 0.000 g)
Y轴: 13358 (≈ 0.815 g)
Z轴: 11481 (≈ 0.700 g)

陀螺仪数据:
X轴: 8445 (≈ 64.465 °/s)
Y轴: 23295 (≈ 177.824 °/s)
Z轴: 30463 (≈ 232.541 °/s)

关键知识点说明

数据换算规则

  • 加速度计 :默认量程 ±2g,分辨率16384 LSB/g(即 16384 个数字量对应 1g 加速度),公式:加速度(g) = 16位数值 / 16384
  • 陀螺仪 :默认量程 ±250°/s,分辨率131 LSB/(°/s),公式:角速度(°/s) = 16位数值 / 131

16 位有符号数转换

MPU6050 输出的是 16 位补码数据,脚本中combine_16bit函数实现:

  • 先拼接高低字节为无符号数;
  • 若最高位为 1(负数),则减去0x10000转换为有符号数。

容错处理

脚本中read_mpu_reg函数增加了异常处理:若i2cget读取失败(返回--或空),则返回 0,避免脚本报错中断。

总结

Linux 下通过i2c-tools可直接与 I2C 设备交互,无需编写驱动,适合快速调试。MPU6050 需先唤醒(写入 0x6B 寄存器)才能读取有效数据。传感器原始数据为 16 位补码,需转换为有符号数后再换算为物理单位,脚本已封装核心转换逻辑,可直接复用。

相关推荐
520拼好饭被践踏7 小时前
JAVA+Agent学习day22
java·开发语言·后端·学习
懿路向前7 小时前
【HarmonyOS学习笔记】2026-07-24 | textProcessing 实体识别与踩坑实录
笔记·学习·边缘计算·harmonyos
菩提树下的打坐7 小时前
性能测试进阶:从 JMeter 基线到 SLO 驱动的压测体系
学习·jmeter
Kina_C7 小时前
LVS-NAT 负载均衡实验从环境搭建到规则持久化
linux·运维·服务器·负载均衡·lvs
小肝一下8 小时前
7. 库制作与原理
linux·c语言·操作系统·bash·shell·动静态库
Albart5758 小时前
2026年Python入门路线图:从零到实战的30天逐日详解(三)
学习·flask·#python30 天入门·python 实战教程·pytest 单元测试·python 虚拟环境·logging 日志
Android洋芋8 小时前
PrintFriendly网页文章转PDF插件工具及技术分析
运维·服务器·pdf·网页转pdf
Elastic 中国社区官方博客8 小时前
使用重新设计的 AutoOps 更快地进行 Elasticsearch 问题排查
大数据·运维·前端·人工智能·elasticsearch·搜索引擎·全文检索
RoboWizard8 小时前
金士顿高速闪存盘 单双接口适配多元存储需求
大数据·运维·人工智能·智能手机·云计算
hkj88088 小时前
Ubuntu 20.04 安装 OpenJDK 17
linux·运维·ubuntu