2026 ADI机器控制设计竞赛 - 用ADMT4000模块实现断电可恢复里程计
该项目使用了ADMT4000模块,实现了断电可恢复里程计的设计,它的主要功能为:实现里程计功能,将旋转圈数换算为行驶距离,并在断电重启后保持累计里程不丢失。
标签
ESP32S3
xiao
ADMT4000
42漫游者
更新2026-05-11
19

一、所选任务介绍

本次项目选择完成的任务为:基于 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 的读数稳定性,因此在调试过程中,磁铁安装是一个重要环节。


7e4b028729cc02f744eec25a3ad983aa.jpg


fe55d5275adb8f332c27c1e04651973e.jpg

四、方案框图与设计思路

本项目的方案框图如下:

image.png

磁铁/演示轮旋转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. 软件流程图


OLED Preference Adjustment-2026-04-24-093229.png

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 显示当前 TURNANG  DIST。如果之前已有保存的里程,系统会直接恢复并显示。

1037d8abcc99010b71f172c7a787e834.jpg

2. 手动旋转磁铁进行里程累计

通过手动旋转磁铁或演示轮,模拟车轮转动。程序实时计算角度变化,并将其换算为距离增量,OLED 上的 DIST 实时更新。这样就完成了“旋转圈数到累计里程”的映射展示。

3. 断电重启验证

在系统已经累计一定里程后,断电再重新上电。可以观察到 OLED 显示的里程不会归零,而是保持在断电前的值,说明断电恢复功能正常工作。

4. 长按 BOOT 按键清零

在程序运行过程中,长按 XIAO 板载 BOOT 键约 1 秒,OLED 将显示 RESET OK,同时系统将当前角度设为新的软件零点,并将累计里程清零。之后再次旋转磁铁,新的里程会从零重新累计,便于多次重复演示。

通过上述展示,本项目实现了题目要求中的全部关键功能,并在演示逻辑上更加完整直观。

八、遇到的难点及解决方法

1. 磁铁安装位置不合适导致传感器读数异常

在调试初期,如果磁铁没有与传感器中心尽量同轴,或者磁铁与模块间距不合适,ADMT4000 的角度数据会出现抖动甚至无效。
解决方法: 通过调整磁铁中心位置以及与模块的距离,使其进入稳定工作区间。

2. 上电后出现负里程或非零里程

由于程序实现了断电恢复功能,系统上电后默认会读取之前保存的里程,因此在调试阶段可能出现“刚开机就不是零”的情况。
解决方法: 增加板载 BOOT 长按清零功能,在不破坏断电恢复逻辑的前提下,实现手动归零,更适合演示。

3. 断电恢复与“清零”需求存在逻辑冲突

题目要求断电后里程不丢失,但演示时又希望能够快速归零重新开始。
解决方法: 将“断电恢复”和“人工清零”拆分为两套逻辑:平时自动恢复,长按按键时执行软件零点重设和里程清零,两者互不冲突。

九、心得体会与建议

通过本次项目实践,我对 ADMT4000 多圈绝对角度传感器的特性和应用方式有了更加深入的认识。相比普通的单圈传感器,ADMT4000 最显著的优势在于其能够在断电后恢复真实位置,这使得它在里程计、卷线器、升降机构、机械关节等场景中具有较高的应用价值。通过本次项目,我不仅完成了一个具体功能,还真正理解了“绝对位置感知”和“系统状态恢复”在工程设计中的意义。思考了实际应用中应该如何落地,应该是机械比设计吧。

同时,我也深刻体会到:一个传感器项目的完成,不仅仅取决于代码是否正确,更依赖于机械安装、供电稳定性和接线质量。尤其在调试 ADMT4000 时,磁铁位置、同轴度、间距这些细节都会直接影响结果。只有把硬件搭建、参数理解和软件逻辑结合起来进行整体调试,系统才能稳定运行。

附件下载
admt4000_odometer_demo.ino
团队介绍
个人独立开发
评论
0 / 100
查看更多
硬禾服务号
关注最新动态
0512-67862536
info@eetree.cn
江苏省苏州市苏州工业园区新平街388号腾飞创新园A2幢815室
苏州硬禾信息科技有限公司
Copyright © 2024 苏州硬禾信息科技有限公司 All Rights Reserved 苏ICP备19040198号