一、所选任务介绍
本次项目选择完成的任务为:基于 ADMT4000 模块实现里程计功能,将旋转圈数换算为行驶距离,并在断电重启后保持累计里程不丢失。
该任务的核心要求包括以下几个方面:首先,需要通过 SPI 接口读取 ADMT4000 的多圈绝对角度信息;其次,需要预先设定一个虚拟轮子的周长,并将旋转圈数和角度变化换算为实际行驶距离;再次,需要保证断电后重新上电时,系统能够恢复断电前的里程状态,而不是从零开始;最后,需要在 ADMT4000 的 46 圈有效工作范围内完成功能验证。
我之所以选择该任务,主要基于以下几点考虑。第一,该任务较入门题更进一步,不仅要求完成传感器数据读取,还要求完成一个有明确应用意义的数据映射过程,即“角度到距离”的转换。第二,ADMT4000 具备多圈绝对位置检测与断电可恢复的特点,而里程计恰好是最能体现这一特性的应用场景之一。第三,该任务在硬件复杂度上相对适中,不依赖复杂的机械结构和执行机构,能够在有限时间内快速完成一个完整且具备演示价值的系统。
因此,我将本项目设计为一个基于 ADMT4000 的断电可恢复里程计演示系统,利用 XIAO ESP32-S3 作为主控,结合 OLED 显示模块与板载存储功能,通过手动旋转磁铁模拟轮子转动,实现里程的实时累计、断电恢复以及按键清零等功能。
二、项目描述
本项目的整体目标,是构建一个能够将 ADMT4000 检测到的多圈绝对角度信息实时转换为累计里程的演示系统,并验证其断电恢复能力。为了增强展示效果和应用合理性,我设定了一个虚拟轮周长为 20 cm 的模型,即认为轮子每旋转一圈,代表前进 20 cm。
系统工作时,ADMT4000 传感器持续输出当前磁铁的绝对多圈角度。XIAO ESP32-S3 通过 SPI 接口读取该信息,并解析为当前圈数和当前圈内角度。在此基础上,程序进一步计算总角度变化量,并利用预设轮周长将其换算为对应的距离增量,最终得到累计里程。OLED 屏幕用于显示当前的圈数、角度和累计里程,构成了完整的人机交互界面。
为了实现题目要求中的“断电后里程不归零”,本项目采用 ESP32 的 Preferences 非易失性存储机制,对累计里程、最近一次传感器总角度以及软件零点进行保存。这样,当系统重新上电时,程序便能够读取历史数据,并结合 ADMT4000 的绝对位置继续恢复并累计里程。
此外,为了提升演示便利性,我还设计了一个板载 BOOT 按键长按清零的功能。当用户在程序运行过程中长按 BOOT 键约 1 秒后,系统会将当前角度设定为新的软件零点,并将累计里程清零。这样既不影响默认的断电恢复逻辑,演示的时候快速重复展示。
三、硬件介绍
本项目使用到的硬件主要包括以下几部分:
1. ADMT4000 多圈绝对角度传感器模块
ADMT4000 是本项目的核心传感器,用于检测磁铁相对于芯片的位置变化,并输出多圈绝对角度信息。相比普通的单圈磁编码器或需要断电后重新回零的角度检测方案,ADMT4000 的优势在于其可以记录多圈信息,并在重新上电后恢复真实位置,因此特别适合应用于里程计、卷线器、升降机构以及机械关节等需要断电记忆的场景。
2. Seeed XIAO ESP32-S3 主控板
XIAO ESP32-S3 作为系统的主控单元,负责整个系统的数据采集、换算、显示与保存。其主要任务包括:
- 通过 SPI 读取 ADMT4000 的原始角度数据
- 将角度信息解析为圈数和连续总角度
- 根据轮子周长将角度变化换算为距离变化
- 控制 OLED 实时显示
- 使用 Preferences 实现断电存储
- 读取板载 BOOT 按键实现软件清零
该主控体积小、资源充足、接口丰富,且便于快速开发,非常适合作为此类传感与显示系统的控制核心。
3. OLED 显示模块
本项目使用了一块小尺寸 I2C OLED 显示模块,用于实时显示系统关键参数。由于显示屏尺寸较小,为了保证可读性,最终保留了三个核心显示字段:
- TURN:当前相对圈数
- ANG:当前相对角度
- DIST:累计里程
OLED 的加入使整个项目从“仅在串口输出调试信息”升级为“具备独立显示能力的完整演示系统”,更适合比赛展示。
4. 磁铁
磁铁是 ADMT4000 的角度检测对象。通过手动旋转磁铁,可以模拟轮子转动。磁铁的安装位置、同轴度以及与模块之间的距离,会直接影响 ADMT4000 的读数稳定性,因此在调试过程中,磁铁安装是一个重要环节。

