2026ADI机器控制设计竞赛-旋转方向与转速检测报告
该项目使用了ADMT4000模块,实现了通过磁力检测旋转方向与转速的设计,的设计,它的主要功能为:使用磁转数传感器ADMT4000模块,搭配ESP32开发板,实现通过磁力检测旋转方向、角度与转速的功能。
标签
ADMT4000
磁力检测旋
角度与转速
wushu20300
更新2026-05-18
37

一、项目简介

本项目使用ADMT4000模块来检查磁铁的旋转圈数和角度,通过RP2040读取测量到的数据,通过串口读取并显示当前的速度、圈数和角度。

二、硬件介绍

ADMT4000 模块这是一款多圈磁角度(圈数)传感器,核心采用ADMT4000 芯片。该芯片属于磁转数传感器,即使在设备断电时也能记录磁系统的旋转圈数。重新上电后,可通过 i2c 接口查询模块,获取系统的绝对位置。ADMT4000 最多可记录 46 圈外部磁场变化,绝对位置计数沿顺时针(CW)方向递增。

主控模块基于ESP32微控制器,利用串口进行数据采集和显示

工作原理手持磁铁靠近传感器,同时使磁铁旋转。ADMT4000 模块读取磁场信息,从而获取旋转角度与累计圈数。

三、任务选择

选择任务为任务一:旋转方向与转速检测。

1.手动旋转磁铁,通过串口实时识别旋转方向(正转/反转)并计算转速。

任务要求

2.读取ADMT4000 角度数据,判断当前旋转方向(正转/反转),串口实时显示

3.根据角度变化量和时间计算转速,串口实时显示

静止时显示转速为0,旋转时实时更新

4.46 圈范围内验证方向和转速检测的正确性


四、设计思路

基于ESP32主控单元串联各模块。选用手持可旋转磁铁作为磁场源;ADMT4000传感模块以核心芯片为基础,利用其断电存圈数特性(最大46圈),通过SPI接口与主控通信,遵循顺时针计数规则。ESP32主控承担数据采集、处理与传输职责,借助串口将数据输出至显示终端。

4a0daf6c-a023-4dee-92a6-ddee9a749383.png

1.系统初始化

I2C 接口初始化:配置 ESP32 的 SPI ADMT4000 模块通信。

串口初始化:配置USART,用于输出实时数据。

读取ADMT4000 初始角度:获取当前绝对角度值,作为基准。

2. 数据读取与处理

读取当前角度:通过SPI接口 ADMT4000 读取绝对位置数据解析角度和圈数。

计算角度变化量将当前角度与上次角度相减,得到 delta_angle。

处理360° 跳变:若 delta_angle > 180° 则减去 360°;若 delta_angle < -180° 则加上 360°。

判断旋转方向

delta_angle > 0 → 正转(顺时针)

delta_angle < 0 → 反转(逆时针)

计算转速

记录两次读取的时间差 delta_time(秒)。

转速(度/秒)= delta_angle / delta_time

转速(转/秒)= (delta_angle / 360) / delta_time

串口输出

实时打印:方向(正转/反转)、转速(度/秒 或 转/秒)、累计圈数。

 

 五、系统实现

 

1. XIAO ESP32C3 与 ADMT4000 接线

 image.png

XIAO ESP32C3SPI硬件引脚):

SCK → D8

MOSI → D10

MISO → D9

CS → D2GPIO4,软件片选)

Boot0  D1(开发板固定引脚)

ADMT4000引脚:

VDD → 使用的外部电源Type-C供电

GND → GND

SCK → XIAO D8

SDI → XIAO D9MOSI

SDO → XIAO D10MISO

CS → XIAO D2

715dc3c78ff1d64cf47999b7065c62ed.jpg

2.开发环境TRAE CN

TRAE CN 中配置ESP-IDF v5.4.4 并安装相应的python支持包。

dde35052-71a4-42d2-a2f4-faeb2665d015.png

3.软件编写

