万和燃气热水器加装遥控功能

**

万和燃气热水器加装遥控功能

**
家中使用一台12L万和牌的燃气热水器,由于使用燃气和废气排放的原因,热水器本身安装在厨房内,而热水使用又在卫生间,所以原先未加装遥控的情况下,热水器的开关和调节要么事先设定好,要么需要家人协助,很不方便.于是便考虑自己加装一个遥控,这样在使用热水器时,在卫生间就可以观察且操控热水器,很是方便!
万和12L燃气热水器
万和12L热水器
控制面板
控制面板

1.原控制面板控制原理分析

1.1 控制面板的PCB板

  • 拆开热水器外罩后,控制面板就安装在面罩背面的一个盒子中,下面就是面板的PCB正反面的样子,如果加入遥控,需要先搞清楚其原理和信号.看来不能省事,先把原理图画出来才行.

在这里插入图片描述

PCB正面
PCB背面
PCB背面,上面的标记可以对照本人画的原理图就可以知道其含义
好在单面PCB分析起来并不麻烦~

1.2 原控制面板的原理图

原理图
原控制面板原理图,所有元件参数及标记均与图片上原控制板一致,红色圆圈标记就是前面图上标记的位置,这也是我们需要采用的信号点.
PCBPCB走线也与原板尽可能保持一致,避免原理及信号出错.

1.3 信号分析

原理图比较简单,通过原理图分析,可以得出以下信息
a.面板采用一块74HC164作为串转并的LED驱动芯片,所以要获取温度信息只要读取这个BCD码串就行;
b.按键信号是通过各自的分压电阻将+5V电压进行风压后,将分压信号传回主机的MCU去的;遥控改装也很简单,在标记处并入开关信号即可;
c.需要注意的是,原机的十位数的BCD码的DP(小数点位)并没有给LED显示使用,因为不需要,而是把这个位给了面板的绿色LED工作指示灯用(DIG1),用于指示燃气热水器是否在"燃烧"状态;这个在BCD码串再解码时需注意.
d.蜂鸣器回路无用.

1.4 遥控接口信号考虑

波形
采集的BCD码串,对应:黄:CODE 紫:CP 绿:SM1(SM2波形相同,只不过相对SM1正好差一个节拍,个位和十位轮换显示的区别)
所以:
a.温度端口是5V信号,一般MCU都可以接受,无需隔离;
b.按键输入最好需要用光耦隔离一下,避免冲击之类的事情.

2. 遥控改装的思路

2.1 设计

其实只要理解原控制板原理,改装遥控应该就比较简单,可以根据自己擅长的方案进行改装.下面分享一下本人的改装方案,仅供大家参考.
a.接收端(也就是与热水器本体连接的这一端)使用一个MCU,用于接收遥控器发来的控制信号,并把温度信号传给遥控端;
b.自然需要一个通讯模块,什么类型都行esp8266,24L01,CC1101都行,手边有或者自己用的熟的就行,本人用来一对CC1101,够用就行;
c.接收端最好有两个SPI可用,因为BCD解码和无线通讯可能要各用一个,当然,能自己手搓一个SPI口一个也行-
d.遥控端的MCU最好能带TFT的屏,这样可以DIY比较好看的界面,还有,原先热水器是有一些报警信息的,原面板只能通过BCD码串在两个数码管以E0~E7来显示,其具体含义除非看说明书才能知道含义,一般用户不太会理解这些信息.有了屏,就可以实时读取或观察到这些信息,避免出现问题.
故障
这张纸在热水器前面罩背面贴住,很"贴心"!

2.2 接收端简图

在这里插入图片描述

接收端原理图简化版,偷懒画了主要的控制端口,原理并不复杂,改装时每个人具体不尽相同,所以参考即可.图上不清楚可留言.说明一下:
a.使用了一块STM32F103C8T6 的现成板子,非常普通,很好找,用了一块CC1101做通讯,用了一块四路光耦做信号隔离;
b.做了一个小接口插头,这样可以快速与原面板引出的信号进行对接,开发和调试也比较方便,板子的电源也可以直接取用原控制板上的5V;
c.CC1101用了一个SPI口,BCD解码用了一个SPI口.

接收A
实物照片比较糊,当初没想留照的…
接收B
天线自己重绕了一下,没调好的时候以为天线问题,后来发现和天线无关,也懒得焊回去了,反正可以用,也看不见.

2.3 发射端(遥控端)

遥控端也是找了一块原先用过的板子,MCU是STM32F030C8T6,可以挂一块TFT,把原先的SPI接一个CC1101即可,也是直接用,下面是原理简图示意:
在这里插入图片描述

