零知派ESP32--MLX90393磁感手势屏
项目概述
该项目是一套基于 ESP32、三轴磁力计 MLX90393 与 ST7789(240×240)彩屏的磁场手势交互系统。系统开机后自动校准环境磁场,随后用小磁铁在传感器附近做左、右、上、下、靠近、远离等动作;屏幕提供三种界面:
| 模式 | 名称 | 作用 |
|---|---|---|
| 1 | DATA(数据) | 实时显示 X / Y / Z、|B|、dB 与当前手势 |
| 2 | COMPASS(指南针) | 星空表盘 + 粗指针,跟随平面磁场方向 |
| 3 | PARTICLE(粒子场) | 粒子随手势冲、飘、聚拢、扩散 |
通过按键在三种模式间循环切换,适合作为磁场传感、嵌入式可视化与交互演示项目。
项目亮点
- 六向手势识别:基于三轴相对变化量,识别 LEFT / RIGHT / UP / DOWN / NEAR / FAR。
- 三模式可视化:数据读数、指南针星图、粒子场,一套代码覆盖展示与互动。
- 开机自动校准:采样环境磁场作为基准,减弱地磁与固定偏置影响。
- 局部刷新优化:粒子与指南针尽量只擦旧画新,降低 SPI 屏全刷压力。
- 一键切模式:GPIO27 内部上拉按键,消抖 + 冷却,切换稳定。
- 可调方向映射:
FIELD_X_SIGN/FIELD_Y_SIGN可按模块安装方向纠正左右、上下。
项目难点及解决方案
| 难点 | 现象 | 解决方案 |
|---|---|---|
| 静置漂移 | 粒子默认向某一侧持续移动 | 粒子推力主要跟磁场帧间变化,静置时变化≈0;离散手势用一次性冲量并衰减 |
| 指南针残影 | 指针旋转留下旧线 | 擦除路径与绘制一致(垂直于针身偏移),并略加宽擦除范围 |
| 屏幕刷新慢 | 全屏重绘卡顿 | 数据模式低频刷新;粒子/指南针局部擦画;静态 UI 只在切模式时画一次 |
| 手势误触发 | 轻微抖动也出动作 | 阈值 + 主轴比例判断 + GESTURE_COOLDOWN 冷却 |
| 方向与实物相反 | 左右或上下反了 | 调整 FIELD_X_SIGN / FIELD_Y_SIGN,或交换手势分支中的 LEFT/RIGHT、UP/DOWN |
| I2C 地址不一 | 初始化失败 | 依次尝试 0x0C、0x18,并开机扫描 I2C |
目录
一、硬件系统部分
1.1 硬件清单
| 序号 | 名称 | 规格 / 说明 | 数量 |
|---|---|---|---|
| 1 | 主控板 | 零知ESP32 开发板 | 1 |
| 2 | 扩展板 | 零知ESP32 扩展板 | 1 |
| 3 | 磁力计 | MLX90393 三轴磁力计模块(I2C) | 1 |
| 4 | 彩屏 | ST7789,240×240,SPI | 1 |
| 5 | 磁铁 | 小钕磁铁或普通小磁铁(建议距离传感器约 5~15 cm) | 1 |
| 6 | 杜邦线 / 排线 | 端子对公头 | 1 |
| 7 | 供电 | USB 供电即可(注意屏幕与传感器统一 3.3V 逻辑) | 1 |
1.2 接线方案
MLX90393(I2C)
| 传感器引脚 | ESP32 GPIO |
|---|---|
| SDA | 21 |
| SCL | 22 |
| VCC | 3.3V |
| GND | GND |
I2C 时钟:100 kHz。常见从机地址:0x0C 或 0x18。
1.3 硬件连接图

1.4 实物连接图

