一、硬件介绍:

首先是传感器ADMT4000,它是一种磁转数传感器,即使在设备断电时也能够记录磁系统的旋转次数。通电时可以查询该套件,以报告系统的绝对位置。绝对位置通过串行外设接口 (SPI) 报告。ADMT4000 最多可计数 46 圈外部磁场,以顺时针 (CW) 方向递增绝对位置计数。该套件包括三个磁传感器,一个用于计数系统旋转次数的巨磁电阻(GMR)转数计数传感器,一个 GMR 象限检测传感器和一个各向异性磁阻(AMR)角度传感器。AMR 角度传感器与 GMR 象限检测传感器结合使用,可确定系统在 360° 范围内的绝对位置。将 GMR 转数计数传感器输出与 AMR 角度传感器输出相结合,该套件就能以高角度精度报告系统的位置。

执行器件,是一个360度的舵机。与角度舵机有点区别,这个舵机是通过PWM值控制转速和转动方向。
PWM信号与360舵机转速的关系:
0.5ms----------------正向最大转速;
1.5ms----------------速度为0;
2.5ms----------------反向最大转速;
主控使用ESP32-P4。
二、任务介绍:
这次选择任务1:基于多圈绝对位置的多层电梯升降控制系统。ADMT4000 可以对多圈旋转进行检测,这里用舵机模拟电梯的运行,通过舵机旋转移动轿厢移动,设定每旋转1圈对应轿厢移动一层楼。系统断电后,重新上电需要默认电梯轿厢移动到0层楼层。电梯速度需要控制,不能太快。

三、项目实现
用PCB做了个支架,将舵机的输出轴悬在ADMT4000 芯片正上方。舵机输出轴上粘了一颗径向磁铁。老师提供了ESP-IDF读取ADMT4000的例程,所以这里主控我选择了ESP32-P4,下载了老师的项目来实现功能。

有着老师的例程,很容易就读取到了ADMT4000的圈数,然后添加舵机驱动。这里舵机使用LEDC来产生PWM方波进行驱动。PWM方波频率为50Hz,通过占空比控制舵机旋转的方向和速度。
/* 360度舵机
PWM信号与360舵机转速的关系:
0.5ms----------------正向最大转速;
1.5ms----------------速度为0;
2.5ms----------------反向最大转速;
*/
#include "servo360.h"
/**
* @brief 初始化
* @param 无
* @retval 无
*/
void servo_init(void)
{
ledc_timer_config_t ledc_timer = {
.speed_mode = LEDC_LOW_SPEED_MODE,
.duty_resolution = LEDC_TIMER_10_BIT,
.timer_num = SERVO_LEDC_PWM_TIMER,
.freq_hz = 50, // Set output frequency at 50Hz
.clk_cfg = LEDC_AUTO_CLK
};
ESP_ERROR_CHECK(ledc_timer_config(&ledc_timer));
// Prepare and then apply the LEDC PWM channel configuration
ledc_channel_config_t ledc_channel = {
.speed_mode = LEDC_LOW_SPEED_MODE,
.channel = SERVO_LEDC_PWM_CH0_CHANNEL,
.timer_sel = SERVO_LEDC_PWM_TIMER,
.intr_type = LEDC_INTR_DISABLE,
.gpio_num = SERVO_LEDC_PWM_CH0_GPIO,
.duty = 75, // Set duty to 0%
.hpoint = 0
};
ESP_ERROR_CHECK(ledc_channel_config(&ledc_channel));
}
/**
* @brief PWM占空比设置
* @param duty:PWM占空比
* @retval 无
*/
void sg90_pwm_set_duty(uint16_t duty)
{
ledc_set_duty(LEDC_LOW_SPEED_MODE, SERVO_LEDC_PWM_CH0_CHANNEL, duty); /* 设置占空比 */
ledc_update_duty(LEDC_LOW_SPEED_MODE, SERVO_LEDC_PWM_CH0_CHANNEL); /* 更新占空比 */
}
//舵机控制
//speed:速度控制 0.5ms----------------正向最大转速; 1.5ms----------------速度为0; 2.5ms----------------反向最大转速;
// 速度值从-50到50
void steer_control(int speed)
{
sg90_pwm_set_duty(speed+75);
}
然后因为还需要和用户交互,用户需要输入需要到达的楼层给系统。所以增加了串口输入功能,用来和用户进行交互。这里添加了串口1.
#include "uart.h"
/**
* @brief 初始化串口
* @param baudrate: 波特率, 根据自己需要设置波特率值
* @note 注意: 必须设置正确的时钟源, 否则串口波特率就会设置异常.
* @retval 无
*/
void uart_init(uint32_t baudrate)
{
const uart_config_t uart_cfg = {
.baud_rate = UART_BAUD_RATE,
.data_bits = UART_DATA_BITS,
.parity = UART_PARITY,
.stop_bits = UART_STOP_BITS,
.flow_ctrl = UART_FLOW_CTRL,
.source_clk = UART_SCLK_DEFAULT,
};
// Initialize UART peripheral with the given configuration
uart_param_config(UART_PORT_NUM, & uart_cfg);
// Set UART pins
uart_set_pin(UART_PORT_NUM, UART_TX_GPIO_PIN, UART_RX_GPIO_PIN, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
// Install UART driver and get the queue handle
uart_driver_install(UART_PORT_NUM, RX_BUF_SIZE, TX_BUF_SIZE, 0, NULL, 0);
}
四、功能展示
ADMT4000连接到ESP32-P4上,舵机也与开发板连接。但是ADMT4000模块杜邦线没有电源输入,所以需要额外再用一条Type-c线给模块供电。开发板通过串口模块连接电脑,使用串口上位机可以输入数字给开发板,用来控制舵机旋转。



五、存在的问题
1、舵机旋转会有电流干扰,如果舵机设定速度过快,ESP32-P4串口就有可能连不上了。所以这里开发板第二个type-c口也连上了一个USB电源,用来给整个系统供电,以保证电源的稳定,舵机速度设定都是比较慢的,防止电流干扰。
2、舵机正向和逆向旋转速度不一致。正向旋转时最低速度给2即可,但是逆向给最低速度2都无法旋转,需要给到3才能旋转。这也就导致同样的速度,旋转方向不一样时速度是不一样的。
3、以后想用这个芯片做无刷电机小车的轮子的传感器,但是不知道能不能对ADMT4000当前的圈数进行复位,重置当前圈数归零的方法啊?
六、心得体会:
感谢硬核科技和ADI提供的这次机会,能够体验到这颗顶尖的磁转数传感器。在这里学习最新技术,有老师手把手指导,还有群里大佬的耐心讲解,学习即开心又高效。