软件流程图

image.png

主要功能函数介绍:

 

1. 引脚与参数定义

 #define SAMPLE_INTERVAL_MS      50

#define PRINT_INTERVAL_MS       500

#define ANGLE_DEADZONE_DEG      0.3f

#define MAX_ANGLE_CHANGE_DEG    180.0f

#define MAG_CHECK_WINDOW        5

#define MAG_ANGLE_RANGE_THRESH  2.0f


定义采样间隔50ms、串口输出0.5秒、静止阈值0.3°、最大允许角度跳变180°、转速限幅1000°/s、磁场检测窗口5次及变化阈值2°。这些常量保证了系统实时性与稳定性,防止噪声和异常数据干扰。


2. 线圈复位与按键处理

static void perform_coil_reset(void)

{    gpio_set_level(COIL_RESET_PIN, 1);   

 esp_timer_start_once(timer, COIL_RESET_PULSE_MS * 1000);

}

static void boot0_button_pressed(void* arg, void* data)

{    perform_coil_reset();   

 first_sample = true;   

 magnetic_field_valid = false;    

history_count = 0;

}

按下BOOT0后,复位引脚拉高5ms,硬件清零ADMT4000圈数;同时重置软件状态:首帧标志、磁场标志、历史窗口计数器。确保复位后系统从零开始检测,避免旧数据残留。

 

3. 传感器数据解析

static inline int extract_turns(uint16_t turns_raw)

{    return (turns_raw >> 10) & 0x3F;

}

static inline float compute_absolute_angle(int turns, float single_angle)

{   

 return turns * 360.0f + single_angle;

}


从寄存器0x03高6位提取圈数(0~45),低10位转为单圈角度(0~360°)。compute_absolute_angle 累计绝对角度 = 圈数×360+单圈角,实现连续角度差分,避免跨360°跳变问题,为方向判断提供基础。

 

4. 运行时磁场检测

static bool check_magnetic_field(float current_angle) 
{    angle_history[history_idx] = current_angle;    // 滑动窗口计算最大最小角度差   
 return (max_angle - min_angle) > MAG_ANGLE_RANGE_THRESH;
}

维护长度为5的角度滑动窗口,计算最大最小差值。若差值 > 2°则判为磁场有效,否则无效。该算法仅依赖角度变化,不依赖可能异常的圈数值,可快速识别磁铁靠近/远离,避免无磁铁时的误判。


5. 数据有效性检查


if (turns < 0 || turns > 45)
 {    if (now_ms - last_warning_time > 2000)         
printf("圈数异常=%d\n", turns);  continue;  // 丢弃本次数据
}
if (fabs(delta_angle) > MAX_ANGLE_CHANGE_DEG) 
{    printf("角度跳变过大\n");    continue;
}

有磁场时检查圈数范围0~45和角度跳变是否超过180°,若违反则丢弃该帧数据,仅更新时间戳,保持上一次有效值。每2秒打印一次警告,防止异常数据污染系统状态,确保输出稳定可靠


6. 无磁场处理


if (!magnetic_field_valid) 
{    current_direction = "无磁场/静止";
    current_speed_dps = 0.0f;
    if (has_valid_data) 
{        current_turns = frozen_turns;
        current_angle = frozen_angle;    
} else 
{        current_turns = 0; current_angle = 0.0f;    }    continue;}

无磁场时强制显示“无磁场/静止”,转速0。若曾获得有效数据,则显示冻结值;否则显示0圈0°。完全避免了无磁铁时圈数异常打印,同时保持输出整洁。磁场恢复后自动退出该模式。


7. 角度差分与方向转速计算

