1. 电磁寻迹小车系统概述
电磁寻迹小车是一种通过检测铺设在地面上的电磁信号来实现自动导航的智能移动平台。这种技术在大学生智能车竞赛、工业AGV小车等领域有着广泛应用。我们选用STM32F103C8T6作为主控芯片,这是一款性价比极高的ARM Cortex-M3内核微控制器,具有丰富的外设资源,非常适合用于此类嵌入式控制项目。
电磁寻迹的基本原理是:在赛道中央铺设通有20kHz交流电的导线,小车通过电感线圈检测电磁场强度变化。当小车偏离中心线时,左右两侧线圈感应到的信号强度会出现差异,通过分析这种差异就能判断偏离方向和程度。
提示:实际比赛中电磁导线的电流频率可能有所不同,需要根据具体规则调整传感器谐振频率。
2. 硬件系统设计详解
2.1 核心电路设计
主控电路以STM32F103C8T6为核心,需要配置以下关键电路:
- 电源电路:采用AMS1117-3.3V稳压芯片,将输入电压(通常7.2V锂电池)转换为3.3V
- 复位电路:10kΩ上拉电阻配合0.1μF电容实现可靠复位
- 时钟电路:8MHz晶振配合两个22pF负载电容
- 调试接口:标准的SWD四线调试接口(SWDIO、SWCLK、GND、VCC)
2.2 电磁传感器设计
电感式电磁传感器是系统的核心感知部件,其设计要点包括:
- 线圈参数:建议使用直径8-10mm的空心线圈,绕制50-80匝
- 谐振电路:LC并联谐振电路,谐振频率应匹配赛道电磁场频率(通常20kHz)
- 信号调理:二级放大电路设计
- 第一级:高输入阻抗的电压跟随器
- 第二级:可调增益的反相放大器(增益通常100-200倍)
典型电路参数:
- 谐振电容:0.1μF(对应20kHz时电感量约6.3mH)
- 放大电阻:Rf=100kΩ,Rin=1kΩ(增益100倍)
2.3 电机驱动设计
L298N双H桥驱动模块是常见选择,其关键连接方式:
- 使能端:连接STM32的PWM输出引脚(如TIM3_CH1、TIM3_CH2)
- 输入控制:四个GPIO控制电机正反转
- 电源设计:
- 逻辑电源:5V(可从稳压芯片获取)
- 电机电源:直接接电池(7.2V)
- 必须加装续流二极管(如1N5819)
重要提示:电机电源与逻辑电源必须共地,且电机回路要远离信号线。
3. PCB设计实战要点
3.1 布局策略
-
分区布局原则:
- 数字区:MCU、晶振、调试接口
- 模拟区:传感器电路、运放
- 功率区:电机驱动、电源电路
-
关键器件位置:
- 电磁传感器前置,距离地面1-2cm
- 电机驱动靠近电机接口
- 稳压芯片靠近电源输入
3.2 布线技巧
-
电源布线:
- 主电源线宽≥1mm
- 3.3V电源采用星型拓扑
- 每个IC电源引脚添加0.1μF去耦电容
-
信号线处理:
- 模拟信号线尽量短,两侧铺地保护
- 数字信号线避免穿越模拟区
- PWM信号线要等长,减少时序偏差
-
接地设计:
- 采用单点接地策略
- 模拟地和数字地在电源处单点连接
- 电机回流路径独立
4. 软件系统实现
4.1 初始化代码深度解析
ADC初始化代码增强版:
c复制void ADC_Init_Enhanced(void) {
ADC_InitTypeDef ADC_InitStruct;
GPIO_InitTypeDef GPIO_InitStruct;
// 时钟使能
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_ADC1, ENABLE);
// GPIO配置
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AIN;
GPIO_Init(GPIOA, &GPIO_InitStruct);
// ADC校准
ADC_ResetCalibration(ADC1);
while(ADC_GetResetCalibrationStatus(ADC1));
ADC_StartCalibration(ADC1);
while(ADC_GetCalibrationStatus(ADC1));
// ADC参数配置
ADC_InitStruct.ADC_Mode = ADC_Mode_Independent;
ADC_InitStruct.ADC_ScanConvMode = ENABLE; // 启用扫描模式
ADC_InitStruct.ADC_ContinuousConvMode = ENABLE; // 连续转换
ADC_InitStruct.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
ADC_InitStruct.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStruct.ADC_NbrOfChannel = 3;
ADC_Init(ADC1, &ADC_InitStruct);
// 规则通道配置
ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_55Cycles5);
ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 2, ADC_SampleTime_55Cycles5);
ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 3, ADC_SampleTime_55Cycles5);
// DMA配置(可选)
// ... DMA初始化代码 ...
ADC_Cmd(ADC1, ENABLE);
ADC_SoftwareStartConvCmd(ADC1, ENABLE); // 启动连续转换
}
关键改进点:
- 增加了ADC校准流程,提高转换精度
- 采用连续转换模式,减少软件开销
- 预配置规则通道序列,便于DMA传输
- 采样时间设置为55.5周期,适合中频信号
4.2 电机控制算法优化
基础PID控制算法实现:
c复制typedef struct {
float Kp, Ki, Kd;
float integral;
float prev_error;
} PID_Controller;
void PID_Init(PID_Controller* pid, float Kp, float Ki, float Kd) {
pid->Kp = Kp;
pid->Ki = Ki;
pid->Kd = Kd;
pid->integral = 0;
pid->prev_error = 0;
}
float PID_Update(PID_Controller* pid, float error, float dt) {
pid->integral += error * dt;
float derivative = (error - pid->prev_error) / dt;
pid->prev_error = error;
return pid->Kp * error + pid->Ki * pid->integral + pid->Kd * derivative;
}
void Motor_Control(float deviation) {
static PID_Controller pid;
static uint8_t is_initialized = 0;
if(!is_initialized) {
PID_Init(&pid, 0.5f, 0.01f, 0.2f); // 需要根据实际调试
is_initialized = 1;
}
float control = PID_Update(&pid, deviation, 0.01f); // 10ms控制周期
// 限幅处理
control = (control > 500) ? 500 : ((control < -500) ? -500 : control);
// 电机输出
if(control >= 0) {
TIM_SetCompare1(TIM3, 500 + control); // 左电机
TIM_SetCompare2(TIM3, 500 - control); // 右电机
} else {
TIM_SetCompare1(TIM3, 500 + control);
TIM_SetCompare2(TIM3, 500 - control);
}
}
算法特点:
- 采用位置式PID算法,避免积分饱和
- 加入微分项,提高系统响应速度
- 控制量限幅保护,防止电机过载
- 参数可在线调整,方便现场调试
5. 系统调试与优化
5.1 传感器校准流程
-
静态校准:
- 将小车置于赛道中心,记录各传感器基准值
- 向左/右偏移1cm,记录差值
- 计算灵敏度系数:mV/cm
-
动态测试:
- 以低速运行,观察传感器响应曲线
- 调整运放增益,使信号幅度在ADC量程的70-90%
-
数字滤波:
c复制#define FILTER_DEPTH 5 uint16_t moving_average(uint16_t new_val, uint16_t* buffer) { static uint8_t index = 0; static uint32_t sum = 0; sum -= buffer[index]; buffer[index] = new_val; sum += new_val; index = (index + 1) % FILTER_DEPTH; return sum / FILTER_DEPTH; }
5.2 常见问题排查
-
传感器无信号:
- 检查LC谐振频率(用示波器观察波形)
- 测量运放各级输出
- 确认ADC引脚配置正确
-
电机抖动:
- 检查PWM频率(建议10-20kHz)
- 测量电源电压波动
- 检查电机接线是否松动
-
跑偏问题:
- 重新校准传感器
- 检查机械结构对称性
- 调整PID参数
6. 进阶优化方向
-
赛道记忆算法:
- 记录历史偏差数据
- 预判弯道趋势
- 实现速度规划
-
动态参数调整:
c复制void adaptive_PID(PID_Controller* pid, float error) { // 根据误差大小动态调整参数 if(fabs(error) > 100) { pid->Kp = 0.8f; pid->Ki = 0.0f; // 大误差时取消积分 } else { pid->Kp = 0.5f; pid->Ki = 0.01f; } } -
无线调试接口:
- 通过蓝牙传输实时数据
- 上位机显示传感器波形
- 在线修改控制参数
在实际比赛中,我们通过以下优化将赛道通过时间缩短了30%:
- 采用三排传感器布局,提高前瞻距离
- 实现弯道提前减速策略
- 优化电池供电路径,降低内阻