四、方案框图与设计思路
本项目的方案框图如下:

磁铁/演示轮旋转ADMT4000多圈绝对角度采集XIAO ESP32-S3 数据处理OLED 显示 TURN / ANG /DISTPreferences 非易失性存储板载 BOOT 键
本项目的设计思路可以概括为以下五个步骤:
1. 角度采集
利用 ADMT4000 模块采集磁铁的多圈绝对位置。与普通单圈传感器相比,ADMT4000 能够同时提供圈数信息和单圈内精确角度。
2. 角度解析
XIAO ESP32-S3 通过 SPI 接口读取 ADMT4000 寄存器内容,并将其解析为:
- 当前圈数
- 当前圈内角度
- 连续总角度
3. 距离换算
系统设定轮周长为 20 cm,即每旋转一圈对应 20 cm 位移。程序根据总角度变化量按比例换算得到距离增量,并累计为总里程。
4. 断电恢复
程序定时将当前累计里程、传感器总角度和软件零点写入 Preferences。这样在断电重启后,可以直接恢复断电前的运行状态,实现里程不归零。
5. 按键清零
为了方便现场演示,程序支持长按板载 BOOT 键进行软件清零。清零后,当前角度被设为新的零点,里程归零,但系统仍保留后续断电恢复能力。
这种设计方案在结构上较为完整,同时又尽可能简化了硬件复杂度,适合稳定演示。
五、原理图与 PCB 设计说明
本项目未使用自定义 PCB,因此该部分不涉及自主设计 PCB 和打样环节。整个系统采用现成开发板和模块,通过导线连接完成。
主要连接关系如下:
ADMT4000 与 XIAO ESP32-S3
- CS# 连接至 D1
- SCLK 连接至 D8
- SDO 连接至 D9
- SDI 连接至 D10
- GND 与 XIAO 共地
OLED 与 XIAO ESP32-S3
- GND 连接至 GND
- VCC 连接至 3V3
- SCL 连接至 D5
- SDA 连接至 D4
需要特别注意的是,若 ADMT4000 模块通过自身 Type-C 接口单独供电,则必须确保其地线与 XIAO 主控共地,否则 SPI 通信无法正常工作。
虽然本项目没有自定义 PCB,但这种“模块化拼接”的方式更利于快速原型开发。
六、软件流程图、调试软件说明与关键代码说明
1. 软件流程图

