考试结束之后在家,终于觉得有必要把之前鸽了很久得ESP32驱动墨水屏的项目提上日程。
但是俗话说的好,工欲善其事,必先利其器,我加工好了PCB,在某宝买焊锡浆的时候瞥到一个220V某仙子的加热台,10块钱不到,我一寻思,这小别致,长得还挺东西,于是打包带了一块儿,觉得这个可以回来做个恒温的 小焊台,小巧又有灵性(给自己挖个坑)!
初步设想利用STM32+热敏电阻+继电器+PID实现恒定温度
利用0.96寸OLED+电位器设定温度 ~~实现100300℃温度可调~ 后来发现发热板最高温度在260左右
除了编码器是刚买的,其他的东西都是家里破烂儿箱里面找出来的
后来发现屏幕是个坏的,网上下单了几块儿
郁闷的是,当时还不知道STM32的这个最小开发板如今已经涨到快50一块儿了,我去年4月初买的 特意去看了一下订单,不过才17块,19年咸鱼买的103ZET6的开发板不过也不到50。唉 放这么个东西在里面,我的心忽然变得好痛。
热敏电阻测温这就没啥好说的了
热敏电阻的用法参照了另外一位博主的帖子 NTC温度检测程序
我手上有一块儿,STM32F103C8最小系统板,查看芯片手册发现ADC是12位精度,量程0~3.6V,我选了MF-58-50K-3950的热敏电阻,选取了一个20K的定值电阻,这样的话中间量程大概在150℃,不过大概粗略计算了一下,12位ADC就算定值电阻取50K在300℃的时候,热敏电阻的阻值应该也是能测出来的。
会用STM32的ADC加上看懂那个NTC测温的程序,实现热敏电阻的温度测定了,不过那个博主有一个地方没说清楚
#define RN 10// 额定阻值(绝对温度时的电阻值10k)
在定义完RN之后 应该再定义一个R16 写清楚R16是定值电阻阻值比较好
RN之后说明添加热敏电阻 再绝对温度时的阻值比较好
刚开始没搞清楚R16的意义(也不能怪别人还是自己学习马马虎虎,没看清楚)错误的把R16当成RN了,导致20℃的室温,算出来的值为4℃多,后来回去又仔细检查了一下,发现是R16设置错了
修改完了之后,就得到了正确的温度了
在室温下得到准确温度之后,我向试试这东西最大能测到多少度,我看网上有人整理出了MF-58在0-300℃的阻值,于是我直接大力出奇迹,上火烧了一下电阻,发现烧了一会儿给它烧傻了,还是不可逆的
在温度大概超过450℃之后可以看到adc的测量值已经从5变成了4000+已经接近12位量程最大值4096了,说明热敏电阻已经坏了,取下来用表量一下,果然200M欧挡位下已经显示为开路,经过这个实验感觉最大温度在300℃一下,应该能够正常工作
#define BaseVol 3.33 //ADC基准电压(理论为3.3V 实际测得为3.33v)
#define B 3950.0//温度系数
#define TN 298.15//额定温度(绝对温度加常温:273.15+25)
#define RN 50// 定值电阻 额定阻值(绝对温度时的电阻值19.77k)
#define R0 19.77 // 热敏电阻 额定阻值(绝对温度时的电阻值50k)
//原博主这里没有申明定值电阻,这里的R0与他的R16相同
//色环电阻阻值为20k,经过我的测量发现阻值为19.77k
//希望这样能进一步提高精确度吧,尽管温度的精度并不需要那么高
int main(void)
{
u16 adcx; //ACD采集数值
float RV; //测量出的 热敏电阻电压
float RT; //计算出的 热敏电阻阻值float RT;
float Tmp; //计算出的温度值
delay_init(); //延时函数初始化
LED_Init(); //LED初始化
Adc_Init(); //ADC初始化
NVIC_Configuration(); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
SystemInit();
uart_init(9600); //串口初始化为9600
while(1){
adcx=Get_Adc_Average(ADC_Channel_1,10); //获取ADC1 10次采样的平均值
RV=(float)adcx*(BaseVol/4096); //热敏电阻电压值
RT=(float)RV*R0/(BaseVol-RV);//求出当前温度阻值 (BaseVoltage-RV)/R16=RV/RT;
Tmp=(float)1/(1/TN+(log((float)RT/RN)/B))-273.15;//%RT = RN exp*B(1/T-1/TN)%
printf("adc:%d \n",adcx); //显示adc测量值
printf("RV:%f \n",RV); //热敏电阻电压
printf("RT:%f \n",RT); //计算出的热敏电阻阻值
printf("Tmp:%f \n\n",Tmp); //计算出的温度
//每一步都打印出来主要是为了方便找出错误是在哪一步 (lll¬ω¬)
printf("\n");
delay_ms(1000);
LED=!LED;
}
}
既然要进行PID调参,那当然得有基于温度的曲线了
要么在407的板子上用TFT屏幕显示温度曲线,要么编写上位机软件用Qt绘制温度曲线
我选择后者,正好借着这个机会学习一下Qt,另外在上位机中直接修改PID的三个参数,至于串口数据的传输,准备用json格式实现,这就又涉及到C语言的json字符串解析了,想想不禁觉得,下个冬天我的头可能会更冷了
蕾姆!
经过几天的折磨,我终于取得了阶段性的战果!
能点灯的上位机终于诞生了!
既然LED都能点亮了,那么离接收串口数据到绘制温度曲线还会远吗!?
每天在上班的时候,上下班的路上,都会时不时的迸发出一个让自己都直呼AMAZING的想法。
今天在大马路上骑着共享小电驴风驰电掣的我,忽然想到 既然咱C++不行就算了呗,何必要跟一个Qt死磕呢
用串口接收时间、温度数据保存到txt文本里,之后用matlab画出来 它不也一样嘛!
我现在为了焊接墨水屏驱动板 而做个加热板了 现在为了调试这个加热板的PID再去学个Qt 感觉完全就是南辕北辙了
再后来转念一想,matlab画图都行的话 python直接引用个库不是更简单了吗【主要吧 matlab好久没用了 捡起来比较麻烦,可不是我不会啊(bushi】
于是彻底跟Qt说分手!
回家之后,立马就整出了下面的东西
首先将温度、时间数据用串口发送出来,之后保存到文件
借助一小段python代码
我想要的温度曲线就这么 一丝不挂的出现在了我的面前!非常之性感
现在这个曲线是没有加入PID控制的,只是单纯的温度到了继电器断开,停止加热,温度低于设定值之后,开始加热
在高温段的时候,表现似乎还算可以
但是如果想要维持一个较低的温度,这种简单的模式就翻车了
当目标设定在50度的时候,因为加热板功率太大,过冲特别严重,直接飙到了110,所以我同学之前建议的,直接用这种简单的方式控制,是行不通滴
另外,后来在B站继续深入研究PID视频的时候,发现UP介绍了进阶版的工具——STM Studio
好嘛,有了这玩意儿直接就能读取单片机寄存器里面的数据,然后一个右键瞬间就生成曲线了。。。
当时我就瞬间石化了,我这费了老半天的劲儿,结果前人已经造好了一个轮子,一个高铁的轮子,坐上去直接起飞~
经过我几天的细心雕琢,现在它成这样了~
本来之前是个8路继电器的,但是我只需要一路,我这急性子又不想等快递了
后面直接拉大锯 给它淦成了非常7+1
五一连续上了好几天班,整个人都被榨干了
每天下班就只想 来两把游戏,啥也不想干
终于这几天缓过来了
前天把屏幕加上了,驱动代码也没写,不过无外乎也就是几个函数调用一下就行了,之前也用OLED做过带UI的界面,取模 打点够我这次用了,连显存都不要了
编码器这次是第一次接触,网上现学编码器原理
自己上手实践,焊接驱动电路【早知道就买现成的模块儿了 自己焊接完了之后发现并没有做到体积比能买来的小 而且过程中 接错线,白给一个下午 然后那个博主的电容选的不合理 导致我的波形怎么都不理想,又白给几个小时】
最后把这几个坑都解决掉之后 终于得到了比较很理想的波形
而网上移植过来的代码,也因为忘了更改头文件里面的一个引脚声明,使得这个代码第一次移植不成功 第一个下午也就这么白给了。中间还试了试其他人的程序,也都是不顺利,丢步比较严重,今天打开代码忽然想到自己好像是头文件的声明引脚忘了修改,改完之后终于一切顺利
正转加数字,反转减数字
可能是只用了一个中断触发的问题,导致正转很完美,反转的效果就本一般了,先这样吧 基本功能都已经有了,至少能用了
调PID的才是接下来主要的工作
编码器参考文章 不过博主这个线路接法,编码器不动的时候IO口应该是高电平 ,转动的时候会有低电平,难道不是应该把IO口设置成上拉输入嘛,另外这里外部中断他用的上升沿检测,我用的下降沿检测,后面想了想,反转出现不准确应该是我用下降沿的问题,还是测试,明天改为上升沿试试