二、软件架构设计
整体是典型的「传感器采样 + 手势状态机 + 分模式渲染」架构,单文件 MLX90393.ino 组织。
2.1 系统初始化(setup)
大致顺序:
- 串口
115200,短延时约 200ms - 配置 GPIO27 上拉输入
- 初始化 TFT,显示
SYSTEM START Wire.begin(21, 22),时钟 100kHzscanI2C()扫描总线initMLX90393()尝试地址0x0C/0x18- 失败则
showSensorError()并返回 - 成功则
calibrateMagneticField()(约 40 次 × 10ms) drawStaticUI()→ 默认进入 DATA 模式
2.2 主循环逻辑(loop)
每轮固定做三件事:
-
handleModeButton()
消抖 40ms,冷却 350ms,按下沿:DATA → COMPASS → PARTICLE → DATA -
定时读传感器(50ms)
readMagneticData()→ 计算deltaX/Y/Z、deltaMagnitude
→detectGesture()→updateIdleState()
→ 串口打印X Y Z dB Gesture -
定时刷屏
- DATA:约 150ms
- COMPASS / PARTICLE:约 40ms
→updateDisplay()分发到对应刷新函数
若传感器未就绪,每 3 秒重试初始化与校准。
三、代码拆分讲解
按功能块理解 MLX90393.ino:
3.1 配置与状态
- 引脚:
MLX_SDA_PIN、MLX_SCL_PIN、BUTTON_PIN - 周期:
SENSOR_INTERVAL、SCREEN_INTERVAL_*、GESTURE_COOLDOWN - 手势阈值:
X/Y_GESTURE_THRESHOLD、DISTANCE_THRESHOLD、DIRECTION_RATIO - 方向映射:
FIELD_X_SIGN、FIELD_Y_SIGN - 模式枚举:
MODE_DATA / MODE_COMPASS / MODE_PARTICLE - 磁场状态:
magnetic*、base*、delta*、currentGesture
3.2 数据模式
| 函数 | 作用 |
|---|---|
drawDataStaticUI() |
标题、五行标签、底部提示(静态) |
updateDataDisplay() |
刷新数值区与手势文字(局部清字) |
显示项:X Y Z |B| dB,底部为当前手势。
3.3 指南针模式
| 函数 | 作用 |
|---|---|
initCompassSky() |
生成星点、画表盘与初始针 |
updateCompassDisplay() |
由平滑后的 ΔX/ΔY 算角度,擦旧针再画新针 |
eraseCompassNeedle() / drawCompassNeedle() |
加粗针 + 同几何擦除,减残影 |
drawCompassRing() / drawCompassStars() |
表盘刻度与星空背景 |
3.4 粒子模式
| 函数 | 作用 |
|---|---|
initParticleField() |
初始化约 72 个粒子与标题栏 |
updateParticlePhysics() |
帧间磁场变化 + 手势冲量 → 速度积分 |
updateParticleDisplay() |
擦旧粒子、画新粒子、更新底部手势 HUD |
交互效果对应关系:
| 动作 | 粒子效果 |
|---|---|
| 左 / 右 | 水平冲 |
| 上 / 下 | 竖直冲 |
| 斜向移动 | 连续跟随 XY,可斜飘 |
| 靠近 / 远离 | 聚拢 / 扩散 |
3.5 模式调度
| 函数 | 作用 |
|---|---|
handleModeButton() |
按键消抖与切模式 |
applyDisplayMode() |
切模式时重建对应界面 |
updateDisplay() |
按 displayMode 调用刷新函数 |
四、操作过程及数据展示
4.1 操作步骤
-
接线
按 1.2 节接好屏幕、MLX90393、按键,确认共地、供电为 3.3V。 -
烧录
打开MLX90393.ino,选择 零知ESP32 后上传。 -
开机校准
上电后屏幕短暂显示SYSTEM START。
此时请将磁铁远离传感器,等待校准结束进入 DATA 界面。 -
体验三种模式
- DATA:磁铁靠近/平移,观察数值与手势文字变化
- 按一下 GPIO27 → COMPASS:指针跟随平面磁场方向,底部有强度条
- 再按 → PARTICLE:做六向动作,观察粒子冲、飘、聚散;静置应基本停住
- 再按回到 DATA
4.2 演示视频
零知派ESP32--MLX90393磁感手势屏
五、技术原理
5.1 工作原理
-
相对磁场
开机校准得到环境基准(baseX, baseY, baseZ)。
运行时:delta = 当前值 - 基准。手势看的是变化,而不是绝对地磁。 -
方向手势
磁铁在某一侧移动时,对应轴变化往往最大。用「主轴过阈值 + 明显大于另两轴」区分左右与上下,减少斜向混淆。 -
距离手势
靠近时 |B| 通常升高 →deltaMagnitude为正大 → NEAR;远离则相反 → FAR。 -
粒子驱动
- 连续跟手:平滑后的帧间变化驱动 XY 推力
- 离散手势:装载一次冲量并逐帧衰减,避免手势文字保持期间一直推粒子
- 静置:变化不足死区则速度清零
-
指南针
用平面分量(FIELD_X_SIGN·ΔX, FIELD_Y_SIGN·ΔY)求atan2得针角,EMA 平滑后局部重绘指针。 -
显示调度
传感器 50ms 一采;UI 按模式不同周期刷新,避免 SPI 带宽被无效全刷占满。
5.2 工作模式配置
| 配置项 | 默认值 | 说明 |
|---|---|---|
SENSOR_INTERVAL |
50 ms | 磁场采样周期 |
SCREEN_INTERVAL_DATA |
150 ms | 数据屏刷新 |
SCREEN_INTERVAL_PARTICLE / GAME |
40 ms | 粒子 / 指南针刷新 |
GESTURE_COOLDOWN |
700 ms | 手势识别冷却 |
CALIBRATION_SAMPLES |
40 | 校准采样次数 |
CALIBRATION_DELAY |
10 ms | 校准采样间隔 |
X/Y_GESTURE_THRESHOLD |
180 | 左右 / 上下阈值 |
DISTANCE_THRESHOLD |
250 | 靠近远离阈值 |
DIRECTION_RATIO |
1.25 | 主轴相对另轴倍率 |
FIELD_X_SIGN |
见代码 | 左右方向映射 |
FIELD_Y_SIGN |
见代码 | 上下方向映射 |
PARTICLE_COUNT |
72 | 粒子数量 |
| 默认模式 | MODE_DATA |
开机进入数据模式 |
| 切换顺序 | DATA → COMPASS → PARTICLE | GPIO27 循环 |
屏幕旋转:tft.setRotation(3),若画面方向不符可改为 0~3 试一下。
六、常见问题指引
Q1:左右或上下反了
- 修改
FIELD_X_SIGN/FIELD_Y_SIGN(1与-1互换) - 或按代码注释交换 LEFT/RIGHT、UP/DOWN 分支
Q2:指南针有残影
- 确认擦针与画针使用同一垂直偏移几何
- 仍有残点时可略加大擦除宽度或针尖清除半径
Q3:开机很慢
- 当前已缩短启动延时与校准时间;若仍慢,可再略减
CALIBRATION_SAMPLES(过少会影响基准稳定性)
更多推荐


所有评论(0)