跑跑啦航模

  STM32巡线小车是学习嵌入式控制和PID算法的经典项目。本文以STM32F103C8T6(蓝色魔法板)为例,做一台高速巡线小车。

一、硬件准备

  主控:STM32F103C8T6最小系统板 × 1

  下载器:ST-Link V2 或 USB转TTL串口模块

  巡线传感器:5路红外巡线模块(TCRT5000)× 1

  驱动:L298N 或 TB6612FNG电机驱动

  电机:带编码器的直流减速电机 × 2(编码器用于测速,做闭环控制)

  底盘:2WD小车底盘

  电源:7.4V(2S)锂电池

二、5路巡线传感器原理

  5路红外传感器排成一条直线,每个传感器检测到黑线时输出低电平(或高电平,取决于模块设计)。常见的传感器排列方式和对应数值:

  传感器位置从左到右编号 1 2 3 4 5

  当小车完全在黑线上方时,只有3号(中间)传感器检测到黑线,输出值为 00100。

  当小车偏左时,左侧传感器检测到黑线,如 11000。

  我们可以将5位二进制加权计算出一个位置偏差值:

  偏差 = (-2×S1 + -1×S2 + 0×S3 + 1×S4 + 2×S5) / (S1+S2+S3+S4+S5)

  偏差范围 -2 ~ +2,0表示居中。

三、PID巡线算法实现

// PID巡线核心代码(Keil MDK工程片段)

#include "stm32f10x.h"
#include "delay.h"

// PID参数(需要根据实际情况整定)
float Kp = 0.5;  // 比例系数
float Ki = 0.01; // 积分系数
float Kd = 0.1;  // 微分系数

// 读5路传感器值
uint8_t ReadSensors(void) {
    return (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_0) << 0) |
           (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1) << 1) |
           (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_2) << 2) |
           (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_3) << 3) |
           (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_4) << 4);
}

// 计算偏差
float CalcError(uint8_t sensorVal) {
    uint8_t s[5];
    float error = 0;
    float sum = 0;
    for(int i=0; i<5; i++) {
        s[i] = (sensorVal >> i) & 0x01;
    }
    error = (-2*s[0] + -1*s[1] + 0*s[2] + 1*s[3] + 2*s[4]);
    sum = s[0]+s[1]+s[2]+s[3]+s[4];
    if(sum == 0) return 0; // 没检测到线
    return error / sum;
}

// PID控制器
float lastError = 0;
float integral = 0;

int PID_Control(float error) {
    float proportional = error;
    integral += error;
    float derivative = error - lastError;
    lastError = error;
    return (int)(Kp*proportional + Ki*integral + Kd*derivative);
}

// 主循环
int baseSpeed = 60; // 基础速度 0-100
void main(void) {
    while(1) {
        uint8_t sensors = ReadSensors();
        float error = CalcError(sensors);
        int correction = PID_Control(error);
        
        int leftSpeed = baseSpeed + correction;
        int rightSpeed = baseSpeed - correction;
        
        // 限幅
        if(leftSpeed > 100) leftSpeed = 100;
        if(leftSpeed < -100) leftSpeed = -100;
        if(rightSpeed > 100) rightSpeed = 100;
        if(rightSpeed < -100) rightSpeed = -100;
        
        SetMotorSpeed(LEFT, leftSpeed);
        SetMotorSpeed(RIGHT, rightSpeed);
        
        delay_ms(10);
    }
}

四、PID参数整定方法

  1. 先将Ki和Kd设为0,只调Kp。从小到大增加Kp直到小车在线路上开始震荡。

  2. Kp调到刚好震荡后稍微减小一点(取临界值的60%~80%)。

  3. 加入Kd微分项,消除震荡,让小车走线更平滑。Kd通常取Kp的10%~20%。

  4. 最后加一点点Ki积分项(Kp的1%~5%),消除直线段的稳态误差。

  实际调试中,推荐串口输出偏差值和PID输出值,用曲线图观察效果。

五、常见问题

  Q:小车在直线上左右摆动?

  A:Kp太大或Kd太小。减小Kp或增大Kd。

  Q:小车过弯时冲出轨道?

  A:基础速度太高或者PID响应不够快。降低基础速度或增大Kp。

  Q:传感器读数不稳定?

  A:传感器高度调整到离地面约5-10mm。反光强的地面可能需要调节传感器上的电位器调灵敏度。

跑跑啦航模详情

联系手机15058675618 qq售后群号241350086 微信号paopaola_com
长距离FPV无人机,高清传感器模块,终身保修和升级服务。