ADI机器控制设计竞赛 - 基于ADMT4000的多圈角度读取与断电记忆
该项目使用了ADMT4000,实现了传感器数据读取的设计,它的主要功能为:多圈角度读取与断电记忆。
标签
ADI
角度传感器
ADMT4000
金玉其中
更新2026-05-11
42

1 项目任务介绍

1.1 任务背景

本项目围绕ADMT4000多圈绝对角度传感器展开,通过SPI通信接口实时读取传感器的单圈角度、多圈角度及累计圈数,并通过串口输出验证其在断电条件下的数据保持能力。

1.2 任务目标

序号

任务目标

说明

1

SPI 通信实现

通过 bitbangio 软件模拟 SPI 读取 ADMT4000 寄存器数据

2

实时数据读取

读取单圈角度(ANGLE 寄存器)和多圈角度+圈数(ABSANGLE 寄存器)

3

串口数据打印

实时输出当前圈数、绝对角度、单圈角度

4

断电数据保持测试

手动旋转至任意位置后断电,重新上电验证数据一致性

5

断电转动记忆测试

断电期间手动转动传感器,上电后验证角度记录功能

2 项目描述

2.1 项目概述

本项目设计了一套基于ADMT4000多圈绝对角度传感器的实时角度监测系统。系统以ESP32开发板为主控,通过SPI协议与传感器通信,实时采集并显示传感器的单圈角度值和多圈累计圈数。同时,系统验证了 ADMT4000传感器的非易失性数据存储特性,测试了断电前后数据一致性以及断电期间转动角度的记忆能力。

3 硬件介绍

3.1 主控板 — Adafruit ESP32-S3

这个开发板带有原生USB和4mb闪存+ 2mb PSRAM,非常适合与CircuitPython开发。原生USB意味着它可以像键盘或磁盘驱动器一样工作。WiFi意味着它对物联网项目来说非常棒。ESP32-S3是一款高度集成、低功耗、2.4 GHz Wi-Fi/BLE片上系统(SoC)解决方案,内置本地USB以及其他一些有趣的新技术。凭借其最先进的功率和射频性能,该SoC是与物联网(IoT),可穿戴电子产品和智能家居相关的各种应用场景的理想选择。

3.2 角度传感器 — ADMT4000

ADMT4000 是一款 多圈绝对角度传感器,能够在断电后保持位置数据,上电后立即读取当前绝对位置。

参数

说明

工作电压

3.3V

通信协议

SPI

分辨率

12位(单圈4096等分)

测量范围

0 ~ 46圈(0 ~ 16560°)

数据保持

非易失性存储

时钟频率

最大 4 MHz

工作温度

-40°C ~ +85°C

寄存器映射

寄存器

地址

功能

数据长度

CNVPAGE

0x01

转换页面选择

-

ABSANGLE

0x03

绝对角度+多圈圈数

16位

ANGLE

0x05

单圈角度

12位

FAULT

0x06

故障状态

8位

GENERAL

0x10

通用配置

8位

3.3 硬件连接图
0

3.4 引脚定义

SPI 通信引脚

ESP32-S3 引脚

ADMT4000

功能说明

D10

CLK

SPI 时钟信号

D11

MOSI

主输出从输入数据

D12

MISO

主输入从输出数据(可选)

A5

CS

片选信号,低电平有效

复位控制引脚(ADMT4000_RST)

XIAO 引脚

功能

说明

A2

RST

复位信号引脚

A3

SHDN

供电关断控制引脚

A4

COIL_PS

线圈电源使能引脚

人机交互

XIAO 引脚

功能

说明

BOOT

启动按钮

低电平触发复位操作

4 方案设计

4.1 系统框图
0

5 软件设计

5.1 软件流程图
0

5.2 主程序代码结构

代码文件列表

文件名

功能说明

code.py

主程序入口,初始化和主循环

ADMT4000.py

传感器驱动类(ADMT4000、ADMT4000_RST)

关键代码说明

SPI 初始化(code.py)


spi_admt = bitbangio.SPI(
clock=board.D10, # 模拟SPI时钟
MOSI=board.D11, # 主输出从输入
MISO=board.D12 # 主输入从输出(可选)
)

cs = board.A5 # 片选引脚

# 初始化ADMT4000
admt4000 = ADMT4000(spi_admt, cs)

使用bitbangio库模拟SPI通信,D10 作为时钟、D11 作为 MOSI、D12 作为 MISO。A5 作为片选信号。

复位控制类(ADMT4000.py)