a.另一面接了一块TFT液晶屏,使用SPI接CC1101时注意避开这些端口
b.使用3个GPIO输入按键指令
在这里插入图片描述
使用废PCB做个壳子,用起来没问题,这是冷机待机状态.字体是绿色
在这里插入图片描述
这是热机待机状态,字体是蓝色
在这里插入图片描述
加热燃烧状态,字体是黄色.关机或冷机超时后或息屏并进入休眠状态,主机送电后会唤醒遥控端,另外停止加热超时后也会发出停机指令,避免忘记关机造成浪费!

3.控制程序分析

3.1 接收端需要注意的地方

BCD码串的解码是接收端MCU的一项主要任务.通过波形分析,可以得到下面的码串:

u8 smgduan[16]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};//0~F 温度BCD码数据

这里需要注意的是,燃烧时十位数的BCD码和上面有所区别,最高位"bit7"被置位为 “0”,表示当前处于"燃烧"的状态(正如前面提到过的).因此,需要将此状态正确解码出来并加以利用.另外,也应同时考虑到"故障"码的解码.完整的解码程序如下:

u8 smgduan[16]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};//0~F 温度BCD码数据
/************************************************
函数名称 : decoding
功    能 : 用于翻译解释来自端口的8段BCD码串,结果为对应的数字
						其中小数点的码位(bit7)在控制中被设计为点火状态位
						中间包含点火状态的解码,如果BCD码点火状态为"0",则进行自动关机倒计时
参    数 : 无
返 回 值 : 计算的温度值,点火状态,关机倒计时计数
作    者 : huangxu
*************************************************/
u8 decoding(void)																											//解码
{	
	u8 i,tmp0=0,tmp1=0,decode;								//温度个位和温度十位,最终返回的温度计算值
	
	if(0!=BCD)																													//首先进行非"0"判断,判断是否是BCD码
	{
		for(i=0;i<15;i++)																									//进行查表转换,因为包含错误码解码,所以需进行全码解码
		{
			if ((BCD&0xFF)==smgduan[i])						//温度十位,此时是待机编码
			{
				tmp0=i;																												//进行对应位数刷新,码位即对应的真实数值
				stop_time--;																									//停机倒计时
				WorkSta=11;																										//待机状态 未点火"11"
			}
			else if (((BCD&0xFF)==(smgduan[i]&0x7F)))	//点火时编码,因编码DP位借用给工作指示灯,所以工作时温度十位的编码bit7为"0"
			{
				tmp0=i;																												//进行对应位数刷新
				stop_time=1200;																								//复归停机计时 约10 分钟
				WorkSta=22;																										//点火状态 最低位置"22"
			}
			if (((BCD>>8)&0xFF)==smgduan[i])				//温度个位
			{
				tmp1=i;
			}
		}
		decode = 10*tmp0 + tmp1;							//获取实际的温度值
	}
	else
	{
		WorkSta= 0;								//未启动状态"00",另外一种情况未通电有遥控端进行判断,"00"默认已通电未启动状态
		decode = 0;								//无温度值返回"0"
	}
	return decode;
}

因为BCD码解码是被动接受(来自于主机MCU),所以应使用对应SPI端口的中断来"采集"温度数据.并考虑设置采集"窗口",在采集结束后关闭SPI中断,这样可以避免连续的SPI中断导致遥控端来的指令无法执行.

//中断服务程序
void SPI2_IRQHandler(void)
{
    
    if (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_IT_RXNE) == SET)
    {
        BCD = SPI_I2S_ReceiveData(SPI2);			//采集BCD数据
        /* 清除接收中断 */
        SPI_I2S_ClearITPendingBit(SPI2, SPI_I2S_IT_RXNE);
   }
}

在主循环中加入如下采集窗口:

							__enable_irq();    			// 开启总中断,采集新的温度设定值
								delay_ms(20 );				//注意取值<1864	数据接收指示 慢闪两次
								led_flashing( );			//
								delay_ms(20 );				//注意取值<1864
								led_flashing( );			//
							__disable_irq();   			// 关闭总中断	

这样就避免MCU进程被SPI中断拴住的局面,避免死机.

关于CC1101的驱动,本人也是"拿来主义",没有太多的改动,当然"坑"也是有的,前面调试的时候,动不动就"死机",无线通讯信号偶有波动,这边立马躺尸.真是无可奈何!后来经过排查,发现标准例程中确实有问题,通讯过程当中一旦信号波动,丢失,即可进入死等状态,具体修改位置如下:(****处)

/**
  * @brief :CC1101发送接收模式设置
  * @param :
  *			@Mode:TX_MODE,发送模式 RX_MODE,接收模式
  * @note  :无
  * @retval:寄存器状态
  */
