附件有两个程序,一般情况烧录主程序即可。摇杆、旋转编码器出问题时烧录校准程序,测出新的阈值,在主程序里边修改下。
一、任务5的要求
- 利用热敏电阻和光传感器监测环境温度和光照强度,根据光照强度自动调节LCD字体及背景颜色。
- 利用温度传感器监测发热电阻温度变化;加热时根据温度高低,RGB LED展示不同颜色,同时产生不同频率的声音波形。
- 彩色LCD显示屏分3页展示:1、目标温度、温度传感器数据、发热驱动电路占空比;2、环境温度、温度传感器数据、光照强度;3、温度传感器的实时温度曲线图。
- 利用旋转编码器设置发热电阻的预设温度。利用拓展板上的开关控制加热启停。利用电位计切换LCD屏显示页面。
二、系统概述
本系统主要由主控模块、环境检测模块、用户交互模块和加热控制模块组成。主控模块采用TI MSPM0L1306微控制器作为核心处理单元,负责整体逻辑控制和数据处理。环境检测模块包括热敏电阻和光照传感器,用于实时监测室内温度和光照强度。用户交互模块由ST7735 LCD屏幕、电位器摇杆和旋转编码器组成,提供直观的信息展示和便捷的操作体验。加热控制模块则通过PWM波形控制加热电路的工作状态,配合NST112温度传感器实现恒温加热。
三、程序设计细节
(a) 环境检测模块
光照传感器连接MSPM0的片上运放将光照强度转换为电压信号,再通过ADC获得光照强度数值。
针对ADC外设,应当以较高采样率采集光照传感器和旋转编码器按键的数据,以较低采样率采集热敏电阻的数据。以固定ADC采样率采集这三者数据的后果是顾此失彼:要么热敏电阻数据异常,要么无法捕捉旋转编码器细微的转动。
(b)用户交互模块
① LCD屏幕显示内容:
加热时,屏幕下方显示“HEATING!”字样。
第一页:显示目标温度(用户设定的期望温度)、加热电路的实际温度、以及加热电路PWM占空比(用于反映加热功率)。这些信息帮助用户了解当前加热状态和系统的工作情况。
Goal:发热电阻目标温度;Heat:发热电路当前温度;Power:发热电阻驱动电路PWM占空比
第二页:显示当前加热电路的实际温度、室内实时温度以及光照强度数值。这些数据反映了室内环境的实时状况,为用户提供参考依据。
Room:热敏电阻温度,反映室温;Heat:发热电阻当前温度;Light:光照强度整除10的数值
第三页:实时绘制当前温度曲线图。通过曲线图,用户可以直观地看到温度的变化趋势,更好地了解室内温度的波动情况。
红色曲线表示发热电阻温度;绿色直线指示从左往右刷新,指示当前数据;左侧坐标轴单位摄氏度
② 电位器摇杆读取方式:
电位器摇杆通过直接连接GPIO引脚进行读取。当电位器摇杆上下拨动时,会改变GPIO引脚上的电平状态。统计高低电平的持续时间和比例关系来判断电位器摇杆的拨动方向,并据此切换LCD屏幕的显示内容。
③ 加热控制模块:
加热电路采用PWM波形控制其工作状态,实现温度的恒温功能。当加热温度达到预设值时,PWM占空比减小以降低加热功率;当温度低于预设值时,PWM占空比增大以提高加热功率。
加热启动时,LCD屏幕下方会显示“HEATING”字样,提醒用户当前正在加热过程中。低于目标温度时,LED红色闪烁,蜂鸣器发出连续高音;在目标温度附近时,LED绿色常亮,蜂鸣器发出间断低音;高于目标温度时,LED蓝色常亮,蜂鸣器发出连续低音。
蜂鸣器由9018三极管驱动,电路工作电压5V
四、软件设计
(a) 注意事项
必须设置O3编译优化等级,手动增加处理器的堆栈大小。
在这里改堆栈大小
考虑本项目无需处理突发事件,软件整体按照轮询方式,依次采集各传感器的信息加以分析处理,然后由相应模块执行预设动作。未使用中断。
旋转编码器的旋钮不识别转动的话,请再试几次。这项功能对旋转的力度和速度,以及电路连线接触情况,均有要求。我在视频中测试下来旋转编码器正常。如果是比赛的话,要么胶水把杜邦线固定,要么直接调完电路用电线焊死相关引脚。两种方式可以保证旋转编码器工作正常。
NST112和ST7735的驱动代码借鉴了https://www.eetree.cn/project/detail/1456,在此向作者salti-fish表示感谢。
(b) 部分代码
① 摇杆位置检测
D1=0,D2=0,D3=0;
//说明:D1+D2判断左右位置,D1/D2判断上下位置,优化等级O3在Debug模式下基本OK的
//但凡其他地方用中断,务必在中断里设置valid为0
valid=1;
while((GPIO_LEDS_PORT->DIN31_0 & GPIO_LEDS_JOYSTICK_PIN));
while((GPIO_LEDS_PORT->DIN31_0 & GPIO_LEDS_JOYSTICK_PIN)==0) ++D3;
while((GPIO_LEDS_PORT->DIN31_0 & GPIO_LEDS_JOYSTICK_PIN)) ++D2;
while((GPIO_LEDS_PORT->DIN31_0 & GPIO_LEDS_JOYSTICK_PIN)==0);
while((GPIO_LEDS_PORT->DIN31_0 & GPIO_LEDS_JOYSTICK_PIN)) ++D3;
while((GPIO_LEDS_PORT->DIN31_0 & GPIO_LEDS_JOYSTICK_PIN)==0) ++D1;
is_valid=valid;
if(is_valid){
Point1=D1;Point2=D2;
}
y_point=((float)D1/D2-0.250)/(2.2-0.25)*100;
if(y_point>100) y_point=100;
② 光照传感器引脚配置
OPA、ADC12的引脚设置为PA26,并忽略报错。
③ 摇杆上下翻页
通过阈值检测翻页动作。加热时,摇杆信号会受到不明干扰,翻页动作需要滤波。
//判断摇杆位置,上下切换显示
//screen_change表示LCD屏幕翻页方向,display_Mode代表LCD屏幕显示页面
if(y_point<15){
screen_change=-1;
screen_dec_cnt++;
}
else if(y_point>80){
screen_change=1;
screen_inc_cnt++;
}
else if(y_point>20 && y_point<55){
//加热时翻页动作必须滤波,否则翻页动作频繁误触发
if(is_heating){
screen_change=0;
screen_change+=((screen_inc_cnt-screen_dec_cnt)>5);
screen_change-=((screen_inc_cnt-screen_dec_cnt)<-5);
}
display_Mode+=screen_change;
screen_change=0;
if(display_Mode<0) display_Mode=0;
else if(display_Mode>2) display_Mode=2;
screen_dec_cnt=0;
screen_inc_cnt=0;
//检测加热起始或终止,加热电路PWM稍后调节
if(btn_l_change>5 && ButtonADCValue>BtnNoop_Low && ButtonADCValue<BtnNoop_High){
is_heating=!is_heating;
btn_l_change=0;
if(is_heating){
//update_PWM_HEAT(99);
update_PWM_BEEP(2000);
}
else{
//update_PWM_HEAT(0);
update_PWM_BEEP(0);
}
}
}
④ 加热电阻温度实时显示
假设白色背景,在LCD屏幕的某个坐标绘制白色点即可清除原有信息。按这个思路绘制的加热温度曲线图。所以我没有使用硬件SPI驱动屏幕的理由,是因为基于软件SPI绘制温度曲线图已足够流畅。
uint8_t pt_index=(bufferIndex-1+80)%80;
//计算上一次温度数据点的位置
int8_t y_position=90-tempBuffer[(bufferIndex-1+80)%80];
if(y_position>90) y_position=90;
else if(y_position<24) y_position=24;
//清除上一次绘制的绿色扫描线
LCD_DrawLine(pt_index+24,20,pt_index+24,91,WHITE);
//绘制上一次温度数据点,红色
LCD_DrawPoint(pt_index+24,y_position , RED);
//计算本次温度数据点的位置
y_position=90-tempBuffer[(bufferIndex)%80];
if(y_position>90) y_position=90;
else if(y_position<24) y_position=24;
//清除本次数据点的位置,留到下一次绘制
LCD_DrawPoint((bufferIndex)%80+24,y_position , WHITE);
//绘制的本次绿色扫描线
LCD_DrawLine((bufferIndex)%80+24,20,(bufferIndex)%80+24,91,GREEN);
//储存本次的温度数据
tempBuffer[bufferIndex] = heat_temp;
bufferIndex = (bufferIndex + 1) % 80;
存储空间使用情况:
六、结论与展望
本项目成功设计并实现了一个基于TI MSPM0L1306 Launchpad与拓展板的智能环境调节展示系统。该系统通过实时监测环境温度、加热电路状态和光照强度等信息,并根据用户需求智能调节加热电路的工作状态以及提供光音效反馈效果。
未来考虑:加入音乐播放功能,加入游戏功能,加入PID功能(没有学会过PID算法)。
七、备注
摇杆动作识别异常,或者按键不响应,请烧录校准程序。使用方法我懒得打字了,请看视频“感谢观看”后的一部分。向左、右稍微旋转一点旋钮,得出对应阈值,在屏幕上会显示。至于电位器摇杆,向上向下拨动一般不会有问题。
//***旋转编码器&按键的阈值***//
//按键静置,编码器左旋ADC值范围,校准程序的屏幕上显示值
//所谓显示值,是ADC原始数据整除10的的结果
#define BtnDec_Low 220
#define BtnDec_High 230
//按键静置,编码器右旋
#define BtnInc_Low 230
#define BtnInc_High 240
//编码器和按键静置
#define BtnNoop_Low 240
#define BtnNoop_High 250
//编码器静置,按下按键
#define BtnPush_Low 80
#define BtnPush_High 89