1 项目需求
- 至少使用一种自控算法控制,如PID等
- 可用按键或拨轮控制目标温度
- 可在LCD屏上显示目标温度及实时温度
带屏版的12指神探,它是在原板基础上,配备了一块240*240分辨率的LCD彩屏以及两个可程控按键和一个拨轮,丰富了人机交互功能,方便信息观察、界面切换等使用方式。此外还配备了白色外壳,精心设计的包装不仅使板卡日常使用时更加美观也便于板卡的站立以及使用安全。
这个模块是通过Type C的USB接口提供供电、下载以及通信的功能,板上有5V转3.3V,最高支持800mA的电压变换器,在12根引脚上也将5V和3.3V引出,方便对其它外设板供电。
主控芯片:采用树莓派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
应用场景:
- 逻辑分析仪、daplink、电压电流表、
- 协议发生器、多功能控制切换
- DIY扩展板:信号发生器、高速数据采集、桌面天气时钟小组件、智能家居总控台
开发环境:
- Micropython:简单易学、资料丰富、例程繁多,适用于初学者快速上手及使用
- C/C++:语句效率更高,适合发挥RP2040更极致的性能
- Arduino:有适配RP2040芯片的扩展包,方便c语言上手开发
12指神探的管脚定义:
传感器扩展板:
作为12指神探的传感器扩展板,接口完全适配,正确方向插入后即可使用。扩展板搭载了几款常见传感器和功能模块,包括为初学者准备的麦克风、蜂鸣器、、红外收发、霍尔效应开关、加热电阻,为进阶操作准备的温湿度传感器、六轴传感器、接近/环境光/IR传感器、颜色传感器。其中温湿度传感器、六轴传感器、接近传感器、颜色传感器可拆卸为单个模块,通过杜邦线等连接线延伸其使用的空间范围。出厂默认传感器正面朝上使用。若需背面朝上使用,则自行焊接排母后按指示方向插入。
2 完成的功能
2.1 硬件部分:
- 使用了ST7789显示屏来显示温度、湿度以及控制信息。
- 通过PWM控制器控制一个设备(可能是加热器或风扇)以调节温度。
- 使用了SHT30传感器来测量温度和湿度。
- 通过三个按钮(buttonL、buttonPRESS、buttonR)来调节设定的目标温度。
2.2软件部分:
- 实现了一个PID控制算法来根据当前温度与设定温度之间的偏差来调节PWM输出,以达到控制温度的目的。
- 通过I2C协议与SHT30传感器通信,读取温度和湿度数据。
- 在显示屏上实时显示当前温度、湿度、设定温度以及按钮状态信息。
- 通过按钮来调节设定的目标温度,并在设定温度超出范围时在显示屏上显示相应提示信息。
2.3PID控制算法:
- 根据当前温度与设定温度之间的偏差,计算出P(比例)、I(积分)和D(微分)三个部分的调节量。
- 根据这三个部分的调节量,调整PWM输出,控制设备的工作状态,以使实际温度逐渐接近设定温度。
3 实现思路
初始化设置:
- 首先进行了必要的引入库和模块的操作,包括引入各种需要的库和模块,初始化SPI、PWM、I2C等硬件设备,并设置显示屏等参数。
读取温度和湿度数据:
- 定义了一个read_sht30()函数,通过I2C通信与SHT30传感器进行交互,发送测量命令并读取返回的温度和湿度数据。
PID控制算法:
- 在一个循环中,不断读取当前的温度和湿度数据,然后根据当前温度与设定温度之间的偏差,计算出PID控制算法中的P、I、D三部分的调节量。
- 根据这三部分的调节量,调整PWM输出的占空比,控制设备的工作状态,以实现温度的调节。
按钮控制设定温度:
- 在循环中检测按钮的状态,根据按钮的按下情况来调节设定的目标温度。
- 当按下左按钮时,目标温度减小;当按下右按钮时,目标温度增加。同时,限制设定温度的范围在0到80之间。
显示屏显示信息:
- 在显示屏上实时显示当前温度、湿度、设定温度以及按钮状态信息,以便用户了解系统的工作状态和参数设置情况。
PID控制:
- 在PID控制算法中,设定了P、I、D三个参数的值,根据当前偏差和历史偏差的变化来调节PWM输出,使得设备工作状态能够根据实际情况进行调节。
利用Thonny实现设计。
Thonny自带RP2040解释器,较为简单上手。
利用电子森林AI助手,可以生成简单python代码,大大减少设计时间,提高效率。
4 实现过程
4.1 软硬件框图图
4.2 引入库和模块
在代码中引入库和模块是为了扩展代码的功能和利用已有的功能模块。在这个温度控制系统中,引入库和模块的目的是为了实现与硬件设备的交互、数据处理和显示等功能。
引入库:
- 引入库通常是指导入外部的函数和类库,以便在代码中使用其中定义的函数和类。这些库可以包含各种功能,如控制硬件设备、数据处理、显示等。
- 在这个系统中,可能会引入各种库,比如SPI库用于SPI通信、PWM库用于PWM控制、I2C库用于I2C通信、显示屏库用于显示屏控制等。
引入模块:
- 引入模块通常是指导入自定义的模块文件,以便在代码中使用该模块中定义的函数和类。模块可以帮助组织代码、提高代码的可维护性和复用性。
- 在这个系统中,可能会自定义一些模块,比如温度传感器模块、PID控制模块、按钮控制模块等,然后在主程序中引入这些模块来实现相应的功能。
- 通过引入库和模块,可以使代码更加模块化、清晰和易于维护。这样的设计方法有助于降低代码的复杂度,提高代码的可读性和可扩展性,使系统更易于理解和维护。
import uos
import test.st7789 as st7789
from test.fonts import vga2_8x8 as font1
from test.fonts import vga1_16x32 as font2
import random
import framebuf
from machine import Pin, SPI, I2C,ADC,PWM
import time, math,array
from utime import sleep_ms
import struct
4.3 初始化设备
目的:
- 初始化为后续的应用程序或控制逻辑提供了硬件基础。
内容:
- 初始化两个PWM对象,用于控制设备的PWM输出。
- 初始化SPI总线对象,用于与显示屏通信。
- 初始化ST7789显示屏对象,设置显示屏参数。
- 使用SPI总线和显示屏对象清空显示内容。
- 初始化三个按钮对象,连接到不同引脚并使用上拉电阻。
pwm = PWM(Pin(19))
pwm.freq(50)
re = PWM(Pin(22))
st7789_res = 0
st7789_dc = 1
disp_width = 240
disp_height = 240
CENTER_Y = int(disp_width/2)
CENTER_X = int(disp_height/2)
spi_sck=Pin(2)
spi_tx=Pin(3)
spi0=SPI(0,baudrate=4000000, phase=1, polarity=1, sck=spi_sck, mosi=spi_tx)
display = st7789.ST7789(spi0, disp_width, disp_width,
reset=machine.Pin(st7789_res, machine.Pin.OUT),
dc=machine.Pin(st7789_dc, machine.Pin.OUT),
xstart=0, ystart=0, rotation=0)
display.fill(st7789.BLACK)
buttonL = Pin(7,Pin.IN, Pin.PULL_UP) #调低
buttonPRESS = Pin(8,Pin.IN, Pin.PULL_UP)
buttonR = Pin(9,Pin.IN, Pin.PULL_UP) #调高
duty=0
target_temp=20
offset=0 #e(k)
offset1=0 #e(k-1)
offset2=0 #e(k-2)
p=10 #PID参数
i=2
d=0
4.4 读取SHT30传感器
通过I2C总线与SHT30传感器通信,读取温度和湿度数据,并返回这些数据。
实现方式包括以下步骤:
- 定义SHT30传感器的I2C地址和读取温度湿度的命令。
- 通过I2C总线向SHT30传感器发送测量命令。
- 延时等待传感器完成测量。
- 从传感器读取6个字节的数据,包括温度、湿度和各自的校验值。
- 根据读取的数据计算温度和湿度数值。
- 返回计算得到的温度和湿度数值。
def read_sht30():
# 定义SHT30的I2C地址
SHT30_I2CADDR = 0x44
# 定义读取温度和湿度的命令
CMD_MEASURE = bytearray([0x24, 0x00])
# 向SHT30发送测量命令
i2c.writeto(SHT30_I2CADDR, CMD_MEASURE)
# 延时等待测量结果
time.sleep(0.015)
# 读取测量结果,共6字节,包含温度、湿度和各自的校验值
data = i2c.readfrom(SHT30_I2CADDR, 6)
# 计算温度和湿度
temp = -45 + 175 * ((data[0] << 8 | data[1]) / 65535)
temp = round(temp, 2)
humidity = 100 * ((data[3] << 8 | data[4]) / 65535)
humidity = round(humidity, 2)
return temp, humidity
#创建I2C对象
i2c = I2C(id=0,scl=Pin(21),sda=Pin(20),freq=100_000)
4.5 主函数
通过PID控制算法根据温度偏差调节PWM输出控制设备,同时可以通过按钮调节设定温度,并在LCD显示屏上实时显示温度、湿度以及控制信息,实现了实时监测和调节温度的功能。
功能:
- 读取温度和湿度:
- 使用
read_sht30()
函数读取当前温度和湿度数据。 - 将读取到的温度和湿度数据打印输出。
- 使用
- 温度控制:
- 根据目标温度和当前温度计算温度偏差。
- 根据PID控制算法计算出控制量的调节值。
- 根据调节值调整PWM输出的占空比,控制温度设备的加热或冷却。
- 限制PWM占空比在0到1023之间。
- 温度设定:
- 通过按钮控制可以增加或减少目标温度。
- 当目标温度超过80摄氏度时,显示"over",并限制目标温度为80摄氏度。
- 当目标温度低于0摄氏度时,显示"less",并限制目标温度为0摄氏度。
- 按钮状态显示:
- 实时显示左右按钮和按压按钮的状态。
- 在LCD上显示当前温度、湿度以及设定的目标温度。
工作方式:
- 在一个无限循环中,不断读取温度和湿度数据,并进行温度控制和按钮操作的处理。
- 持续监测温度偏差,并根据PID控制算法调整控制量,实现温度的自动调节。
- 通过按钮控制可以手动调节目标温度,并在LCD上实时显示各种状态信息。
temp, humidity = read_sht30()
print('温度: '+str(temp)+', 湿度: '+str(humidity))
offset2=offset1 #记录上一次偏差
offset1=offset
offset=target_temp-temp
adjustmentP=offset-offset1
adjustmentP*=p
adjustmentI=offset
adjustmentI*=i
adjustmentD=offset-offset1-offset1+offset2
adjustmentD*=d
adjustment=adjustmentP+adjustmentI+adjustmentD
duty+=adjustment
if duty<0:
duty=0
elif duty>1023:
duty=1023
re.duty_u16(int(duty*65536/1023))
print(target_temp,temp,offset,duty)
time.sleep(0.02)
if(buttonR.value()==0):
target_temp=target_temp+1
if(target_temp>80):
target_temp=80
display.text(font2, 'over ', 10, 100)
else:
display.text(font2, ' ', 10, 100)
if(buttonL.value()==0):
target_temp=target_temp-1
if(target_temp<0):
target_temp=0
display.text(font2, 'less', 10, 100)
else:
display.text(font2, ' ', 10, 100)
buttonValueL = buttonL.value()
buttonValuePRESS = buttonPRESS.value()
buttonValueR = buttonR.value()
#lcd display
display.text(font1,"buttonValueL="+str(buttonValueL) , 10, 130)
display.text(font1, "buttonValuePRESS="+str(buttonValuePRESS), 10, 150)
display.text(font1, "buttonValueR="+str(buttonValueR), 10, 170)
display.text(font2, 'temp: '+str(temp)+'*C', 10, 10)
display.text(font2, 'humi: '+str(humidity)+'%', 10, 40)
display.text(font2, 'set_tem: '+str(target_temp)+'*C', 10, 70)
5 遇到的主要难题
python运行一直报错
主要原因:
- 缩进错误:Python非常依赖于代码的缩进,确保代码块的缩进是一致的,不同代码块之间的缩进也要正确匹配。
- 语法错误:检查代码中是否有拼写错误、漏掉的冒号、括号不匹配等语法问题。
- 缺少引号:确保字符串等内容被正确地引号包围,单引号和双引号要成对出现。
- 缺少模块或库:如果代码中使用了第三方库或模块,确保这些库已经被正确安装并且可以被Python解释器找到。
6 未来的计划建议
该项目已经成功实现了温控的功能,并达到了预期指标。然而,还有许多可以提升与扩展的地方:
优化PID算法:
- 调试和优化PID参数,使系统的响应速度更快、稳定性更好,以更精确地控制温度。
- 考虑实现自适应PID控制算法,根据系统的动态特性自动调整PID参数。
增加安全功能:
- 引入温度过高或过低的报警功能,当温度超出安全范围时触发报警。
- 考虑添加自动断电保护功能,以防止温度控制系统出现故障时对设备造成损坏。
数据记录与分析:
- 添加数据记录功能,定期记录温度和湿度数据,以便后续分析和优化系统性能。
- 考虑实现数据可视化功能,通过图表展示历史数据趋势,帮助用户了解温度变化规律。