任务要求
使用用搭配带屏12指神探的传感器扩展板实现一个恒温控制系统
- 至少使用一种自控算法控制,如PID等
- 可用按键或拨轮控制目标温度
- 可在LCD屏上显示目标温度及实时温度
一、基本介绍
1.thonny:
这算是一个轻量化的python开发平台,适合有python开发经验以及python初学者使用,安装配置非常简单,根据提供的链接参考自己的操作系统选择并进行安装就可以了:Thonny软件:https://thonny.org/
2.硬禾学堂2024寒假在家练平台:
寒假在家练活动涵盖了数十个平台,我出于对传感器的兴趣,选择了其中的搭配带屏12指神探的传感器扩展板平台,它的管脚图如下所示:
更详细的平台介绍可以参见https://www.eetree.cn/platform/2590
二、环境配置
程序使用micropython编写、对于有python开发经验的人来说不算难事。
要让显示屏发挥功能,首先需要下载现成的st7789库,我是直接在https://www.eetree.cn/platform/2590#heading-3
链接中的附件部分下载了带屏十二指神探测试包,根据其中的教程文档进行调试的。
在识别板卡完成、导入显示屏需要的库之后,在thonny中能看见板卡中的文件,对其进行编辑即可实现想达到的功能。
最后在基本功能实现时,我的板卡区域显示如图:
三、代码解释
我的代码主要分为两个部分,sht30.py与main.py
先从sht30.py部分说起
from machine import I2C,Pin
import utime
class SHT30:
def __init__(self):
self.sensor = I2C(0, scl=Pin(21), sda=Pin(20))
self.addr = 0x44
self.read_temp_hum_cmd = b'\x2c\x10'
def measure(self):
self.sensor.writeto(self.addr, self.read_temp_hum_cmd)
utime.sleep(0.1)
data = self.sensor.readfrom(self.addr, 6)
temp_raw = (data[0] << 8 | data[1])
humidity_raw = (data[3] << 8 | data[4])
temperature = temp_raw * 175 / 65535 - 45
humidity = humidity_raw * 100.0 / 65535
return temperature, humidity
在这部分代码中,定义了一个SHT30传感器,以供主函数中调用作为传感器功能使用。
main.py文件的内容如下所示:
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, ADC,PWM
import time, math,array
from utime import sleep_ms
import struct
from sht30 import SHT30
sensor = SHT30()
temperature,humidity = sensor.measure()
set_temp = 30
integral = 0
previous_error = 0
heater_pin = Pin(22,Pin.OUT)
heater_pwm = PWM(heater_pin)
heater_pwm.freq(1000)
pwm = PWM(Pin(19))
pwm.freq(50)
#image_file0 = "/logo.bin" #图片文件地址
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)
# xAxis = ADC(Pin(28))
# yAxis = ADC(Pin(29))
buttonM = Pin(5,Pin.IN, Pin.PULL_UP) #B
buttonS = Pin(6,Pin.IN, Pin.PULL_UP) #A
buttonL = Pin(7,Pin.IN, Pin.PULL_UP) #A
buttonPRESS = Pin(8,Pin.IN, Pin.PULL_UP) #A
buttonR = Pin(9,Pin.IN, Pin.PULL_UP) #A
'''
f_image = open(image_file0, 'rb')
for column in range(1,240):
buf=f_image.read(480)
display.blit_buffer(buf, 1, column, 240, 1)
'''
def pid_control(kp,ki,kd,set_temp,current_temp):
global previous_error, integral
error = set_temp - current_temp
integral = max(min(integral + error, 50), -50)
derivative = error - previous_error
output = kp * error + ki * integral + kd * derivative
previous_error = error
return max(min(output,100), 0)
while True:
# xValue = xAxis.read_u16()
# yValue = yAxis.read_u16()
sensor = SHT30()
temperature,humidity = sensor.measure()
buttonValueM = buttonM.value()
buttonValueS = buttonS.value()
buttonValueL = buttonL.value()
buttonValuePRESS = buttonPRESS.value()
buttonValueR = buttonR.value()
# display.text(font1, "xVaule="+"%05d" %(xValue) , 10, 70)
# display.text(font1, "yVaule="+"%05d" %(yValue), 120, 70)
display.text(font2, "pid control", 10, 0)
display.text(font1, "buttonValueM="+str(buttonValueM), 10, 60)
display.text(font1, "buttonValueS="+str(buttonValueS), 10, 80)
display.text(font1,"buttonValueL="+str(buttonValueL) , 10, 100)
display.text(font1, "buttonValuePRESS="+str(buttonValuePRESS), 10, 120)
display.text(font1, "buttonValueR="+str(buttonValueR), 10, 140)
display.text(font1, "current_temperature="+str(temperature),10,160)
display.text(font1, "set_temperature="+str(set_temp),10,180)
if buttonValueM == 0 or buttonValueL == 0:
set_temp = set_temp - 1
elif buttonValueS == 0 or buttonValueR == 0:
set_temp += 1
elif buttonValuePRESS == 0:
set_temp = 30
pid = pid_control(28,0.1,5,set_temp,temperature)
heater_pwm.duty_u16(int((pid/100.0)*65535))
time.sleep(0.2)
四、效果展示
通过对温度进行调整并观察数据可以发现,该平台的恒温控制系统具有加热功能,但会出现过冲的情况(加热太多);而对于降温,则只能依靠室温缓慢下降。在一定波动范围内,实际温度可以在预设温度的±0.05°范围内波动
总得来说,使用PID自动算法能够基本实现功能,在可接受的误差范围与等待时间内完成温度的自动调节。