项目需求
• 至少使用一种自控算法控制,如PID等 • 可用按键或拨轮控制目标温度 • 可在LCD屏上显示目标温度及实时温度
完成的功能及达到的性能
2.1 使用PID算法实现温度控制
PID算法是一种常用的控制算法,用于自动调节系统的输出以使其接近期望值。PID代表比例(Proportional)、积分(Integral)、微分(Derivative),分别对应PID算法的三个部分。
• 比例(Proportional)部分根据实际输出和期望值之间的差异来产生一个调节量,用于快速响应系统输出的变化。 • 积分(Integral)部分根据实际输出和期望值之间的累积差异来产生一个调节量,用于消除系统的稳态误差。 • 微分(Derivative)部分根据实际输出的变化率来产生一个调节量,用于抑制系统的超调和振荡。
PID算法通过组合比例、积分和微分部分的调节量来调节系统输出。根据实际应用的需求,可以调节PID算法中每个部分的权重,以达到更好的控制效果。但PID调参的过程很复杂,需要不断调节参数,使其达到我们的需求。
2.2 使用拨轮控制目标温度
在这个项目中,我们使用了拨轮来控制目标温度。通过LCD屏幕实时显示目标温度,并使用PID算法控制加热电阻以使温度传感器的数值接近目标温度。通过拨轮向左滑动减小目标温度,向右滑动增加目标温度。温度的单位为0.5。
2.3 LCD屏上显示目标温度及实时温度
通过LCD屏幕实现人机交互界面,可以直观地显示温度的变化
1.先通过数据手册了解要使用的温度传感器的型号和通信协议。
2.初始化屏幕相关的函数。
3.配置拨轮相关的IO口。
4.通过PID算法控制达到目标温度。
5.实现过程
6点亮屏幕
# 导入包和字库
import test.st7789 as st7789
from test.fonts import vga2_8x8 as font1, vga1_16x32 as font2
# 初始化显示屏
spi_sck, spi_tx = Pin(2), Pin(3)
spi0 = SPI(0, baudrate=4000000, phase=1, polarity=1, sck=spi_sck, mosi=spi_tx)
display = st7789.ST7789(spi0, 240, 240, reset=Pin(0, Pin.OUT), dc=Pin(1, Pin.OUT), xstart=0, ystart=0, rotation=0)
display.fill(st7789.BLACK)
拨轮控制
# 配置拨轮
buttonM = Pin(5, Pin.IN, Pin.PULL_UP)
buttonS = Pin(6, Pin.IN, Pin.PULL_UP)
温度传感器
根据数据手册,我们了解到温度传感器使用的是IIC协议。
# 导入库文件
from machine import Pin, SPI, PWM, I2C
# 温度湿度相关读取操作
def read_sht30():
i2c.writeto(0x44, b'\x2C\x06') # 写入对应的地址
time.sleep(0.5) # 缓冲一段时间
data = i2c.readfrom(0x44, 6) # 读取存放温度湿度的寄存器
if len(data) == 6: # 读取到寄存器的长度达到
temp = -45 + (175 * (data[0] << 8 | data[1]) / 65535.0) # 通过手册运算得出温度
humidity = 100 * ((data[3] << 8 | data[4]) / 65535.0) # 通过手册运算得出湿度
return temp, humidity
return None, None
PID计算
def pid_control(set_point, measured_value):
global last_error, integral
error = set_point - measured_value # 计算目标的未达到温度的累计值
integral = max(min(integral + error, 50), -50) # 限制温度的累计值
derivative = error - last_error
output = Kp * error + Ki * integral + Kd * derivative # 通过PID计算得出最后的控制数据
last_error = error # 更新累计值
return max(min(output, 100), 0) # 限制输出范围为0-100
通过显示屏函数实现对屏幕的操作
# 保留小数点后一位,观察PID调节的效果
def update_display(temperature, humidity, set_point):
display.text(font2, "PID", 10, 10)
display.text(font1, "Temperature:={:.1f} C".format(temperature), 10, 90)
display.text(font1, "Humidity:={:.1f} %".format(humidity), 10, 110)
display.text(font1, "Set Temp: {:.1f} C".format(set_point), 10, 130)
通过拨轮实现对目标温度的控制
通过左右拨轮实现对目标温度的调节。
def adjust_set_point(buttonM, buttonS, set_point, step=0.5):
if not buttonM.value():
set_point += step
time.sleep(0.1) # 去抖延迟
if not buttonS.value():
set_point -= step
time.sleep(0.1) # 去抖延迟
return set_point
通过循环不断更新显示数据
通过PID控制PWM波,实现控制占空比来快速达到目标温度,并保持目标温度的效果。
while True:
temperature, humidity = read_sht30()
output = pid_control(set_point, temperature)
heater_pwm.duty_u16(int((output / 100.0) * 65535))
set_point = adjust_set_point(buttonM, buttonS, set_point)
update_display(temperature, humidity, set_point)
程序流程图
实现功能
我们可以看加热电阻不断通过PID调节保持目标温度
3. 项目总结
1. 遇到的主要难题这是我第一次用micropython开发程序,其中遇到许多问题,最让人头大便是PID参数的调节,因为要保持在一定范围内控制,调参数就是老大难的问题,最后调节到一个令自己比较算满意的结果。
2. 未来的计划经过这次项目训练,让我认识到micropython开发的乐趣,也认识到主控树莓派Pico核心芯片RP2040,可以调用的乐趣,希望自己以后在需要用其他外设联动的时候,能多使用RP2040,来解决一些问题。