2. 调试软件说明
项目开发和调试主要使用 Arduino IDE / arduino-cli 完成,配合串口监视器观察运行信息。调试时主要关注以下内容:
- ADMT4000 是否能稳定读到有效角度
- OLED 是否正确显示圈数、角度和里程
- 断电重启后里程是否保持
- 长按 BOOT 是否能实现软件清零
3. 关键代码说明
(1)距离换算公式
这是整个项目最核心的计算逻辑:
static float distanceCmFromDeltaDeg(float deltaDeg) {
return (deltaDeg / 360.0f) * WHEEL_CIRCUMFERENCE_CM;
}
该公式表示:一整圈角度为 360°,而在本项目中,一整圈对应 20 cm 距离,因此任意角度变化都可以按比例换算成距离变化。
(2)断电恢复逻辑
程序在初始化时读取上一次保存的数据:
const float savedDistanceCm = prefs.getFloat("dist_cm", 0.0f);
const float savedSensorTotalDeg = prefs.getFloat("sensor_deg", bootSample.totalDeg);
zeroTotalDeg = prefs.getFloat("zero_deg", bootSample.totalDeg);
再根据当前传感器绝对角度与保存角度的差值,补回断电期间的距离变化,从而实现真正意义上的状态恢复。
(3)按键清零逻辑
程序通过检测 BOOT 键的按下持续时间来判断是否执行清零:
if (initialized && !resetHandledThisPress && (nowMs - resetPressStartMs >= RESET_HOLD_MS)) {
resetHandledThisPress = true;
resetOdometerAtCurrentPosition();
}
清零时并不是修改 ADMT4000 本体的绝对角度,而是将当前角度保存为新的软件零点,同时把累计距离归零。这种做法既保持了传感器绝对测量特性,又满足了演示中的“复位”需求。
七、实物演示及说明
实物演示主要包括以下几个环节:
1. 上电恢复
系统上电后,OLED 首先显示启动界面;当 ADMT4000 检测到有效磁铁位置后,OLED 显示当前 TURN、ANG 与 DIST。如果之前已有保存的里程,系统会直接恢复并显示。

2. 手动旋转磁铁进行里程累计
通过手动旋转磁铁或演示轮,模拟车轮转动。程序实时计算角度变化,并将其换算为距离增量,OLED 上的 DIST 实时更新。这样就完成了“旋转圈数到累计里程”的映射展示。
3. 断电重启验证
在系统已经累计一定里程后,断电再重新上电。可以观察到 OLED 显示的里程不会归零,而是保持在断电前的值,说明断电恢复功能正常工作。
4. 长按 BOOT 按键清零
在程序运行过程中,长按 XIAO 板载 BOOT 键约 1 秒,OLED 将显示 RESET OK,同时系统将当前角度设为新的软件零点,并将累计里程清零。之后再次旋转磁铁,新的里程会从零重新累计,便于多次重复演示。
通过上述展示,本项目实现了题目要求中的全部关键功能,并在演示逻辑上更加完整直观。
八、遇到的难点及解决方法
1. 磁铁安装位置不合适导致传感器读数异常
在调试初期,如果磁铁没有与传感器中心尽量同轴,或者磁铁与模块间距不合适,ADMT4000 的角度数据会出现抖动甚至无效。
解决方法: 通过调整磁铁中心位置以及与模块的距离,使其进入稳定工作区间。
2. 上电后出现负里程或非零里程
由于程序实现了断电恢复功能,系统上电后默认会读取之前保存的里程,因此在调试阶段可能出现“刚开机就不是零”的情况。
解决方法: 增加板载 BOOT 长按清零功能,在不破坏断电恢复逻辑的前提下,实现手动归零,更适合演示。
3. 断电恢复与“清零”需求存在逻辑冲突
题目要求断电后里程不丢失,但演示时又希望能够快速归零重新开始。
解决方法: 将“断电恢复”和“人工清零”拆分为两套逻辑:平时自动恢复,长按按键时执行软件零点重设和里程清零,两者互不冲突。
九、心得体会与建议
通过本次项目实践,我对 ADMT4000 多圈绝对角度传感器的特性和应用方式有了更加深入的认识。相比普通的单圈传感器,ADMT4000 最显著的优势在于其能够在断电后恢复真实位置,这使得它在里程计、卷线器、升降机构、机械关节等场景中具有较高的应用价值。通过本次项目,我不仅完成了一个具体功能,还真正理解了“绝对位置感知”和“系统状态恢复”在工程设计中的意义。思考了实际应用中应该如何落地,应该是机械比设计吧。
同时,我也深刻体会到:一个传感器项目的完成,不仅仅取决于代码是否正确,更依赖于机械安装、供电稳定性和接线质量。尤其在调试 ADMT4000 时,磁铁位置、同轴度、间距这些细节都会直接影响结果。只有把硬件搭建、参数理解和软件逻辑结合起来进行整体调试,系统才能稳定运行。
