项目总结报告
项目功能介绍
这个项目制作的是一个利用PID算法来控制温湿度的简单系统,其中能通过lcd屏幕显示设定的温度与当前温度,两个按钮能分别控制设定温度的升高和降低,其中加热电阻来调节温度。
设计思路
本系统采用的是“搭配带屏12指神探的传感器扩展板”。对于温度的控制,采用的算法是位置环PID算法,通过nsht30采集实时的温湿度数据进行反馈,最后由加热电阻进行温度的控制。为了具有更好的人机交互性,LCD屏幕可显示当前温度与目标温度,还可以通过按钮调节设定温度。
硬件框图
软件流程图
硬件介绍
搭配带屏12指神探的传感器扩展板
采用树莓派Pico核心芯片RP2040
- 双Arm Cortex M0+内核,可以运行到133MHz
- 264KBSRAM,板卡上外扩2MBFlash
- 性能强大、高度灵活的可编程IO(PIO)可用于高速数字接口
- 拥有2个UART、2个SPI、2个I2C、16个PWM通道以及4路12位精度ADC
- 支持MicroPython、C、C++编程
- 拖拽UF2固件至U盘的方式烧录固件,方便快捷
- TYPE-C接口用于供电和数据传输
- 一个boot按键用于进入boot模式
- 两个可程控按键和一个拨轮用于自定义功能
- 搭载240*240分辨率的LCD彩屏,通过SPI接口进行通信,控制器为常用的ST7789芯片,例程丰富便于开发
- 扩展接口包含5v、3.3v输出、GND。9个GPIO,可同时使能最多三个通道ADC
st7789芯片控制的oled屏幕
ST7789S是一款用于262k彩色、图形型TFT-LCD的单片机控制器/驱动程序。它由720个组成源线和320门线驱动电路。这个芯片能够直接连接到外部微处理器,并接受8位/9位/16位/18位并行接口。显示数据可以存储在片上显示数据的RAM为240x320x18位。它可以执行无显示数据的RAM读/写操作外部操作时钟,最大限度地减少功耗。此外,由于集成电源驱动液晶所需的电路;用最少的元件制造一个显示系统是可能的。
IRM-H638T红外接收探头
红外接收头它采用最新的集成电路技术开发和设计的DIP型红外雷达,为大多数常见的红外协议提供了兼容性。
PIN二极管和前置放大器被组装在一个引线框架上,模压成一个黑色的环氧封装,作为一个红外滤光片。
经解调的输出信号可由微处理器直接解码.
产品特性:反映速度快、不受可见光影响、无铅化制程、符合RoH规范。
工作电压:2.7V~5.5V
工作电流:500uA
接收距离:5m
中心频率:38kHz
接收角度:±40°@水平;±40°@垂直
LTR-381RGB环境光传感器
LTR-381RGB-WA 集成的低压I2C环境光传感器(ALS)和彩色传感器
随着先进的RGB彩色传感器,该传感器将光(红色,绿色,蓝色和IR)转换为直接I2C接口的数字输出可捕获信号。 ALS在广泛的动态范围内提供线性响应,并且非常适合在非常低或明亮的环境亮度下应用。 传感器具有可编程中断,具有响应事件的系统,因此需要将传感器移除以读取系统效率。 此CMOS设计和工厂设置一时间修剪能力最小传感器对传感器的变化,以便向最终客户提供可制造性。
CC6201ST霍尔传感器
CC6201是一颗微功耗、高灵敏度全极性、并具有闩锁输出的霍尔开关传感装置,可直接取代传统的磁簧开关。特别适用于使用电池电源 的便携式电子产品,如行动电话、无绳电话、笔记型电脑、PDA等。 CC6201具有磁场辨别全极性,亦即只要磁场北极或南极靠近即可启动,磁场撤消后,输出便关闭。与其他一般霍尔传感装置不同的是并 不要特定南极或北极才可以动作,减少了组装时辨别磁极的困扰。产品采用了动态失调消除技术,该技术能够消除由封装应力,热应力,以及 温度梯度所造成的失调电压,提高器件的一致性。 CC6201内部电路包含了霍尔薄片、电压稳压模块、信号放大处理模块、动态失调消除模块、锁存模块以及CMOS输出级。由于CC6201 使用先进的Bi-CMOS 工艺,整体优化了的线路结构,使得产品获得极低的输入误差反馈。同时该产品采用及其小型化的封装工艺,使得产品 更具极高的性能和市场优势。 CC6201提供TSOT23-3和TO-92S两种封装,工作温度范围为-40~150℃。
实现的功能
系统预设的控制温度为25度,可通过两个按钮升高或降低设定温度,oled屏幕上会显示当前的温湿度和设定的温度。
图片展示
初始状态
加热中
重要代码片段
PID控制算法
class PID():
def __init__(self, dt, max, min, Kp, Ki, Kd):
self.dt = dt # 循环时长
self.max = max # 操作变量最大值
self.min = min # 操作变量最小值
self.Kp = Kp # 比例增益
self.Ki = Ki # 微分增益
self.Kd = Kd # 积分增益
self.integral = 0 # 直到上一次的误差值
self.pre_error = 0 # 上一次的误差值
def calculate(self, setPoint, pv):
# 其中 pv:process value 即过程值,
error = setPoint - pv # 误差(设定值与实际值的差值)
Pout = self.Kp * error # 比例项 Kp * e(t)
self.integral += error * self.dt #∑e(t)*△t
Iout = self.Ki * self.integral # 积分项 Ki * ∑e(t)*△t
derivative = (error - self.pre_error) / self.dt #(e(t)-e(t-1))/△t
Dout = self.Kd * derivative # 微分项 Kd * (e(t)-e(t-1))/△t
output = Pout + Iout + Dout # 新的目标值 位置式PID:u(t) = Kp*e(t) + Ki * ∑e(t)*△t + Kd * (e(t)-e(t-1))/△t
if (output > self.max):
output = self.max
elif (output < self.min):
output = self.min
self.pre_error = error # 保存本次误差,以供下次计算 e(k-1) = e(k)
return output
pid = PID(0.1, 100, 0, 0.1, 0.5, 0.01)
读取温湿度
# 设置I2C总线
i2c = machine.I2C(0, scl=machine.Pin(21), sda=machine.Pin(20))
# nsht30传感器的地址
nsht30_addr = 0x44
# 发送命令以获取温湿度数据
i2c.writeto(nsht30_addr, bytes([0xf3]))
# 等待传感器准备好数据
time.sleep(0.1)
# 读取温湿度数据
data = i2c.readfrom(nsht30_addr, 6)
time.sleep(0.1)
# 解析温湿度数据
temperature = round(((data[0] << 8) | data[1]) * 175 / 0xffff - 45,1)
humidity = round(((data[3] << 8) | data[4]) * 100 / 0xffff,1)
LCD屏幕显示
spi = SPI(0, baudrate=40_000_000, polarity=1, phase=0, sck=Pin(18,Pin.OUT), mosi=Pin(19,Pin.OUT))
display = st7789.ST7789(spi, 240, 320,
reset=Pin(0, Pin.OUT),
dc=Pin(1, Pin.OUT),
cs=Pin(4, Pin.OUT),
backlight=Pin(16, Pin.OUT),
color_order = st7789.RGB,
inversion = False,
rotation = 0)
display.init()
display.text(font, "present humidity:",10, 25, st7789.WHITE)
遇到的主要难题及解决方法
- 发现扩展板无法进入boot模式解决方法:需要先按下reset键再进行供电,出现u盘后再松开
- oled屏幕无法驱动,不会显示英文解决方法:在GitHub上下载st7789的驱动库包后烧录到pico上,调整代码参数
- oled屏幕显示的文字是相反的解决方法:将rotation的参数改为0
未来功能的改进
目前只能通过加热电阻实现温度的升高,但无法实现温度降低的调节。未来可连接四线风扇,通过pwm调节风扇转速的方式来降低环境温度。此外,湿度的调节目前也无法实现。未来可能需要外加水泵。