class ADMT4000_RST:
def __init__(self, coil_ps_pin=board.A4, shdn_pin=board.A3, rst_pin=board.A2):
"""初始化复位控制引脚"""
self.coil_ps = digitalio.DigitalInOut(coil_ps_pin)
self.coil_ps.direction = digitalio.Direction.OUTPUT
self.shdn = digitalio.DigitalInOut(shdn_pin)
self.shdn.direction = digitalio.Direction.OUTPUT
self.rst = digitalio.DigitalInOut(rst_pin)
self.rst.direction = digitalio.Direction.OUTPUT

# 初始状态
self.coil_ps.value = False
self.shdn.value = True # SHDN默认高(正常工作)
self.rst.value = True # RST默认高(正常工作)

初始化三个控制引脚,设置为输出模式,初始值为正常工作状态。

复位流程


def coil_rst(self):
"""执行线圈复位流程"""
print("开始复位流程...")

# 1. RST拉低
self.rst.value = False
time.sleep(0.01)

# 2. SHDN拉高 (为线圈供电)
self.shdn.value = True
print("线圈充电中...")
time.sleep(5) # 等待5秒充电
self.shdn.value = False

# 3. COIL_PS拉高 (启动复位)
self.coil_ps.value = True
print("触发复位")
time.sleep(0.02)

# 4. COIL_PS拉低
self.coil_ps.value = False

# 5. RST拉高
self.rst.value = True
time.sleep(0.02)

print("复位完成")

寄存器读取


def read_register(self, reg_addr):
"""从指定寄存器读取数据"""
self.cs.value = False # 片选拉低

while not self.spi.try_lock():
pass # 等待SPI

try:
# 发送读命令:寄存器地址 | 0x01
tx = bytearray([reg_addr | 0x01, 0x00, 0x00, 0x00])
rx = bytearray(len(tx))
self.spi.write_readinto(tx, rx) # SPI传输
finally:
self.spi.unlock()

self.cs.value = True # 片选拉高

# 解析返回数据
Data1 = rx[1] << 8
Data1 |= rx[2]
return int(Data1)

读取寄存器时,发送字节的第一个 bit 必须为 1(表示读操作),后 7 bit 为寄存器地址。

绝对角度解析

def read_absolute_angle(self):
"""读取绝对角度和旋转计数"""
abs_angle_data = self.read_register(self.ABSANGLE)

# 解析数据
turn_count = (abs_angle_data >> 8) / 4 # 高8/4 = 圈数
angle = (abs_angle_data & 0x3ff) * 0.351 # 低10位 × 0.351°

return angle, turn_count

ABSANGLE 寄存器返回 16 位数据,高 8 位表示累计圈数(需除以 4),低 10 位表示当前圈的细分数(乘以 0.351° 得到角度值)。

按键检测与主循环

# 初始化启动按钮
boot_btn = digitalio.DigitalInOut(board.BOOT)
boot_btn.switch_to_input(pull=digitalio.Pull.UP)

reset_in_progress = False

while True:
# 检测启动按钮按下 (低电平触发)
if not boot_btn.value and not reset_in_progress:
reset_in_progress = True
admt_rst.coil_rst()
reset_in_progress = False

# 读取并打印角度数据
ABSangle, turn_count = admt4000.read_absolute_angle()
angle = admt4000.read_angle()
print(f"Abs Angle: {ABSangle:.0f}°, Turn Count: {turn_count}")
print(f"Angle: {angle:.0f}°")

time.sleep(1)

6 实物演示及测试结果

数据读取测试

上电后手动旋转传感器,观察串口输出的角度变化。


0

单圈角度和多圈圈数读取正常,数据随旋转实时更新。

断电数据保持测试

测试方法: 旋转至特定位置后断电,重新上电观察数据。


0

ADMT4000 传感器具有非易失性数据存储功能,断电后数据完整保留,重新上电即可读取。

断电转动记忆测试

测试方法: 断电期间手动转动传感器,重新上电观察数据变化。


0


0

断电期间传感器的转动角度大概是180°,上电后读取的数据包含了断电期间的转动量,实现转动记忆功能

7 遇到的难点及解决方法

复位操作失败

问题描述: 按下复位按钮后,传感器角度未能归零,复位流程执行但效果不佳。

尝试的解决方案:

方案

调整内容

测试结果

方案1

增加充电时间(2秒→5秒)

仍未成功

方案2

调整复位引脚时序

效果不明显

方案3

修改 COIL_PS 脉冲宽度

角度有微小变化但未归零

经过多次软件调试和时序优化,复位功能仍未能完全实现目标。

8 心得体会

在本次项目实践中,积累了极为宝贵的经验。在软件模拟SPI通信方面,我们不仅深入探究了SPI协议的运作机制,还熟练掌握了bitbangio库的应用技巧,成功实现了通过软件手段模拟硬件通信接口的功能。对于多圈传感器数据处理,我们透彻理解了ADMT4000传感器的数据协议规范,能够精准解析16位寄存器数据,并掌握了单圈角度与多圈累计圈数的精确计算方法。

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