一、硬件介绍
Tab5 集成了双芯片架构和丰富的硬件资源,其主控采用基于 RISC‑V 架构的 ESP32‑P4 SoC,并配备 16MB Flash 与 32MB PSRAM,无线模块则选用 ESP32-C6-MINI-1U,支持 Wi-Fi 6;
还配备5英寸(1280×720 IPS)触控屏幕,以及2MP摄像头(1600×1200)、双麦克风阵列,3.5mm耳机孔与扬声器;
内置BMI270六轴传感器、实时时钟,板载HY2.0-4P,M5-Bus,GPIO_EXT排母和microSD卡槽等;
底部兼容NP‑F550可拆卸锂电池(具备充放电与实时监测电路);


系统框图


二、功能实现
1、硬件介绍
BMI270 六轴姿态传感器
BMI270 是一款超低功耗惯性测量单元(IMU),集成了加速度计和陀螺仪的小型传感器芯片;
BMI270 是一个 6轴传感器,包含:
3轴加速度计: 测量物体在X、Y、Z三个方向上的加速度,用于检测运动、倾斜和震动;
3轴陀螺仪: 测量物体围绕X、Y、Z三个轴旋转的角速度,用于检测旋转和姿态变化;
支持中断唤醒
特性

硬件引脚连接

原理图


2、功能效果
在LCD屏幕上显示BMI270传感器获取到的相关数值(加速度计 / 陀螺仪),并根据当前IMU的方向,屏幕显示方向进行自动旋转,当静止一段时间(5s)后关闭屏幕(睡眠模式),当再次检测到有运动时,屏幕才重新点亮;
静止休眠 / 运动唤醒:当静止一段时间后关闭屏幕,当再次检测到有运动时,屏幕重新点亮;
自动旋转:根据设备的握持方向(横屏、竖屏、倒立),自动调整屏幕内容的显示方向;
Accel (加速度计): 测量受力;
Gyro (陀螺仪): 测量旋转角速度;
三、代码编写
读取加速度计的 X 和 Y 轴分量:
x > 0.7 或 x < -0.7:判断左右倾斜;
y > 0.7 或 y < -0.7:判断上下倾斜;
#include <M5Unified.h>
// 创建画布
M5Canvas canvas(&M5.Display);
m5::imu_data_t imuData;
// 记录当前的旋转方向
int currentRotation = -1;
// 休眠功能相关变量
float lastAccX = 0, lastAccY = 0, lastAccZ = 0; // 上一次的加速度值
unsigned long lastActivityTime = 0; // 最后一次检测到运动的时间
bool isScreenOn = true; // 当前屏幕状态
// 参数设置
const float MOVEMENT_THRESHOLD = 0.15; // 灵敏度:0.15g (自定义)
const unsigned long SLEEP_TIMEOUT_MS = 5000; // 超时时间:5秒 (自定义)
void setup() {
M5.begin();
// 初始时 默认方向
M5.Display.setRotation(1);
currentRotation = 1;
// 初始化画布
canvas.createSprite(M5.Display.width(), M5.Display.height());
// 设置字体和对齐方式
canvas.setFont(&fonts::FreeMonoBold24pt7b);
canvas.setTextDatum(middle_center);
canvas.setTextColor(WHITE);
lastActivityTime = millis();
}
// 自动旋转函数
void autoRotate() {
float x = imuData.accel.x;
float y = imuData.accel.y;
int newRotation = currentRotation;
if (x > 0.7) newRotation = 3;
else if (x < -0.7) newRotation = 1;
else if (y > 0.7) newRotation = 0;
else if (y < -0.7) newRotation = 2;
// 重新绘制文本
if (newRotation != currentRotation) {
M5.Display.setRotation(newRotation);
currentRotation = newRotation;
canvas.deleteSprite();
canvas.createSprite(M5.Display.width(), M5.Display.height());
canvas.setFont(&fonts::FreeMonoBold24pt7b);
canvas.setTextDatum(middle_center);
canvas.setTextColor(WHITE);
}
}
// 屏幕休眠函数
void checkSleep() {
// 计算三个轴的变化量
float deltaX = abs(imuData.accel.x - lastAccX);
float deltaY = abs(imuData.accel.y - lastAccY);
float deltaZ = abs(imuData.accel.z - lastAccZ);
// 计算总变化量
float totalChange = deltaX + deltaY + deltaZ;
// 判断是否在动
if (totalChange > MOVEMENT_THRESHOLD) {
lastActivityTime = millis(); // 刷新计时器
// 屏幕状态
if (!isScreenOn) {
M5.Display.wakeup(); // 唤醒屏幕
M5.Display.setBrightness(128); // 恢复亮度 (自定义)
isScreenOn = true;
}
lastAccX = imuData.accel.x;
lastAccY = imuData.accel.y;
lastAccZ = imuData.accel.z;
} else {
if (isScreenOn && (millis() - lastActivityTime > SLEEP_TIMEOUT_MS)) {
M5.Display.sleep(); // 熄灭屏幕
isScreenOn = false;
}
}
}
void loop() {
M5.Imu.update();
imuData = M5.Imu.getImuData(); //获取IMU数值
// 唤醒检测
checkSleep();
// 屏幕亮时,才绘制
if (isScreenOn) {
// 检查旋转
autoRotate();
//屏幕显示 IMU数值
canvas.fillSprite(BLUE);
int midX = canvas.width() / 2;
int midY = canvas.height() / 2;
int lh = 50;
int startY = midY - (lh * 3);
char buf[32];
sprintf(buf, "Acc X: %7.2f", imuData.accel.x);
canvas.drawString(buf, midX, startY);
sprintf(buf, "Acc Y: %7.2f", imuData.accel.y);
canvas.drawString(buf, midX, startY + lh);
sprintf(buf, "Acc Z: %7.2f", imuData.accel.z);
canvas.drawString(buf, midX, startY + lh * 2);
sprintf(buf, "Gyr X: %7.2f", imuData.gyro.x);
canvas.drawString(buf, midX, startY + lh * 4);
sprintf(buf, "Gyr Y: %7.2f", imuData.gyro.y);
canvas.drawString(buf, midX, startY + lh * 5);
sprintf(buf, "Gyr Z: %7.2f", imuData.gyro.z);
canvas.drawString(buf, midX, startY + lh * 6);
canvas.pushSprite(0, 0);
}
delay(100);
}四、程序烧录
1、连接USB数据线至开发板;
2、选择端口号对应的开发板;
3、点击 上传 烧录程序到开发板上;


五、效果演示

我要赚赏金
