寒假练项目总结报告
1. 项目介绍
此项目为硬禾科技举办的2024寒假练活动,我的项目是基于平台4-搭配带屏12指神探的传感器扩展板的恒温或恒湿控制系统。该项目主要是通过利用传感器扩展板上的温湿度传感器模块以及加热电阻,使用PID自控算法控制温度达到设定温度,并在LCD屏上实时显示目标温度与实时温度。
2. 硬件介绍
此次实验平台是平台4-搭配带屏12指神探的传感器扩展板,带屏版的12指神探,是在原板基础上,配备了一块240*240分辨率的LCD彩屏以及两个可程控按键和一个拨轮,丰富了人机交互功能,方便信息观察、界面切换等使用方式。这个模块是通过Type C的USB接口提供供电、下载以及通信的功能,板上有5V转3.3V,最高支持800mA的电压变换器,在12根引脚上也将5V和3.3V引出,方便对其它外设板供电。
- 主控芯片:采用树莓派Pico核心芯片RP2040
- 双Arm Cortex M0+内核,可以运行到133MHz
- 支持MicroPython、C、C++编程
作为12指神探的传感器扩展板,接口完全适配,正确方向插入后即可使用。扩展板搭载了几款常见传感器和功能模块,包括为初学者准备的麦克风、蜂鸣器、红外收发、霍尔效应开关、加热电阻,为进阶操作准备的温湿度传感器、六轴传感器、接近/环境光/IR传感器、颜色传感器。其中温湿度传感器、六轴传感器、接近传感器、颜色传感器可拆卸为单个模块,通过杜邦线等连接线延伸其使用的空间范围。
本项目中主要使用到的硬件部分有带屏12指神探,以及扩展板上的温湿度传感器以及加热电阻。
3. 设计思路
为了实现温度控制以及实时显示,我们首先需要将温湿度传感器模块以及LCD显示屏正确驱动。LCD屏的驱动可以使用板卡自带固件中提供的 st7789.py
库将其驱动,以实现基本的文字显示功能。温湿度传感器 NSHT-30
则可以通过查看该传感器的官方说明手册编写。该传感器驱动是通过使用 I²C
总线实现命令的发送与数据的读取。将LCD屏与温湿度传感器正确驱动后,就可以实现在屏幕上实时显示当前温度值了。接下来我们需要实现加热电阻的加热功能以及其温度控制功能。我们设计使用PWM来实现对加热电阻不同加热强度的控制,使用PID算法的输出作为加热电阻PWM的占空比来讲温度稳定到目标温度。在完成上述目标功能后,再添加一些按键的交互功能,一个可以调节设定温度的恒温控制系统就设计完成了。
软件流程图如下:
4. 主要代码展示
- PID控制算法:
class PIDController:
def __init__(self, Kp, Ki, Kd, setpoint=40):
self.Kp = Kp
self.Ki = Ki
self.Kd = Kd
self.setpoint = setpoint
self.last_error = 0
self.integral = 0
def compute_output(self, measurement):
error = self.setpoint - measurement
self.integral += error
derivative = error - self.last_error
output = self.Kp * error + self.Ki * self.integral + self.Kd * derivative
self.last_error = error
output *= 0.1
output = max(0, min(output, 1))
return output
def update_setpoint(self, newpoint):
self.setpoint = newpoint
我们可以看到在PID控制器类中我们定义了三个方法,一个是初始化的构建方法,一个是计算PID输出的方法,一个是修改设定点的方法。使用PID控制器类的对象并对其进行参数初始化,就可以实现对加热电阻加热功率的有效控制。为了优化PID算法的实用效果,可以自行修改Kp、Ki、Kd三个参数的值。
- I²C通信代码:
def send_cmd(self, cmd_request, response_size=6, read_delay_ms=25):
try:
self.i2c.writeto(self.i2c_addr, cmd_request)
if not response_size:
return
time.sleep_ms(read_delay_ms)
data = self.i2c.readfrom(self.i2c_addr, response_size)
for i in range(response_size//3):
if not self._check_crc(data[i*3:(i+1)*3]): # pos 2 and 5 are CRC
raise NSHT30Error(NSHT30Error.CRC_ERROR)
if data == bytearray(response_size):
raise NSHT30Error(NSHT30Error.DATA_ERROR)
return data
except OSError as ex:
if 'I2C' in ex.args[0]:
raise NSHT30Error(NSHT30Error.BUS_ERROR)
raise ex
这是用于与温湿度传感器通过I²C总线通信的代码部分,这部分包括了I²C的命令发送、数据接收以及CRC校验功能,这些是读取温度传感器温度的基本操作。
- 温度测量方法:
def measure(self, raw=False):
data = self.send_cmd(NSHT30.MEAS_SINGLE_H_CMD, 6)
if raw:
return data
t_celsius = (((data[0] << 8 | data[1]) * 175) / 0xFFFF) - 45 + self.delta_temp
rh = (((data[3] << 8 | data[4]) * 100.0) / 0xFFFF) + self.delta_hum
return t_celsius, rh
在传感器的测量方法中,首先使用I²C协议发送单次测量的指令MEAS_SINGLE_H_CMD(0x2400),并读取6个字节的经过CRC校验的回传数据。然后利用说明手册中给出的公式对测量结果进行换算,最终返回温湿度测量值。
5. 功能演示
- 对板子上电后,默认的设定温度为40℃,加热功能默认关闭,此时屏幕上显示当前温度的实时测量值。
- 当我们按下上方左侧按钮后,加热功能开启,当前温度低于设定温度,可以看到拓展板上的加热警告灯亮起,在一小段时间的温度波动后,我们可以看到实时温度已稳定在设定的默认温度40℃下。
- 通过使用上方右侧的拨轮可以调节当前设定的目标温度。向右侧拨动可以增高目标温度,向左侧拨动可以降低目标温度。按下拨轮可以将温度恢复到默认的设定温度40℃。
视频演示详见链接。
6. 未来计划
- 本项目只实现了温度的测量以及恒温控制,可以在后续工作中添加湿度测量的功能,在温湿度传感器的驱动文件中已经将温湿度测量的结果返回接口写好了,只是目前只用了其中温度的值。
- 界面还不够美观,仅实现了基本的显示功能,可以考虑加入温湿度折线图或更换UI来使界面更直观、美观。