NOW, 5 步 将此黑科技传授予你~
一、普通家电控制电路板分析
普通家电 , 其人机接口一般由按键和指示灯组成(高端的会稍微复杂,这里不考虑)
这样 交互过程 ,其实就是:由当前指示灯信息,按照操作流程按相应按键,来实现相应功能的过程:
注:每次按动相应的按键都会导致相应的指示灯自身的状态从0到1或者从1到0变化,这其实是一个最好的反馈
那么,我们将一个 完整的过程定义为 :按动某个按键(或几个,同时或依次),等待某个指示灯呈现某种状态,得到基于特定电器的固有功能(操作)
例如:你按动电热水壶的烧水按钮,此时烧水指示灯变亮,等到烧水指示灯变暗,表明该烧水过程完成
这样,我们可以 把传统电器抽象成一个黑盒 ,你输入一些按钮控制信号,等待特定指示灯返回信号,再做出另外一些控制信号,依次类推,直到得到某个最终反馈信号,表明你通过这一交互过程完成了对黑盒的交互实现了黑盒给定的功能。
因此 , 想要做个手机控制的家电就要用硬件在人与机之间插一脚~
呵呵:从上图来看电水壶已经不纯了,硬件插入到人壶之间后,还把壶卖给了手机,手机又偷偷地把壶和人卖给了服务器~
二、如何设计硬件电路读取指示灯的工作状态和控制开关按下
综上 ,硬件部分关键在于读灯和按键!
我本来以为:
① 一般的传统家电的指示灯电路是在,3.3V~5V左右的电压下工作的,分为高电平点亮和低电平点亮
②一般的传统家电的按键按下会产生一个低电平/高电平传入MCU进行去抖等判断
所以原初认为这样就能搞定问题了:
注:通过在电器外部插入一个MCU用来监听内部按键按下和LED管脚的状态来获取,并且可以伪造按键按下信息和LED状态
而实际上是:
① 没有所谓的高低电平,得从数字电路的01中跳出来,高电平是大于某个阈值的电平,低电平是低于某个阈值的电平
② 按键存在一些特殊情况,比如多路复用(下面是我遇到的情况:就不能仅仅看为高低电平来处理)
注:图中采用3个按钮复用一个MCU输入,通过串联不同阻值的电阻来使不同按键按下后MCU按键输入引脚产生不同的电压,MCU采用一定方式区分出这些电压就能区分出是哪个按键按下
因此:
① 想获得指示灯状态可以采用——读取指示灯引脚上的电压值,然后在嵌入式程序里计算,如果高于高电平阈值被认为是高电平,如果低于低电平阈值被认为是低电平。
② 要想模拟按键按下可以采用——在每个按键上并一路继电器开关,插入监听的MCU通过控制继电器模拟按键按下。
如下 ,是我针对某一款家用电器的改造方案:
其中:
该家电一共有5个指示灯(图中左上),左1和左2状态互补,其他三个灯状态独立,每个灯与家电内部的MCU都有相应的独立线路相连。由于,上面分析我们不能简单地以数字信号来获取指示灯的状态,所以这里分别利用外置监听MCU的PA0,PA1,PA2和PA3四个引脚来做AD输入读取左1,左3,左4和左5四个指示灯引脚两端的电压值。
经反复测量分析得到关于指示灯的部分工作信息(图中左下):在家电开机的时候高电平维持在3.28~3.29V左右,此时指示灯是关的(也就是低电平灯亮);低电平维持在0.6V一下,此时指示灯是开着的。特殊情况:在机器断电情况下,PA0~PA3四路AD输入电压在1.5~1.8V之间。
因此,我将1V作为低电平的上限,将3.2V作为高电平的下线,1~3.2V处于浮空状态。
对于模拟按键按下则通过3个继电器,每个继电器并联在一个按键之上。如图中间偏上CONTROL WIRE,其中RED WIRE连接在三个按键的公共输入端,BLACK WIRE、WRITE WIRE和GREEN WIRE分别连到相应按钮的另一端。而这四个线又连接到右上角所示的电路上。该电路是一个包含ULN2003和3个继电器的电路。
因此,只要将VCC和GND加上电压,外部监听MCU用3个引脚连接到IN5/IN6/IN7,若MCU置相应引脚为高则相当于相应按键按下,置低相当于抬起。人的手动按按键的过程相当于按下+延时+抬起的过程。
三、编写嵌入式代码实现4路AD读取指示灯电压值+3路继电器开关控制
上面说到,用 继电器模拟按键按下 ,其实就是设置相应的管脚为:
高电平+延时一段时间+低电平(高电平表示开始按下,延时表示按下的一个短暂的时间,低电平表示又抬起来了)
其相应的代码大家也能明白: (解析TxBuffer1[0]里的内容,为'a'则让PA4对应的继电器模拟按键按下,为'b'则让PA5对应的继电器模拟按键按下,依次类推...
1 switch(TxBuffer1[0]){ 2 case 'a': 3 GPIO_SetBits(GPIOA, GPIO_Pin_4);//置PA4引脚为高 4 ticks = 900000;//延时 5 while(ticks--); 6 GPIO_ResetBits(GPIOA, GPIO_Pin_4);//置PA4引脚为低 7 break; 8 case 'b': 9 GPIO_SetBits(GPIOA, GPIO_Pin_5); 10 ticks = 900000; 11 while(ticks--); 12 GPIO_ResetBits(GPIOA, GPIO_Pin_5); 13 break; 14 case 'c': 15 GPIO_SetBits(GPIOA, GPIO_Pin_6); 16 ticks = 900000; 17 while(ticks--); 18 GPIO_ResetBits(GPIOA, GPIO_Pin_6); 19 break; 20 default:break; 21 }
而 AD则对小白来说稍微难以理解一点,简单来说 AD就和电压表的功能类似,可以读取某一引脚上的电压值。
上面讲到,我们分别用PA0/PA1/PA2/PA3四个引脚读取四个指示灯的电压值,然后在嵌入式程序中判断每个电压值是高电平还是低电平,来判每个指示灯的状态:
读取电压值小于1V表示低电平,表示指示灯亮;读取电压值大于3.2V表示高电平,表示指示灯暗
其相应的代码大家也能明白: (每次通过蓝牙发送一个以'S'开头、'E'结尾、中间包含4个字母(每个字母可以是'Y'、'N'、'M',分别表示对应指示灯状态为开、关、未知...其中第5行调用GetVolt(After_filter[i])函数是取多次测AD值的一个平均,用这个平均值能减少一些干扰;接下来6、7、8三行为根据所测AD值计算对应指示灯的状态。
1 USART_OUT(USART1,"S");//use the bluetooth send a char 'S' 2 while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);//wait for the bluetooth send finish 3 for(i = 0; i < M; i++)//get the four AD value and judge wether the pin is high or low, 4 { //finally send the 'Y'/'N' stand for the LED[i] is on or off 5 value[i] = GetVolt(After_filter[i]); 6 if(value[i]<100)USART_OUT(USART1,"Y");//the AD value below 1V, means the LED is on 7 else if(value[i]>320)USART_OUT(USART1,"N");//the AD value above 3.2V, means the LED is off 8 else USART_OUT(USART1,"M");//if the AD value between 1V and 3.2V, means nothing 9 while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET); 10 ticks = 900000; 11 while(ticks--); 12 } 13 USART_OUT(USART1,"E"); 14 while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);
整 个嵌入式工程是基于STM32F103C8T6单片机开发的,其工程结构比较清晰如下:
Startup中的文件是stm32的启动文件,是纯汇编写的,主要用来启动stm32,在此之后就进入我们熟悉的main函数的位置执行了!
main.c函数包含主要的初始化函数和main函数,上面两个逻辑处理函数全在main函数中。
stm3f10_it.c是中断函数,这里主要有一个串口数据接收中断函数。
FWLIB中是本工程用到的功能如:AD、DMA、GPIO、RCC、USART等的库,暂不用考虑
CMSYS中是stm32固件相关,暂不用考虑
注:不熟悉的人能看懂上面两个贴出的代码就行了,要理解整个工程要一点stm32的知识~
四、用传统蓝牙HC-06沟通单片机和APP
至此我们外部MCU算是真正打入到我们要控制的家电内部了!
接下来如何让其他设备, 如手机做打入内部MCU的接线人呢- ?
这里我采用的是传统的蓝牙通信技术~
注:图中1、2、3、4分别为待黑家电的控制电路板、3路继电器电路板、HC-06蓝牙模块和STM32最小系统
这里采用的蓝牙模块是一种传统的(非4.0)蓝牙串口模块~
附加讲解:
① 传统的蓝牙iPhone是不支持的,目前新款安卓智能机和iPhone用的是蓝牙4.0技术(不过安卓的也兼容非4.0蓝牙),我们常听说的iBeacon、智能手环啥的里面采用的是BLE技术(即:蓝牙低功耗技术,是基于标准蓝牙4.0协议栈做的低功耗版本)
② 蓝牙串口模块即你利用此模块操作蓝牙就像串口一样简单,模块中无需自己写任何蓝牙协议代码,只需要像串口一样将其上面的TXD连接到MCU的RXD,其上面的RXD连到MCU上的TXD,接下来MCU采用串口的方式便能达到和采用蓝牙一样的通信效果。
所以,上面代码中
USART_OUT(USART1,"Y");
其实是通过蓝牙串口透传模块,将数据通 发 给给了已经配对且连接的蓝牙设备了(如手机)~
那么当手机通过APP发送一条控制命令时,硬件是如何 收 到的呢?
同样的,由于是透传模块,远端通过蓝牙发送过来的数据也会在相应的串口中断中收到~
这里的控制命令有3种:
'a'+0x0d+0x0a 表示模拟按动按键1
'b'+0x0d+0x0a 表示模拟按动按键2
'c'+0x0d+0x0a 表示模拟按动按键3
1 void USART1_IRQHandler(void) 2 { 3 unsigned int i; 4 if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) 5 { 6 RxBuffer1[RxCounter1++] = USART_ReceiveData(USART1); 7 if(RxBuffer1[RxCounter1 - 2] == 0x0d && RxBuffer1[RxCounter1 - 1] == 0x0a) 8 { 9 for(i = 0; i < RxCounter1; i++) TxBuffer1[i] = RxBuffer1[i]; 10 rec_f = 1; 11 TxBuffer1[RxCounter1] = 0; 12 RxCounter1 = 0; 13 } 14 } 15 if(USART_GetITStatus(USART1, USART_IT_TXE) != RESET) 16 { 17 USART_ITConfig(USART1, USART_IT_TXE, DISABLE); 18 } 19 }
注:这样就和和第三节的第一段代码对应了吧~串口中断收到app发来的控制命令的信息存放在TxBuffer1中,通过解析TxBuffer1[0]的值来判断模拟哪个按键按下~
五、APP端的蓝牙代码从哪里找、怎么写
至此,硬件端的设计和编码算是完全搞定了!
1、现在你可以看看我之前写的一篇文章试试能不能在PC的串口助手对被黑的家电进行状态监控和远程控制: [C#] 编程控制笔记本蓝牙与外部蓝牙设备通信: http://www.cnblogs.com/zjutlitao/p/3886826.html 2、然后你可以大致浏览下,主要是分析一个可以和HC-06通信的应用细节,小白勿进,前方高能!! [安卓] 11、串口蓝牙·将软硬结合进行到底: http://www.cnblogs.com/zjutlitao/p/4231635.html 3、前方还是高能,这一篇主要教你做个简单的蓝牙室内定位~ [安卓] 13、安卓蓝牙定位(一)——如何周期性获得蓝牙节点信号强度?: http://www.cnblogs.com/zjutlitao/p/4314096.html 4、这个也很高能,不过我使用傻瓜式的讲法讲的,所以可以模仿着做一个: [智能硬件] 1、三分钟看懂智能硬件原理——蓝牙防丢器制作教程(包括手机应用): http://www.cnblogs.com/zjutlitao/p/4625799.html 5、这个和上一个一样,是在上一个基础上的加深,任然是面向小白,实现了APP向蓝牙硬件写命令: [智能硬件] 2、三分钟看懂智能硬件原理——智能玩具小风扇制作教程(包括手机应用开发): http://www.cnblogs.com/zjutlitao/p/4640745.html 6、下面这个是上面两个同一系列的,实现了蓝牙硬件的APP数据读取,甚高能~ [智能硬件] 3、三分钟看懂智能硬件原理——简易智能手环制作教程(包括炫酷手机客户端开发): http://www.cnblogs.com/zjutlitao/p/4690228.html 7、上面只是基于HC-06串口透传的APP+蓝牙+硬件的小东西,如果你也认为是小东西,可以深入理解下蓝牙协议栈: [蓝牙协议栈] 1、蓝牙核心技术了解(蓝牙协议、架构、硬件和软件笔记): http://www.cnblogs.com/zjutlitao/p/4742428.html
当然 ,如果你是小白让你自己做个安卓APP来和硬件通信是非常够呛的,我的建议是你先看第一条,搞熟了可以看看4、5两条,然后基本上可以看看其他的自由发挥了~
针对于本文的硬件电路我建议先看第一条,先能用PC控制硬件~就这样!
OK,你已经可以把家里的冰箱、电视、饮水机拆了搞起来了~
@beautifulzzzz
2015-11-11 持续更新中~