float delta_angle = absolute_angle - last_absolute_angle;
float delta_time_s = (now_us - last_time_us) / 1e6f;
if (fabs(delta_angle) < ANGLE_DEADZONE_DEG) 
{    // 静止处理} 
else {    current_direction = (delta_angle > 0) ? "正转" : "反转";   
  float raw_speed = fabs(delta_angle) / delta_time_s;
     current_speed_dps = (raw_speed > MAX_SPEED_DPS) ? MAX_SPEED_DPS : raw_speed;
    current_speed_rps = current_speed_dps / 360.0f;}

计算相邻两次角度差和时间差。角度差绝对值小于0.3°视为静止;否则依据正负判方向,转速 = |角度差|/时间差(度/秒),再除以360得转/秒。转速超限幅时取上限,避免异常尖峰。


8. 静止冻结机制


if (fabs(delta_angle) < ANGLE_DEADZONE_DEG)
 {    if (!is_stationary) 
{        frozen_turns = current_turns;
        frozen_angle = current_angle;
        is_stationary = true;    
}    
current_turns = frozen_turns;
    current_angle = frozen_angle;
    last_time_us = now_us;  // 仅更新时间
}

静止时,若之前是运动状态则冻结当前圈数和角度;之后每次输出都使用冻结值,不再更新基准角度。这有效防止静止时微小角度漂移导致显示数字抖动,同时保持了转速为零。


9. 主循环与串口输出

while (1)
 {    if (now_ms - last_sample_time >= SAMPLE_INTERVAL_MS) 
{        // 读取传感器并更新状态    }    
if (now_ms - last_print_time >= PRINT_INTERVAL_MS)
 {        printf("方向: %s | 转速: %.2f °/s (%.3f rps) | 圈数: %d | 角度: %.2f°\n", current_direction, current_speed_dps, current_speed_rps, current_turns, current_angle);   
 }    
vTaskDelay(10);
}

采用双定时机制:每50ms执行传感器读取和状态更新,保证实时性;每500ms通过串口输出一次结果,避免刷屏。输出内容清晰显示方向、转速(度/秒、转/秒)、圈数、角度,满足任务要求。

   

 六、运行测试

1.开机

image.png

2.加上磁铁并旋转

image.png


七、项目出现的意外和对项目的总结

整个项目过程中出现的问题:

1.太相信AI,导致管脚连接和程序出错。

因为在微信里看小伙伴们说用AI调基本上2个小时就调通了。我便把全部都寄托在AI生成代码和调试上,结果选用不合适的AI,导致把所有的情况都进行了尝试,最终也没有调通,这大概花了我一个星期的每个晚上,同时群里有个小伙伴说自己的芯片出了问题,让我一直坚定相信是芯片出了问题。虽然也有小伙伴说芯片没有那么容易坏,但是后来在测试一些管脚的电平时,显示不正常,示波器测试也不正常,更让我坚定相信了这一结果,便放弃了继续尝试的想法,把其中一天调试出问题在AI里的记录粘在了帖子里,本来想根据过程修改得更系统一些,但是太长了,懒的看,便放置了。如果不是管理员再次联系,可能就放弃了。

2.管脚连线的问题。

在管脚连线的过程中,烦了一个致命的错误,只是凭借网络搜索的一些去判断管脚的作用而没有认真的阅读开发板资料,更没有仔细辨别各个管脚的作用。以至于后来有一次把CS连接到了开关上,导致松开开关就是读取错误,按下开关便正常读取一次数据。为了解决这个问题,尝试更改开关的状态,甚至外接了一个开关,都没有解决,花费了半天的时间才发现问题的所在。

3.硬件设备的问题。

因为手中没有磁铁,最开始的时候是在一个磁吸设备上拆下了一个圆形磁铁,这个时候还没有跑通,读不出来数据,然后在网上买了圆形强磁,依旧是读不出来数据。群里技术说可能是磁铁不合适,可能是安装位置不正确,这个时候已经到了认为是芯片出故障的阶段,便没有继续开展工作。直到后来跑通后,只是能看到数据随外部磁场产生变化,但是很难精确对应起来。

希望在能参与后续的活动并积累更多的经验。

在后续修改测试笔记的过程中,感受到了一种很严谨的学习和工作作风,受益颇多。

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