项目介绍
本项目是使用硬禾学堂推出的活动“2022寒假在家一起练”设计的基于树莓派RP2040的嵌入式系统学习平台,通过该平台上的240*240显示屏,按键,摇杆以及RP2040芯片的温度传感器实现温度计,具有图形化显示、超温报警功能。
项目任务要求
- 在LCD屏上显示一个图形化的温度计,并实时显示当前的温度(通过RP2040内部的温度传感器测量)
- 通过摇杆或按键设定报警温度阈值并显示报警温度数值
- 温度超过设定的阈值,温度图示颜色变红,且蜂鸣器发出报警声音
- 给芯片降温到阈值以下,温度传感器颜色变绿,蜂鸣器停止报警
项目环境配置
1.Thonny集成开发环境
2.硬禾学堂基于树莓派RP2040的嵌入式系统学习平台
平台介绍:https://www.eetree.cn/project/detail/698
平台固件:程序依赖的相关库需要烧写硬禾学堂的固件mpy-sge-pmrn-v20220118.uf2:
固件地址: https://gitee.com/eetree-git/RP2040_Game_Kit
固件烧录方法:
1.将板卡连接电脑,在板卡关机状态按B键并打开开关开机
2.待电脑识别磁盘RPI-RP2,将固件复制至根目录即可
项目完成功能
- 使用240*240液晶显示屏显示实时温度计图形,报警温度,实时温度,文字,并以不同的刷新率显示更新数据。实时温度标有CURRENT TEMP字样,报警温度标有ALARM TEMP字样。
- 使用摇杆ADC采样对报警滑块操作,按键按下开启报警,显示SET字样,再按下按键关闭报警,SET字样消失。
- 当开启报警,超过报警温度时实时温度计显示红色,蜂鸣器报警;小于报警温度或关闭报警温度计显示绿色,蜂鸣器关闭。
显示界面
项目设计思路
根据项目任务要求,将本项目分为:实现图形绘制:温度计图形绘制,报警滑块图形绘制;温度获取:当前温度获取,报警温度获取;报警设定:报警按键逻辑,报警蜂鸣器逻辑。
图形绘制使用的是固件的BreakoutColourLCD240x240库驱动显示屏。该库函数已配置好相关参数,调用相关函数并采用局部刷新方法实现图形更新。使用两个Timer定时器分别对实时温度显示,报警温度显示实现不同的刷新率。
温度获取使用ADC采样RP2040温度传感器,转换得到实时温度。而报警温度是通过对摇杆的状态检测,对报警温度增减。
报警设定主要是检测按键是否按下,若按下按键,则开启报警,若再次按下按键,关闭报警。报警滑块根据游戏杆状态改变滑块位置,通过比较实时温度和报警温度值判断是否使能蜂鸣器,蜂鸣器通过PWM驱动。
项目程序流程图
项目主要程序实现
图形刷新是在每次调用绘制函数时,刷新图形。以温度计绘制为例,在程序初始化,先绘制一个完整的温度计,采样温度,然后再绘制变化的区域覆盖原来的图形,达到温度计变化的效果。实时温度数字,报警温度滑块也按照类似方法。不同的周期刷新效果由定时器实现。图形颜色变化通过一个数组变量color传参。
#timer1初始化,以1Hz刷新温度计绘制
timer1.init(freq=1, mode=Timer.PERIODIC, callback=lambda t:display_change(round(get_temp(),1), color))
#timer2初始化,以10Hz刷新报警游标绘制
timer2.init(freq=10, mode=Timer.PERIODIC, callback=lambda t:alarm_change())
#温度变动绘制以及实时温度刷新
#temp 变动温度至temp
#color 温度计颜色数组 [R,G,B]
#current_temp 当前温度
def display_change(temp, color):
global current_temp
current_temp = temp
#print(temp)
display.set_pen(color[0], color[1], color[2])
display.rectangle(58,30,13,160)
display.circle(64,190,10)
display.set_pen(0,0,150)
display.rectangle(58,20,13,7+int((50-temp)/2)*6)
display.set_pen(0,0,0)
display.rectangle(150,50,90,40)
display.set_pen(0,255,0)
display.text(str(temp), 150, 50, 5, 5)
display.update()
温度获取使用ADC采样RP2040的温度传感器,根据转换得到温度。
stemp = ADC(4)
cf = 3.3 / (65535)
def get_temp():
return 27 - (stemp.read_u16() * cf - 0.706)/0.001721
通过对摇杆采样数值的限定,根据函数返回值可以判定报警滑块移动方向。
#游戏杆y轴数据获取
#游戏杆ADC > 40000 返回 1
#游戏杆ADC < 6000 返回 -1
def get_joy_pos():
if y.read_u16() > 40000:
return 1
elif y.read_u16() < 6000:
return -1
else:
return 0
项目遇到的主要难题及解决方法
图形的刷新难点是在绘制图形时如果不刷新图形,则会导致拖影。解决方法是通过擦除的方法,先绘制更新的图形a,再绘制图形b将之前的图形a擦除掉。
报警温度和温度显示刷新率相同,导致无法更好地设置报警温度,解决方法是使用定时器,以不同的刷新率来显示。
按键判断如果只使用延时再检查按键状态的话,会导致报警函数给出的返回值不定。解决方法是使用循环,判断条件为直至按键处于非按下状态。暂时没有找到更好的方法。
#报警温度使能检测
#按下按键b,返回1, 再次按下返回-1
def alarm_get(alarm_set):
if b.value() == 0:
alarm_set *= -1
if alarm_set == 1:
display.set_pen(255,0,0)
display.text("set", 200, 135, 194, 2)
else:
display.set_pen(0,0,0)
display.rectangle(200,135,120,12)
display.update()
while b.value() == 0:
pass
return alarm_set
未来计划和建议
该项目的基本功能已实现,未来计划对该项目添加这些功能,使温度计更加智能:
1.加入网络模块,显示网络从获取的天气信息,并可以使用为物联网智能语音助手获取到温度。
2.添加温度记录功能,周期记录温度数据,将数据导入电脑可画出图像。
3.进一步优化代码,并添加温度统计图像显示。
参考资料