万欣
(北京天融信科技有限公司,北京 100085)
随着智能家居的逐步普及,传统的红外遥控器的缺点日益凸显。特别是当家庭中出现大量各种型号、各种功能的红外遥控器时,就会大大降低用户体验[1]。在现代化智能家居系统中,设计一种能够整合各种家电遥控器功能的系统就能大大改善家电系统的用户体验,同时又具有不错的市场潜力。在开发新型智能家居系统时,也能提供一定的借鉴。
整个系统包括手机端的万能遥控器App以及由App控制的MSP430遥控模块,再由MSP430遥控模块通过户内遥控模块发射红外信号进而控制室内各种家电。本文着重介绍万能遥控器App的框架结构以及设计过程,如图1所示。
图1 系统整体框图Fig.1 System frame chart
用户可以在手机客户端,按手机遥控器界面给外设发送指令,外设接收指令,识别指令是学习还是发射,如果是学习,则等待学习。此时拿遥控器对准万能遥控器的学习端口进行学习,学习结束后再次回到等待接收指令状态。如果是发送,则执行相应按键发射红外信号进行对家居的控制。在界面最上方又信息提示栏,提示用户当前手机的状态,是学习状态还是使用状态,并且显示当前所按的按键[2]。按下menu按钮则可进行不同遥控器界面的切换。
本设计中的遥控器界面设计主要包括页面布局、文本框、按钮以及menu列表几部分[3]。本文使用的是eclipse及ADT插件作为开发环境。具体程序编写时使用的是Java语言。
安卓的布局管理器包括线性布局,表格布局,帧布局,相对布局,网格布局,绝对布局等。本文只用到了线性布局,表格布局,相对布局[4]。线性布局对应的类是LinearLayout,它可以将其中的组件按一定顺序排列起来。表格布局对应的类是TableLayout,它继承自LinearLayout,用表格布局可以方便地用行和列来安排组件,自己并不需要指明有多少行多少列,表格布局是通过添加TableRow来控制行和列,其中一个TableRow代表一行。相对布局对应的类是RelativbeLayout,顾名思义,它是采用先定义一个组件的位置,然后其它组件是相对于这个组件按一定规则排列。
首先分析,遥控器界面由诸多按键组成,按键的排列方式也不是一直不变规则的,因此拿电视遥控器举例,它有一些普通的圆形按键按规则排列,还有音量加减,频道加减,上下左右等按键按较复杂的方式排列[5]。这里本文大致将组件分为两类,一类是排列规则单一的,本文用表格布局,另外一类排列规则稍显麻烦的我用相对布局排列。最外层是线性布局,然后是表格布局,一行一行进行组织安排。遇到较复杂的例如音量键,频道加减键,上下左右ok键等我则在表格布局中又添加了相对布局进行相应的组织[6]。
本文在界面上面定义了两个文本框用来显示手机当前状态和当前按键。android:id="@+id/textView2"这句话相当于这个文本框的身份证明,这句话在整个安卓应用工程中是唯一的,因为本文按相应按键的时候提示框大的内容会跟着相应变化,所以可以用到findViewById(R.id.id名)的方法来找到这个文本框[7]。android:Text="Key:",这句话用来设置此文本框显示的内容。
按键是本文界面设计的重要部分,按键的大小,形状,状态变化,布局都应该认真考虑。Android:id="@+id/button1",这句话赋予了一个按键唯一的身份。Android:layout_width="50dp"android:layout_height="50dp" ,这两句话规定了按钮的大小,android:background="@Drawable/button_selector",这一句话设置了某个按钮的背景图片,通过@drawable这样的语法可以调用drawable目录内的资源文件,可以是图片资源,也可以是用程序绘制的图片XML资源。android:text="静音",设置按键显示的文字android:textColor="#fff"设置文字颜色。android:textSize="12dp"这句话用来设置文字的大小位12像素[8]。android:onClick="clickHandler1"这句话用来给一个按钮添加单击事件监听器。后面可以在java源代码中的相应函数如public void clickHandler1(View view){···}中编写单击之后所要执行的动作。
为了实现多个遥控器界面之间的切换,本文用到了menu功能,点击手机上的menu按键可以实现多个遥控器界面之间的切换,进而切换对不同用电器的控制[9],效果如图2所示。
图2 遥控界面的切换功能Fig.2 Switching function of remote control interface
本文选择2FSK作为基带信号的调制方法。即将手机客户端发送的指令用2FSK调制后再发送给单片机[10]。单片机再将所接收信号解调成其能识别的信号,进一步执行发送及控制功能。
首先确定2FSK信号的位数,这取决于按键的个数,为了方便研究测试与设计,简化了按键的数量,这里设按键为32个(后面可以在此基础上以相同的原理添加),于是需要5位二进制数字才能完全表示,从00000~11111分别代表按键0~31。考虑到进行2FSK解调时需要设置起始位,于是用一个周期为1 KHz的正弦波作为起始信号[11]。下面以01010对应的2FSK信号制作为例,简单讲述这些2FSK信号的制作。
图3 用Cool Edit Pro生成的1 KHz的正弦波Fig.3 1 KHz sine wave from Cool Edit Pro
在安卓开发中,关于任务的执行丰富了事件监听器,系统有一个主线程,一直执行。当某个时间发生,监听器就会发现,但是它不会去打扰系统的主线程,而独自处理,处理完毕后继续进行侦查工作。下面的这段代码是某个按钮的单击时间监听程序,当该按钮用户单击后便会被执行[12]。首先它先找到信息提示Key,让其显示当前的按键值,然后创建一个MediaPlayer类的对象MediaPlayer mPlayer0 =MediaPlayer.create(this,R.raw.sig_05),盛放所要播放的音频信号,然后mPlayer0.start()开始播放[13]。
结合其调制原理,我们只要识别出正弦波信号的频率便可解调基带信号。我们使用的解调设备一般是单片机,单片机可以直接识别出模拟信号[14]。本文使用的的是大家通用的首先将正弦波转换为单片机识别的高低电平,然后通过单片机的、中断或者计时器来测量出高低电平的时间,然后通过周期换算出频率。由图3可以清楚看出上图中低电平有较大差别,通过中断大致计算出低电平的时间,不用太精确便可以得到2FSK的解调信号,01010这里我们发现高电平的差别没有低电平明显,这是因为偏置电路的设计,因为下面的电阻阻值大于上面电阻的阻值,才导致这样的现象,应该使两个分压电阻尽量相等[15]。图4是2FSK解调的硬件电路。
程序流程:
第一步:进入中断;
第二步:等待低电平过去;
第三步:迎接高电平到来,循环5次,分别记录每组高电平时间,如果>250us则记为0,否则记为1;
第四步:计算键值Key = 1*Rec[4]+2*Rec[3]+4*Rec[2]+8*Rec[1]+16*Rec[0]。这里为了防止死循环,每次等待电平过去的while循环里面都有一个附加条件err>0,在循环体里面执行err--,这样可以防止陷入死循环。
图4 2FSK解调硬件电路Fig.4 2FSK demodulation hardware circuit
本文完整概述了对万能遥控器App的设计过程,并对这款APP做了如下测试:按相应按键用示波器观察所发送的信号,实验结果显示正确率为100%。测试结果表明此款万能遥控器设计效果出色,能够满足一般家庭对家用电器的手机端控制需求。但在用户体验方面,此款App还有很大的改进空间。