摘要:嵌入式技术发展推动了以智能手机、平板为代表的便携式移动终端设备的广泛应用和普及。智能家居作为物联网中最贴近民生的领域应用,已获得更多的关注和青睐。论文以智能控制为目标,在便携式移动设备上设计了针对家庭用户的智能电源管理系统,使普通用户可以通过手机APP关闭电插板,总线电源的开关。
本文在调研现今智能家居的具体种类,模型的出现过程及适用场合基础上,分析了在使用过程中可能出现的安全问题;在设计智能电源系统的时候,采用udpsocket通信,借助UDP和WiFi模块的API,将地址和端口号对接,开发了手机APP控制局域网内电源的开关行为。在手机APP端,以iOS为开发平台,利用苹果提供的socket API完成相应APP的开发,实现与WiFi模块的对接,指令发送等,最后实现整个iOS平台电源管理系统的功能。
关键词:iOS Arduino 单片机 WiFi 智能家居
话不多说,先以图致敬
这是一个非常简单的结构图(当然细节部分会比较多,没有完全展示)
本文主要内容
在本文中,略述了一下当今智能家居发展的现状,过去和前景。接来下,我要介绍的是基于iOS平台的智能电源管理系统。其中,总共包含五分部内容,内容为下:
第一部分,简要的介绍了一下当今智能家居的应用状况,分析了国内外智能领域行业的发展标准和发展状况。
第二部分,主要介绍了一下基于iOS平台的电源系统的方案设计,主要阐述了这套系统的应用背景,产品平台,应用技术,方案概念和使用方式等等。
第三部分:主要是介绍了arduino单片机的起源背景,关键技术,使用场景和方式,阐述了arduino中单片机和WiFi模块等硬件的连接方式和代码实现。
第四部分:描述了iOS平台的由来,开发使用的语言和技术,xcode的使用和简单APP的编写,阐述了iOS中socket的使用方法和原理,介绍了iOS的图形化开发和功能模块的实现。
第五部分:本章主要阐述了iOS平台和arduino硬件共同组建的智能电源系统,对最终的结果作出了总结,指出了其中的不足,并明确了下一步前进的方向。
首先我们来介绍一下————WiFi通信技术介绍
WiFi是Wireless Fidelity的简称。它是无线网局域联盟的一个商标,同时,也是一种允许电子设备连接到局域网的一种技术。如今,WiFi一般含有两个射频频道:2.4GUHF和5G SHF ISM,一般比较常用的就是2.4GHZ段的频率。当然现在,也有很多无线通信技术[2],例如:蓝牙,WiFi,ZigBee,Z-Wave,NFC,RFID,UWB,红外,GSM等等。下图是它们的技术参数对比:
通信技术示意图
通过上述的图表对比,我们可以得出,WiFi的传输距离是最长的,传输速率也是基本能满足智能家居的需求,当然,智能家居这块很多无线技术都能适用,比如ZigBee 和 Z-Wave则专为智能家居而设计,但是,相对于对智能手机的适应性来说,还是不如蓝牙和WiFi方便。
总体来说,WiFi作为智能家居传输的优点有这么几处:
1.传输距离远:一般无线在室外的传播范围最大为300m,室内为100m。
2.终端连接设备数量多,可调性大:同一台路由器一般设置最大连接数可达50以上。
3.传输速度快:基于最新的5G射频频道的WiFi传输速度最大可达1500Mbps以上。
4.价格比较平民化,市场普及率高:据调查,网上的大部分WiFi路由器价格均不超过百元。
5.无须布线:WiFi最主要的优势在于不需要布线,可以不受布线条件的限制,因此非常适合移动办公用户的需要,具有广阔市场前景。
6.健康安全:IEEE802.11规定的发射功率不可超过100毫瓦,实际发射功率约60~70毫瓦,而手机的发7.射功率约200毫瓦至1瓦间,手持式对讲机高达5瓦,而且无线网络使用方式并非像手机直接接触人体,应该是绝对安全的。
8.组建方法简单:我们只需要一台AP和无线网卡,就能以无线的模式来分享网络资源,或者进行局域网资源的传输。
9.同样,WiFi的技术也是这里面发展比较迅猛的。到目前为止,WiFi已经发展到第五代技术:基于IEEE 802.11AC标准的双频路由已经在市场上获得一致好评。
再来 ——————Arduino系统介绍
Arduino系统是一款由欧洲开发团队在2005年冬季研发的开源电子平台。它包含各种硬件和软件。比如最常见的Arduino UNO开发板和用户单片机开发的Arduino IDE。
Arduino构建于开放原始码simple I/O介面版,并且具有使用类似Java、C语言的Processing/Wiring开发环境。Arduino系统主要包含两部分:硬件部分盒软件部分,其中,硬件是Arduino配套的一些Arduino单片机板,如下图。软件则是另则是Arduino IDE。开发者在开发环境中编写相应的代码,然后烧录进Arduino单片机中,就可以实现相关的功能开发。
Arduino开发板示例图
Arduino硬件套件包含很多硬件组件,比如:马达,火焰传感器,温度传感器,湿度传感器,显示器,继电器和LED灯等。通过控制灯光、继电器或者其他的装置来反馈、影响环境。板子上的微控制器可以通过Arduino的编程语言来编写程序,编译成二进制文件,烧录进微控制器。Arduino编程是利用基于 Wiring的Arduino编程语言和基于 Processing 的Arduino开发环境来实现的。基于Arduino的项目,可以只包含Arduino,也可以包含Arduino和其他一些在PC上运行的软件,他们之间进行通信 (比如 Flash, Processing, MaxMSP)来实现相应的功能。现如今,嵌入式和智能家居等物联网技术日益成熟,Arduino也在这众多的开发平台中脱颖而出。其中,它包含着以下四大特点:
1.跨平台:Arduino IDE可以在Windows、Mac OS X、Linux三大主流操作系统上运行进行开发,而其他的大多数硬件平台的控制器只能在Windows上开发。
2.简单清晰:Arduino IDE基于processing IDE开发。对于刚进入到这一领域的开发者来说,只要掌握基础的C语言,了解一下Arduino自带的函数,便很容易上手,同时它也有着足够的灵活性和扩展性。Arduino语言基于wiring语言开发,是对 avr-gcc库的二次封装,不需要太多的单片机开发基础,稍微学习后,开发者就可以进行快速的开发。
3.开放性:Arduino平台是完全开源的:比如它的硬件原理图、电路图、IDE软件以及核心库的文件都是开源的,开发者在开源协议范围内里可以任意修改原始设计及相应代码并且衍生功能更加丰富的产品。
4.发展迅速:Arduino不仅仅是全球最流行的开源硬件,同时,也是一个优秀的硬件平台。这里集中了全球许多开发者的身影,它简单快捷的开发方式吸引着一大批嵌入式爱好者的加入。由此,越来越多的开发者利用它研究物联网、硬件等主流技术。许多学校甚至开了相关课程。由此可见,Arduino的发展前景也是不可估量的。
接下来,正式介绍该系统硬件端的分析和代码
硬件电路设计
首页,我用到的硬件设备是
Arduino UNO R3 单片机
Arduino UNO R3是Arduino UNO系列最新的一款单片机,Arduino UNO R3的电路图如下所示:
Arduino UNO R3电路图
作为Ardunon平台上的标准参考模板,UNO具有14路数字输出和输入口,在这其中,有6路电路可以用作PWM输出,有6路用于模拟输入,除了输入口,UNO还包括一个16MHZ的晶体振荡器,USB口,电源插座,ICSP header和复位按钮。在外部电源供给上,Arduion UNO可以采取以下3种供电方式:一是可以外接9V的直流电源直接给供电口供电,二是可以采用220V的电源,利用降压模块转化为直流电源,连接到UNO的GND和VIN引脚即可供电,最后就是通过USB口对其供电。
其中,UNO的电源引脚大致分为VIN引脚,5V,3V和GND引脚。VIN引脚是UNO在接入电源时,对外部供电的电源引脚,当然,UNO也可以依赖此引脚直接从外部电源获取电源给自身供电。5V引脚,UNO通过此引脚获取USB或者稳压器的5V电压,为UNO板子上的5V芯片供电,也可以给其他外接扩展设备提供5V的直流电源,3.3V引脚与5V类似,最后的GND是地脚。在上一章的图2.4中,UNO的存储器为ATmega328,这款存储器拥有32KB的 Flash缓存,其中有0.5KB用于Bootloader,此外,它还拥有2KB 的SRAM 和1KB 的EEPROM。
如图3.1中,UNO有两个串口信号口:RX 和 TX,它们与UNO内部的ATmega8U2 USB-to-TTL芯片连接,并提供TTL电压水平的串口接收信号。这两个信号口是本硬件系统连接WiFi模块最重要的两个引脚接口,可以通过它们帮助ATmega328内置的UART与外部实现串口通信。
UNO烧录程序的方式也很简便,只需要通过USB连接到电脑上,下载相关的驱动,ATmega16U2就可以访问数字口,从而打开USB上的虚拟串口进行数据的传输。
电源转化模块
在本系统中,采用的电源模块有两种:外接蓄电池和220V转9V降压模块。
首先,介绍第一种外接蓄电池。在该系统中,需要用到的器材是一个带有DC 5.5电源头的电池盒,一个9V蓄电池,电视盒如下图所示:
外接电池盒
该供电方式可以在不接入交流电源的情况下实现对一些突发情况下需要的供电需求,例如一些线路故障等等情况。
第二种则是需要重点阐述的降压模块电源。在该系统中,采用降压模块给UNO供电是最方便也是最有效率的,系统需要的材料有一块220V转9V的降压板,两根自制导线,如图:
220V转5V降压模块
降压模块采用隔离型工业级的模块电源,其输入电压为AC 85-265V范围内,或者DC100V-370V的范围也可,输出电压为DC 5V,输出电流为700mA,功率为3W。其工作原理示意图如图:
降压模块工作原理图
在实际电路中,在降压模块的L口接入火线,N口接入零线,Vout通过导线接入UNO的VIN引脚,GND口接入UNO上的GND引脚,即可为UNO提供5V的直流电。
——–WiFi通信和继电器模块——-重中之重
在智能电源系统中,WiFi是无线局域网与硬件连接的桥梁,在该套系统中,选用的是一款支持IEEE 802.11.b/g/n的ESP8266-01 串口WiFi模块,继电器选择的是5V高电平触发的1路继电器模块。
ESP8266模块是Arduino中应用最多的WiFi模块之一,它具有以下几点优势:
- 价格低廉,超低功耗。
- 体积小,安装方便,容易集成。
- 功能强大,内部跑LWIP协议。
- 支持三种模式:AP模式,STA模式,AP+STA共存模式。
- 支持丰富的socket AT指令。
在Arduino UNO上,由于引脚的数量限制,在该系统中,需要对ESP8266的引脚进行焊接,ESP8266的引脚图如图3.5所示。本系统中将CH_PD,RST和VCC短接,从而使CH_PD获得供电。焊接完成后,可以对WiFi模块进行通电实验,如图3.6所示,蓝色指示灯闪烁启动完毕,则通电成功。用杜邦线分别将ESP8266的VCC,GND,TX,RX引脚接入到UNO的5V,GND,RX,TX引脚上。无线模块的组建工作完成。
继电器连接UNO开发板的步骤相对比较简单,同时,继电器需要注意的是连接交流电零线和火线的安全问题。继电器中有五个接口,分别为NO常开口,NC常闭口,COM公共点接口,VCC 5V直流电源接口,GND地线口和IN口。我们将IN接口通过杜邦线连接到UNO的11号PWM引脚上,VCC连接到5V电源上,GND接地线。然后通过IN接口输入高低电平,继而控制继电器电源开关。
好了,到目前为止,最初的硬件基本结构已经搭建完成。
我们来进行硬件系统的组建和串口通信试验吧
在介绍完UNO,继电器,WiFi模块和输入电源后,这一小节将这些分散的模块组成一整套完整的电源控制硬件系统。组建系统流程图如图示:
首先,我们需要在sublime text中测试WiFi模块是否能正常连接。ESP8266是通过串口透传进行通信的,首先,我们需要在IDE中给ESP8266烧录相应的AT指令:
Serial.println("AT+RST");//发送执行指令
Serial.println("AT+CWMODE=3");//选择路由模式为AP+STA混合模式。 Serial.println("AT+CWJAP=\"xieke\",\"12345678\"");//输入路由账号密码。 Serial.println("AT+CIPMUX=1");//打开多连接否则会报错。 Serial.println("AT+CIPSTART=0,\"UDP\",\"192.168.2.100\",8000,9000,1");
//建立UDP的局域网连接。
WIFI_showIP();
//显示自己的IP digitalWrite(wifi_start_led,HIGH);//13引脚输出高电平,led灯亮
获取网卡的本地信息(IP,MACADDRESS),代码实现如下:
data.replace("AT+CIFSR","");
data.replace("+CIFSR:","");
OwnIP = data.substring(57,71);//截取IP字段
OwnMac = data.substring(30,47);//截取MAC地址字段
Serial.println(OwnIP);//输出IP
Serial.println(OwnMac);//输出MAC地址
read_string(0);
将程序烧录进UNO开发板,将继电器的VIN接口接到UNO的11号引脚,接上5V直流电和GND,将ESP8266按上文与UNO相连接,将UNO开发板通过USB连接线连上电脑,安装CH341SER驱动,然后在sublime text中选择arduino 开发板为UNO,设置串口为COM3,串口监视器的波特率设置为115200,打开串口监视器,连接成功,获得本地IP。如图所示。
打开网络调试助手NetAssist,设置本地端口为9000,连接上局域网后,向上文中串口监视器中的网卡IP发送数据,当发送on的时候,继电器开关发生变化,当发送的是自己的IP的时候,则收到由单片机返回的IP,MAC地址和开关状态。
关键代码实现如下:
if(sr.substring(sr_index+1)=="on"){
EEPROM.write(address,!digitalRead(relay));
digitalWrite(relay,!digitalRead(relay));
}
else if(OwnIP.substring(0,5) == sr.substring(sr_index+1).substring(0,5)){
//判断收到是否为与自身同一IP段的IP。若是,则进行数据的返回。
String IPST = OwnMac + JDQStatus;//回复给对方自身的MAC和状态。
}
当在网络调试助手输入自己的IP发送给硬件的IP地址时,收到来自WiFi模块返回的MAC信息和开关状态。调试成功。如图所示。
简单的硬件部分到此结束,接下来,来讲一讲移动端的结构以及实现
iOS开发应用程序需要的步骤相对于Android来说需要的门槛要高一些。首先需要的开发工具和平台在上文中已经提及,iOS的主流框架和开发语言也带有描述。接下来,先介绍一下如何创建一个iOS的APP。
- 在Xcode中选择iOS的Application,选择Single View Application,点击建立即可。如图所示
创建iOS APP界面
- 然后进入开发界面,在iOS开发中,本系统采用的是最常用的MVC开发框架,其中,Model存储数据的模型,View管理开发的视图,Controller控制用户的操作响应。
- iOS开发用的Objective-C是一门面向对象的开发语言,所以在iOS开发中,需要学习iOS开发常用的设计框架和设计模式。一般在开发的过程中,采用MVC的框架开发源代码,期间可以用一些设计模式来更好的开发优化APP,例如:Target-action模式,Block模式,Delegate模式,Notification通知模式等,这些方法能帮助我们更快速,更高效率的开发iOS APP。
智能电源APP架构
1.收藏界面模块
iOS的收藏界面主要采用了iOS中常用的CollectionView, CollectionView 是继承于ScrollView的一种滚动视图,它可以包含不同个item,从而实现对某一分类的操作管理。
首先,创立一个UICollectionViewController和UINavigationController,使NavigationController成为iOS windows的根视图,然后让CollectionView- Controller成为导航控制器的根控制器。
在收藏界面的模块中,系统自定义了9种收藏空间:客厅,卧室,厨房,卫生间,阳台,地下室,书房,车库,会议室。所以在开发中,创建一个主界面AllViewController,使该类继承于集合视图控制器的代理<UICollectionView- Delegate,UICollectionViewDataSource>,重写代理方法,采用iOS中xib的方法自定义单元格cell,实现界面的布局。部分代码如下:
static NSString * CellIdentifier = @"CollectionCell";
AllCollectionViewCell * cell = [collectionView dequeueReusableCellWithReuse Identifier:CellIdentifier forIndexPath:indexPath];
采用单元格的重用机制。
if (cell == nil) {
cell = [[AllCollectionViewCell alloc]initWithFrame:CGRectMake(0, 0, 80, 100)];
该行代码实现自定义Cell的位置和高宽。
}
cell.name = [self ArrayInitWithName][indexPath.item];
cell.imageV.image = [UIImage imageNamed:cell.name];
return cell;
此外,在该收藏界面的底部,系统预留一个搜索按钮,用户可以点击这个按钮进入搜索界面,进行设备的发现和添加。整体示意图如图所示:
详细的收藏界面采用分级的模式设计。点击每个item,进入每个分类,用户可以在分类中查询已收藏过的WiFi电源设备,从而进行控制。当点击单个Cell时,执行iOS中pushViewController的方法,推出自定义的设备控制器,当推出的同时,利用属性传值,将单元格自身的相关信息传输过去。设备列表页面采用的是iOS中的TableView,与CollectionView类似,同样是继承于ScrollView的滚动视图,不过是以行来排列的一种视图。当进入设备列表的时候,系统会从本地存储的UserDeafults中提取相关的数组Data,假如数据为空,则添加暂无信息的页面,否则,添加TableView,显示当前的设备信息,如图所示。
部分实现代码如下:
MainToFindTableViewCell *cell = [tableView dequeueReusableCellWith Identifier:identifier];//重用机制
DPJMSG *dpjmsg = [[DPJMSG alloc]init];
dpjmsg = self.deviceArr[indexPath.row];
cell.wifiImageView.image = dpjmsg.image;
cell.IPAddress.text = dpjmsg.ipAddress;
cell.MacAddress.text = dpjmsg.macAddress;
cell.CollectionLabel.text = dpjmsg.identifier;
//给cell的属性赋值
}
cell.selectionStyle = UITableViewCellSelectionStyleNone;
return cell;
通过上述代码实现,收藏页面的布局和功能达到预期效果。iOS端的主界面和收藏页面主要采用了滚动视图,结合iOS的本地存储UserDeafults机制,完成收藏功能所需要的条件。
2.搜索添加设备模块
作为WiFi电源系统中重要的组成部分,我们需要让系统更加智能化的去代替我们去智能搜索附近可用的设备,那么,如何进行搜索和筛选,是本小节中将要详细叙述的内容。
搜索添加页面由三部分组成:搜索动画页面,已发现设备列表页面,自定义信息添加页面。搜索页面由iOS中的Layer动画技术实现,在搜索页面的视图Center,放置一个ImageView,在其位置的背景放置一个循环展示的水波动画,进入到这个页面的同时,发布搜索动作。搜索机制采用了iOS中的UdpSocekt原理,向连接的WiFi服务器发布广播,WiFi服务器向连接到本身的每个终端发送信息,列如WiFi模块返回相应格式的数据,判断格式,添加至发现设备的列表当中,流程如图所示。
在iOS中,动画主要有UIView animation,CATransition,CALayer等。在搜索页面中,采用的是CALayer的绘制层动画效果,自定义动画间隔和绘制区域的大小,采用外部三方的封装方式,运用Block回调将动画添加至搜索页面当中。同时,封装socket为外部三方,方便调用。在socket封装中,导入已经封装好的AsynUdpSocket,让后在此基础上进行二次封装。首先,自定义socket类,在类中,实现udpSocket的初始化:udpServerSoket = [[GCDAsyncUdpSocket alloc]initWithDelegate:self delegateQueue:dQueue socketQueue:nil],实现广播功能:[udpServerSoket enableBroadcast:YES error:nil],监听本地9000的端口并开始接受数据:[udpServerSoket bindToPort:9000 error:nil];
[udpServerSoket receiveOnce:&error],然后向服务器发送数据用到的是sent data的方法。我们将这系列的方法都封装至外部,在搜索界面直接调用就可以完成相应的功能。外部封装的三方采用单例的设计模式,这样,APP全局只能新建一次UDP Socket,解决数据不能全局化和socket冲突的问题。
当搜索页面检测到有设备时,会跳转至发现列表页面,否则跳出提示框,表明附近没有发现WiFi电源设备。进入设备列表时,系统从本地获取已经储存的设备,匹配新发现的设备Mac地址,若相同,展现已经收藏过的设备名称,如不同,显示IP和MacAddress地址,点击即可进行收藏。
收藏界面,采用列表排列方式,上部分显示设备的mac地址,IP地址和开关状态,下部分是用户自定义的名字填写框,位置选择器和图片。用户可以根据自己的需要自定义设备名称,归属位置,和实物照片,填写完毕之后,可以添加到主页收藏列表里面。
在收藏时,在userdefaults中提取存放的数组data,然后解析为可变数组,将设备的信息整合到model中,添加至本地设备中。图为model属性图。
在添加页面中,位置选择器和图片选择采用pickerView和imagePickerView实现。实现部分代码如图所示:
通过上述代码实现,最终的结果示意图:
3.控制开关模块
在该模块中,直接导入socket的外部类,进入页面先查询该设备的开关状态。整体布局采用固定按钮模式,包含一个电源开关按钮和显示电源状态按钮。
为了方便用户操控辨别设备的开关状态以及考虑安全性。在每次用户开关的过程中,系统都会时时检测设备的开关状态。部分代码实现如下:
self.handle = [SocketHandle sharedHandle];
[self.handle sendAllIP];
__block __weak typeof(self)WeakSelf = self;
self.handle.block = ^(NSString *dpjIP,NSString *msg){
NSString *string = [NSString stringWithFormat:@"%@,%@",
dpjIP,msg];
NSArray *arr = [string componentsSeparatedByString:@","];
NSLog(@"%@",string);
if ([arr[1] isEqualToString:WeakSelf.dpjmsg.macAddress]) {
WeakSelf.array = [NSArray arrayWithArray:arr];
dispatch_sync(dispatch_get_main_queue(), ^{
//检测返回的数据
//判断返回的设备开关状态
if ([(NSString *)arr[2] containsString:@"on"]) {
[WeakSelf.imageButton setImage:[UIImage image
Named:@"on.jpg"] forState:(UIControlStateNormal)];
WeakSelf.isON = YES;
WeakSelf.PowerLabel.text = @"开";
}else{
[WeakSelf.imageButton setImage:[UIImage image
Named:@"off.jpg"] forState:(UIControlStateNormal)];
WeakSelf.isON = NO;
WeakSelf.PowerLabel.text = @"关";
}
});
系统判断完成之后显示开关状态,然后用户点击开关,socket发送udp指令给单片机,完成开断电的操作。界面演示图如图。
开关界面示意图
最后来实际测试一下:
在完成上述模块开发之后,我们打开Xcode,导入iPhone,进行实测。将手机和单片机连接上WiFi,等待单片机连接上WiFi之后,打开搜索界面,等待五秒发现无线设备,进入设备列表后点击进入添加设备页面,填写完整信息后添加成功,然后返回主界面进入添加位置,返现出现了已经添加的模块。点击进入后操控成功。该实验完成。实际示意图如图所示:
经过实测,iOS客户端已经能实现上述的所有功能,完满的达到了所需要的效果。在手机端上,可以实现设备的添加删除,可以对WiFi模块进行操控管理,手机端运行流畅,总体达成目标。
结语
好了,一个简单的智能家居无线控制系统就此已经差不多了,有疑问或者需要进一步了解的小伙伴,请加我微信:xieke789