FRC慢控制系统设计文档

1 引言

1.1 编写目的

为明确FRC慢控制器软件系统结构与主要功能,特撰写本文档。

1.2 背景

本系统运行于CS32F103C8T6单片机,应用Arduino框架开发。

1.3 参考资料

https://www.st.com/resource/en/datasheet/stm32f103c8.pdf
https://www.arduino.cc/en/main/docs
https://arduinojson.org/v6/doc/

2 系统结构

2.1 系统功能

  • 根据主机发送的串口消息读写参数;
  • 输出指定占空比的PWM信号;
  • 读取输入PWM脉冲占空比;
  • PID控制;
  • Fire计数;

2.2 软件整体框架

本系统应用了ArduSensorPlatform框架。包含一个HostHost中包含多个Sensor,每个Sensor拥有一定数量的Channel。通过指定通道号即可确定需要操作的Sensor并从其中相应的Channel读取数据或将数据写入相应的Channel。主机通过CFET2DeviceProtocol协议操作及指定通道号。系统运行流程图如下:

avatar

消息格式为#{s}{r}{OP};{message};$,消息总是以#字符开头,以$字符结尾,OP为主机指定的操作,本系统仅支持SETGET两种操作。s表示消息发送方地址,r表示消息接收方地址。消息主体内容为JSON格式,通过ArduinoJson库进行解析。SET消息内容主体为{a:b, c:d, ...}形式,a、c表示通道号,b、d表示相应通道需要设定的值,若通道不支持写操作则对该通道不进行任何操作。GET消息内容主体为数组形式[a, b, c...],a、b、c、d代表通道号,数据读取完毕后将系统发送串口消息#{s}{r}PUB;{message};供主机读取,messageSET消息内容主体一样是键值对形式。接收消息在主循环中进行。

主循环接收消息的流程图如下图所示:

avatar

3 模块设计说明

3.1 PWM输出模块

3.1.1 功能

实现输出指定占空比和频率的PWM。占空比可以根据上位机指令进行更新。

3.1.2 接口

  • PwmOutPort(uint32_t pin, float frequency)

构造函数,设置输出引脚及信号频率。输出信号占空比默认为0

  • ~PwmOutPort()

析构函数

  • void Output()

输出PWM信号

  • int GetChannelNum()

读取本Sensor的Channel数目

  • int Write(int channelNo, float value)

设置输出信号占空比

3.1.3 设计思路

应用Arduino框架内置的analogWrite()函数实现PWM输出。

3.2 PWM输入模块

3.2.1 功能

计算输入的PWM信号的占空比。

3.2.2 接口

  • PwmInPort(uint32_t pin, float frequency)

指定接受PWM信号的引脚以及接收信号的频率

  • ~PwmInPort()

析构函数

  • int GetChannelNum()

  • int Update()

更新当前测得的PWM信号占空比

  • float Read(int channelNo)

返回当前测得的PWM信号占空比

  • void ISRX()

辅助测量的中断处理函数。X表示通道号,分别为0, 1, 2, 3

3.2.3 设计思路

测量主要通过中断实现。检测到信号上升沿时记录此时的时间,检测到下降沿时将此时的时间与上升沿记录的时间作差即得到高电平的持续时间,从而能够得到占空比。

Arduino框架要求中断函数必须无参数和返回值,因此无法使用PwmInPort类的成员方法作为中断函数。故设置了static函数以及相应的变量、数组作为辅助。currNum变量用于记录当前已注册的PwmInPort数量,当注册新的PwmInPortcurrNum作为当前端口在static数组中的下标并通过switch(currNum)注册相应的中断处理函数ISRX()。新端口注册完毕时currNum增1。

本系统读取的信号为温度传感器输出信号,输出信号周期为1.024ms。

3.3 PID模块

3.3.1 功能

接受主机设置的参数,进行PID控制。

3.3.2 接口

  • PidController()

构造函数。所有参数默认设置为0。

  • ~PidController()

析构函数

  • int GetChannelNum()

  • int Update()

根据pid参数及给定量、反馈量更新当前的输出。

  • float Read(int channelNo)

根据channelNo返回相应的参数,kp、ki、kd、enable、ref、feedback、output分别对应0、1、2、3、4、5、6。

  • int Write(int channelNo, float value)

根据channelNo设置相应的参数。其中output无法进行设置

3.3.3 设计思路

每次进入Update()函数,应用pid算法,结合参数更新output

位置式pid公式如下:

blockformula_editor u_{output}(t) = k_p \cdot e(t) + k_i \cdot \int_0^t e(x)dx + kd \cdot \frac{\mathrm{d}}{\mathrm{d} t} e(t)

转换成数字式:

blockformula_editor u_{o}[t] = k_p \cdot e[t] + k_i \cdot \Sigma_{i = 0}^{t} e[i] + k_d \cdot (e[i] - e[i - 1])

pid算法C++形式:

err = ref - feedback;
integral += err;
output = kp * err + ki * integral + kd * (err - lastError);
lastError = err;

3.4 Fire计数模块

3.4.1 功能

Fire操作进行计数。

3.4.2 接口

  • FireCounter(uint32_t pin)

构造函数指定计数的引脚号

  • ~FireCounter()

析构函数

  • int GetChannelNum()

  • int Update()

  • float Read(int channelNo)

返回当前的Fire计数

  • void ISRX()

辅助中断函数

3.4.3 设计思路

本模块实现思路与PidInPort类似,每次上升沿进入中断计数+1。设置static函数及变量用于辅助。

4 注意事项

  1. 本系统应用PlatformIO平台进行开发,由于开发板为STM32F103C8T6(bluepill)的仿制品,用IDE对进行程序编译、烧写和调试之前,需要对platformio.ini配置文件进行如下修改,相关路径请自行进行更改:
[env:bluepill_f103c8]
upload_flags = -c set CPUTAPID 0x2ba01477
platform = ststm32
board = bluepill_f103c8_128k
framework = arduino
upload_protocol = stlink
lib_deps = bblanchon/ArduinoJson@^6.16.1
debug_tool = stlink

debug_server =
  C:\Users\YourUsername\.platformio\packages\tool-openocd\bin\openocd.exe
  -s C:\Users\YourUsername\.platformio\packages\tool-openocd\scripts
  -f interface\stlink.cfg
  -c "transport select hla_swd"
  -c "set CPUTAPID 0x2ba01477"
  -f target\stm32f1x.cfg
  -c "reset_config none"
  1. bluepill支持PWM的引脚:PA0-PA3, PA6, PA7, PA8-PA12, PB0, PB1, PB6-PB8, PB12

本文章使用limfx的vsocde插件快速发布