void CC1101_Set_Mode( CC1101_ModeType Mode )
{
		uint16_t l_RxWaitTimeout = 0;

    if( Mode == TX_MODE )			//发送模式
    {
        CC1101_Write_Reg( CC1101_IOCFG0,0x46 );
        CC1101_Write_Cmd( CC1101_STX );		
    }
    else if( Mode == RX_MODE )		//接收模式
    {
        CC1101_Write_Reg(CC1101_IOCFG0,0x46);
        CC1101_Write_Cmd( CC1101_SRX );
    }
	
		while( 0 != CC1101_GET_GDO0_STATUS( ))		//等待发送 或 接收开始
			{										//*****此处新加入了超时等待防止信号波动时无应答死机
			delay_ms( 1 );
			if( 1000 == l_RxWaitTimeout++ )
			{
				l_RxWaitTimeout = 0;
				CC1101_Init( );
				break; 
			}
		}		

}


另外,CC1101要注意地址和同步字段的问题.
以上实现的MCU是STM32F103C8T6.

3.2 发射端(遥控端)需注意的地方

遥控端实际上大多数时间处于接收状态,主要用于接收来自设备端的温度信号,仅在需要对热水器进行调节时才发送相应指令.
因此,对于遥控端来讲,处理好接收到的信息是一项主要任务,因为信息的显示是由TFT屏完成的,所以代码并不具有通用性,暂时就不贴了,但是有几点还是要注意到:
a.可以使用解码后的故障码>=0xE0,而正常温度不会大于99的区别,进行温度信号和故障信号的甄别;如下参考:

						if 	(temp_now<140)		//此处依据温度值,选择显示信息.如果小于140(对应于故障信息码"E0"~"E7"转换后的值),正常显示
						{
								FRONT_COLOR=WorkColor[RxBuffer[1]/11];BACK_COLOR=BLACK;
								LCD_Show64Num(66,60, temp_now,2,64,0x40);						//当前温度显示
								BACK_COLOR=WHITE;FRONT_COLOR=~BACK_COLOR;  //画笔颜色 背景色 
						}
						else																																																//错误信息显示,温度值大于140,表示为故障码状态
						{
								FRONT_COLOR=WHITE;BACK_COLOR=BLACK;
							switch (RxBuffer[0]-140)																																					//按照信息进行显示
							{
								case 0:																																													//24字体宽度16,最多21字符/行
										LCD_ShowString(0,100,tftlcd_data.width,tftlcd_data.height,16,"IN WATER SENCE ERROR!");			//E0 进水传感器故障
								break;
								case 1:
										LCD_ShowString(0,100,tftlcd_data.width,tftlcd_data.height,16,"      FLAMEOUIT!     ");			//E1 熄火
								break;
								case 2:
										LCD_ShowString(0,100,tftlcd_data.width,tftlcd_data.height,16,"THERMOCOUPLE PROTECT!");			//E2 热电偶保护
								break;
								case 3:
										LCD_ShowString(0,100,tftlcd_data.width,tftlcd_data.height,16,"FLUE / WIND PRESSURE!");			//E3 烟道或风压
								break;
								case 4:
										LCD_ShowString(0,100,tftlcd_data.width,tftlcd_data.height,16," FAN OR DRIVE ERROR! ");			//风机或驱动电路
								break;
								case 5:
										LCD_ShowString(0,100,tftlcd_data.width,tftlcd_data.height,16,"      TOO HOT!       ");			//过热保护
								break;
								case 6:
										LCD_ShowString(0,100,tftlcd_data.width,tftlcd_data.height,16,"OUT WATER SENCE ERROR");			//出水温度传感器
								break;
								case 7:
										LCD_ShowString(0,100,tftlcd_data.width,tftlcd_data.height,16,"   GAS SELECT ERROR! ");			//气体选择开关错误
								break;
								default :
								break;
							}

b.注意区分几种工况下的区别:
1.热水器端断电;
2.热水器带电,但并未启动;
3.热水器启动,但并未燃烧;
4.热水器处于"燃烧"状态;
5.热水器"燃烧"后超过一段时间,又没有任何操作.
基本考虑到这五种工况后,程序就比较完整了.

c. 一段休眠待机代码:

									RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR,ENABLE); //时钟必须要开启
									PWR_BackupAccessCmd(ENABLE);   
//									PWR_WakeUpPinCmd(PWR_WakeUpPin_1,ENABLE); 
									PWR_ClearFlag(PWR_FLAG_WU);
									PWR_EnterSTANDBYMode();

这段代码放在合适位置可以实现遥控端待机休眠.

以上代码使用STM32F030C8T6实现.

4.其他

遥控与原有的操作面板操作并无冲突,相互独立,即使遥控通道出现问题,也不会影响到原有按键的正常操作和热水器的使用!
本来准备上一段视频演示使用情况,但没有搞明白平台视频上传的操作,暂时先放弃.
接收端和遥控端全套源码附后.
https://download.csdn.net/download/weixin_43022857/89359350

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值