爆改太阳能热水器控制器用esp8266接入HASS |
您所在的位置:网站首页 › 太阳能热水器控制器怎么使用 › 爆改太阳能热水器控制器用esp8266接入HASS |
《太阳能热水器控制器用esp8266接入HASS》
本人家在南方小县城里面,家里装了两套热水器,一套太阳能,一套燃气。
当然一开始只有一套,后面冬天没热水只能每天用烧水壶烧水洗澡,后面实在受不了了,就加了一套燃气热水器。
那么问题来了:
①:家里是自建房,一共四个房间加客厅要用热水,只能集中供水,那么太阳能和燃气热水器要如何切换?
②:燃气热水器只有冬天才用,冬天水温太冷,直接烧燃气消耗太快,怎么省?
③:如果能切换,能不能不要手动切换,那样多麻烦?
先给大家看看成果吧
微信截图_20220221124453.jpg (29.04 KB, 下载次数: 4) 下载附件 2022-2-21 12:44 上传 在HASS里面可以看到水位,水温,外界温度。可以手动切换是否使用燃气热水器,加水操作。 天然气余量是另一个模块,跟控制器没有关系。
=======构思=======
既然有了需求就有了折腾的动力,既然要满足集中供水,就要公用一条管路,那么燃气热水器就只能连接到太阳能管路后面。
但是如果直接对接的话每次用水燃气热水器就会启动,这样不行,要加分流,让燃气热水器在我们需要开启的时候才能开启。
于是我设计了下面这样的水路切换:
无标题.jpg (95.35 KB, 下载次数: 0) 下载附件 2022-2-21 11:11 上传 正常使用时AB点互通,当水温太低需要使用燃气热水器时转换三通阀使AC点互通。 这样在太阳能提升了一定温度的水就可以经过燃气热水器加热到指定温度。 因为太阳能提前加热了一些,所以燃气热水器加热时就不需要消耗太多燃气,也就达到了节约的目的。 过滤器是为了过滤掉在太阳能热水器里面产生的水垢,避免堵塞花洒。 水路设计好了,电路也得跟上。 原先的控制器接线都是分开的,太分散了!思来想去,使用网线连接最适合。控制器这边就不设置接线端子了,直接使用网口输出。 热水器这边使用网口转接,具体是这样的↓![]() 微信图片_20220221113120.jpg (367.28 KB, 下载次数: 0) 下载附件 2022-2-21 11:31 上传 ![]() 微信截图_20220221121503.jpg (197.01 KB, 下载次数: 1) 下载附件 2022-2-21 12:15 上传 网口用AB胶水粘在继电器上固定,继电器是用来控制三通阀切换和燃气热水器的。 这样在热水器和控制器之间只需要拉一条网线就可以互相通讯了,比原来的一大坨线好多了。 当然改造过之后也可以吧控制器放在顶楼6楼,不过我现在是放在二楼,方便调试。
首先三通阀必须要控制,我选用的三通阀是220V切换控制,控制逻辑见下图。
微信截图_20220216221536.jpg (58.72 KB, 下载次数: 0) 下载附件 2022-2-16 22:16 上传 三通阀全貌长这样:![]() 微信截图_20220216221414.jpg (24.12 KB, 下载次数: 0) 下载附件 2022-2-16 22:14 上传 燃气热水器选用强排式需要220V供电的热水器,16升基本满足两人同时用水的需求。
那么如何操控三通阀和燃气热水器的切换呢,思来想去,决定从太阳能控制器下手。
传统的控制器可以自动上水,加热(这玩意儿贼费电,我从来没用过),保温,防冻(南方不需要)。
微信截图_20220216222446.jpg (31.42 KB, 下载次数: 0) 下载附件 2022-2-16 22:25 上传 就这....也好意思说智能![]() 拆开控制器,几个继电器控制加热保温,显示,供电,传感器.......好像不是很复杂 那就自己动手做一个控制器吧! 要满足温度水温测量,水路切换,定时,与ha通讯,单靠8266应该是比较难做的,所以找了个帮手-->STC单片机。 有了单片机,测控可以比较完美的进行,ha通讯就交给8266就行了。
=======选型=======
直接在马云家搜STC单片机,出来了好多型号,前面几个是新出的STC8系列单片机,在stc烧录程序里面查看功能参数。
综合考量,选定了STC8H1K17-TSSOP20封装,单价约2元。
微信截图_20220216224029.jpg (35.85 KB, 下载次数: 0) 下载附件 2022-2-16 22:41 上传 要定时搞事当然要配实时时钟芯片啦,就选简单易懂的DS1302,做diy的小伙伴都知道![]() ![]() 微信截图_20220216224219.jpg (32.87 KB, 下载次数: 0) 下载附件 2022-2-16 22:42 上传 显示嘛,原机使用的数码管是定制的,使用TM1628驱动,改造的话还是尽量适配原机的数码管,最终选用了TM1668驱动原机数码管。![]() 微信截图_20220216224421.jpg (34.97 KB, 下载次数: 0) 下载附件 2022-2-16 22:44 上传 最后是知道水位水温的关键啦,太阳能水位水温传感器~~~![]() 微信截图_20220216224638.jpg (55.37 KB, 下载次数: 0) 下载附件 2022-2-16 22:47 上传 嗯,这玩意儿原理其实挺简单的。 选好器件,就要开始合体♂了(
=======原理图和板子=======
要读取传感器的数据,首先要了解传感器的原理。
这种通用的传感器其实是由两个二极管分离的热敏电阻和水位分割电阻(应该是这么说吧)组成的。具体见下图:
微信截图_20220216225527.jpg (15.91 KB, 下载次数: 1) 下载附件 2022-2-16 22:56 上传 这样在AB两端施加不同的电位就可以分别获取到水位以及水温了,根据这个原理,画出对应的采样电路:![]() 微信截图_20220216225819.jpg (72.62 KB, 下载次数: 1) 下载附件 2022-2-16 22:58 上传 D9-D12是TVS保护管,可以忽略。20脚是AD采样引脚,19和18是激励切换引脚。RED对应A点,YELLO对应B点。 19脚高电平,18脚低电平时:电流可以通过上方的二极管,下方二极管截止,于是采集到了热敏电阻的AD值,保存转换得到温度。 18脚高电平,19脚低电平时:电流可以通过下方的二极管,上方二极管截止,四个电阻串联,水位到达一定程度时,下方的电阻相当于短接,于是采集到对应的AD保存转换得到水位。 没错,就是这么简单就能采集到水位水温了,核心点也就这个,其他都比较简单,就是一些电阻电容把器件组合起来而已,跟搭积木一样。![]() 微信截图_20220216230752.jpg (290.57 KB, 下载次数: 2) 下载附件 2022-2-16 23:09 上传
本地计时时钟采用DS1302,编程简单。
因为上次购买的8266还剩下好些,所以也采用了板载的方式集成8266通讯,通过串口连接两个mcu。
驱动数码管的任务就交给了TM1668,也是很简单就能驱动了。
因为是适配原来的太阳能控制器,所以板子外形做了定制
微信截图_20220221121739.jpg (206.93 KB, 下载次数: 0) 下载附件 2022-2-21 12:17 上传 ![]() 微信截图_20220221121759.jpg (156.49 KB, 下载次数: 0) 下载附件 2022-2-21 12:17 上传 原本打算用NTC检测温度的,后面写程序的时候嫌复杂就放弃了,改用18b20,也能达到要求。 右下角的跳线是调试用的,左下角是网口。
实装后是这样的:
微信图片_20220221122338.jpg (501.18 KB, 下载次数: 0) 下载附件 2022-2-21 12:23 上传 ![]() 微信图片_20220221122446.jpg (578.99 KB, 下载次数: 0) 下载附件 2022-2-21 12:24 上传 数码管改成了可以拿掉的,方便调试
因为8266部分画图的时候没有画好,瞎画的电路,所以装机后信号特差,后面就加了上个帖子改进后的模块 微信图片_20220221122738.jpg (371.27 KB, 下载次数: 0) 下载附件 2022-2-21 12:27 上传 =======编程======= 单片机部分因为组件比较多,代码也比较多和杂乱(半桶水) 所以先跟大家分享新学的检测传感器的部分 其实也不复杂,两个引脚(P1.0和P3.7)分别切换高低电平,然后ADC在电平切换稳定后转换并数字滤波,然后按照规律转换成温度或者水位就可以了。 if(ADCMode){ /***************温度检测***************/ if(!ADCReady){EADC = 1;YELL = 0;RED = 1;ADC_CONTR |= 0x41;} else if(ADCReady){ WenDuL[DiT_ConA] = ADCdata / 256; DiT_ConA ++; ADCdata = 0; ADCMode = 0; ADCReady = 0; EADC = 0; } if(DiT_ConA >= 76) DiT_ConA = 0; } else { /***************水位检测****************/ if(!ADCReady) {EADC = 1;YELL = 1;RED = 0;ADC_CONTR |= 0x41;} else if(ADCReady){ ShuiWeiL[DiT_ConB] = ADCdata / 256; DiT_ConB ++; ADCdata = 0; ADCMode = 1; ADCReady = 0; EADC = 0; } if(DiT_ConB >= 32) DiT_ConB = 0; } /***************18B20**********************/ if(TestTime >= 4){ EA = 0; Temp18b = (unsigned int)read_temperature(); EA = 1; if(Temp18b != 9999) { Temp18b = Temp18b * 0.625; TmpNTC_OS = Temp18b / 10; } else TmpNTC_OS = 99; TestTime = 0; } /****************温度计算*******************/ for(j=0;j 938)Temp = 9999; else{ if(WenDuADC < 475) Temp = 99; else if(WenDuADC < 525){ //81-99度 WenDuADC_P = 525 - WenDuADC; Temp = WenDuADC_P / 2.6 + 80; } else{ //0-80度 WenDuADC_P = 934 - WenDuADC; //原938 Temp = WenDuADC_P / 5.1538; } } /******************水位计算*******************/ for(j=0;j 160) ShuiWei = 4; else if(ShuiWeiADC > 100) ShuiWei = 3; else if(ShuiWeiADC > 70) ShuiWei = 2; else if(ShuiWeiADC > 50) ShuiWei = 1; else if(ShuiWeiADC < 35) ShuiWei = 99; else ShuiWei = 0; } else{ if(ShuiWeiADC > 220) ShuiWei = 4; else if(ShuiWeiADC > 150) ShuiWei = 3; else if(ShuiWeiADC > 90) ShuiWei = 2; else if(ShuiWeiADC > 60) ShuiWei = 1; else if(ShuiWeiADC < 35) ShuiWei = 99; else ShuiWei = 0; }后面是中断部分 /******************ADC中断*********************/ void ADC_Isr() interrupt 5{ ADC_CONTR &= ~0x20; //清中断标志 if(RED && !YELL){ ADCdata += (ADC_RES*4+(ADC_RESL >> 6)); ADCon_WD ++; if(ADCon_WD >= 256){ YELL = 0; RED = 0; ADCon_WD = 0; ADCReady = 1; } ADC_CONTR |= 0x41; } if(!RED && YELL){ ADCdata += (ADC_RES*4+(ADC_RESL >> 6)); ADCon_SW ++; if(ADCon_SW >= 256){ YELL = 0; RED = 0; ADCon_SW = 0; ADCReady = 1; } ADC_CONTR |= 0x41; } }其他就是自动控制部分,按键检测,实时时钟读取,之类七七八八的。 还有一个重点是通讯部分,使用串口通讯。 STC定时上报状态给8266,然后需要控制时8266下发指令给STC,实现通讯。 下面是一部分代码 SendconTimer++; //定时计数 if(SendconTimer > 400){ SendconTimer = 0; switch(Sendcon){ case 0: SendString("GETA");SendNumber(Temp,2);SendEnter();Sendcon++;break; //上报水温 case 1: SendString("GETB");SendNumber(ShuiWei,1);SendEnter();Sendcon++;break; //上报水位 case 2: SendString("GETE");SendNumber(Temp18b / 10,2);SendString(".");SendNumber(Temp18b,1);SendEnter();Sendcon++;break; //上报18B20温度 case 3: if(JiaShuiFlag) {SendString("INWON");SendEnter();Sendcon++;} //上报是否加水 else {SendString("INWOFF");SendEnter();Sendcon++;} break; case 4: if(BaoWenFlag) {SendString("BAWON");SendEnter();Sendcon=0;} //上报是否开启燃气热水器 else {SendString("BAWOFF");SendEnter();Sendcon=0;} break; default:break; } } switch(SendFlag){ case 1: SendString("GETA");SendNumber(Temp,2); //主动查询水温上报 SendEnter();ReadFlag = 0;SendFlag = 0;break; case 2: SendString("GETB");SendNumber(ShuiWei,1); //主动查询水位上报 SendEnter();ReadFlag = 0;SendFlag = 0;break; case 3: SendString("GETC");SendNumber(timer,4); //主动查询当前本地时间 SendEnter();ReadFlag = 0;SendFlag = 0;break; case 4: SendString("GETE");SendNumber(Temp18b / 10,2); //主动查询18b20温度 SendEnter();ReadFlag = 0;SendFlag = 0;break; case 10: if(ShuiWei < 4){JiaShuiFlag = 1;ShuiWeiS = 4;} //上水指令,目标水位为4(就是加满) ReadFlag = 0;SendFlag = 0;BeepCon = 1000;break; case 11: JiaShuiFlag = 0;ReadFlag = 0;SendFlag = 0;BeepCon = 1000;break; //停止上水指令 case 12: SendString("BAWON");SendEnter(); BaoWenFlag = 1;ReadFlag = 0;SendFlag = 0;BeepCon = 1000;break; //打开燃气热水器指令 case 13: SendString("BAWOFF");SendEnter(); BaoWenFlag = 0;ReadFlag = 0;SendFlag = 0;BeepCon = 1000;break; //关闭燃气热水器指令 case 21: CaiPin = 1;ReadFlag = 0;SendFlag = 0;break; //告知已联网成功 default:break; } 下面是串口中断部分: /*UART 中断服务程序*/ void Uart() interrupt 4{ unsigned char i; unsigned char j; unsigned char SerialRead; if(RI){ //读取中断标志位 RI = 0; if(!ReadFlag){ SerialRead = SBUF; if(SerialRead == 0x0a || SerCon > 10){ ReadFlag = 1; SerCon = 0; } else Serialread[SerCon++] = SerialRead; } if(ReadFlag){ SerCon = 0; if(Serialread[0] == 'S' && Serialread[1] == 'E' && Serialread[2] == 'T'){ if(Serialread[3] == 'D'){ Timedata = 0; for(i=4;i |
今日新闻 |
点击排行 |
|
推荐新闻 |
图片新闻 |
|
专题文章 |
CopyRight 2018-2019 实验室设备网 版权所有 win10的实时保护怎么永久关闭 |