基于ARDUINO的智能家居设计与实现Word格式.docx
《基于ARDUINO的智能家居设计与实现Word格式.docx》由会员分享,可在线阅读,更多相关《基于ARDUINO的智能家居设计与实现Word格式.docx(22页珍藏版)》请在冰豆网上搜索。
光线的测量采用光敏电阻;
(6)
伺服舵机;
(7)
外围电路由简单的发光二极管及各类元器件组
(图一)
1.4系统的控制思路与流程
APP客户端使用tcp/ip协议,远程无线连接上工作在服务器模式的wifi模块,wifi模块连接上家庭路由器,需要注意的是家庭网络要处于公网模式,在APP客户端发送控制命令,wifi模块接受命令转成串口数据输出,arduino读取串口数据实现LED灯光亮度智能调节,舵机角度控制,同时arduino模块读取温度传感器数值,采样光敏电阻电压转换为光照度,然后arduino把数据通过串口传给wifi模块,wifi模块发送数据,客户端接收数据然后显示在安卓手机上;
控制流程如图二;
(图二)控制流程图
2、软件、硬件介绍
2.1客户端软件
采用安卓智能手机作为命令发送和接受端,通过因特网传输数据,实现家居的智能监控和远程操控,操作简单,使用方便。
客户端软件采用中文版的安卓编写软件,本文主要专注于整体框架的实现,在此就不再对开发软件进行详细介绍,对软件界面的美观性和舒适性未做过多的修饰。
如有不足之处,请指教!
客户端软件界面如图三:
(图三)
2.2arduino介绍
2.2.1arduino研发过程
MassimoBanzi之前是意大利Ivrea一家高科技设计学校的老师。
他的学生们经常抱怨找不到便宜好用的微控制器。
2005年冬天,MassimoBanzi跟DavidCuartielles讨论了这个问题。
DavidCuartielles是一个西班牙籍晶片工程师,当时在这所学校做访问学者。
两人决定设计自己的电路板,并引入了Banzi的学生DavidMellis为电路板设计编程语言。
两天以后,DavidMellis就写出了程式码。
又过了三天,电路板就完工了。
这块电路板被命名为Arduino。
2.2.2arduino编程软件
ArduinoIDE基于processingIDE开发的。
对于初学者来说,极易掌握,同时有着足够的灵活性。
Arduino语言基于wiring语言开发,是对AVRGCC库的二次封装,不需要太多的单片机基础、编程基础,简单学习后,你也可以快速的进行开发。
(图四)ARDUINO编程软件界面
2.2.3Arduino硬件
Arduino发展至今,出现了适应各种环境的硬件版本,如ArduinoUno、ArduinoNano、ArduinoNano、ArduinoLilyPad,ArduinoMega2560……。
本文采用ArduinoUno为主控器,Arduino
UNO是Arduino
USB接口系列的最新版本,作为Arduino平台的参考标准模板。
UNO的处理器核心是ATmega328,同时具有14路数字输入/输出口(其中6路可作为PWM输出),6路模拟输入,一个16MHz晶体振荡器,一个USB口,一个电源插座,一个ICSP
header和一个复位按钮。
UNO已经发布到第三版,与前两版相比有以下新的特点:
1、在AREF处增加了两个管脚SDA和SCL,支持I2C接口;
2、增加IOREF和一个预留管脚,将来扩展板将能兼容5V和3.3V核心板。
3、改进了复位电路设计
,USB接口芯片由ATmega16U2替代了ATmega8U2,
如图五为改进后的Arduino
UNO。
(图五)ARDUINOUNO硬件图
2.2.4Arduino编程语言简介
Arduino语言是建立在C/C++基础上的,其实也就是基础的C语言,Arduino语言只不过把AVR单片机(微控制器)相关的一些参数设置都函数化,不用我们去了解他的底层,让我们不了解AVR单片机(微控制器)的朋友也能轻松上手。
关键字:
•if
•if...else
•for
•switchcase
•while
•do...while
•break
•continue
•return
•goto
语法符号:
;
{}
//
数据类型:
boolean布尔类型
char字符类型
unsignedint无符号整数类型
long长整数类型
unsignedlong无符号长整数类型
float浮点类型
double双精度浮点类型
string字符数组型
array数组类型
void无类型
数据类型转换:
char()
byte()
int()
long()
float()
常量:
HIGH|LOW:
表示数字IO口的电平,HIGH表示高电平
(1),LOW表示低电平(0)。
INPUT|OUTPUT:
表示数字IO口的方向,INPUT表示输入(高阻态),
OUTPUT:
表示输出(AVR能提供5V电压40mA电流)。
true|false:
true表示真
(1),false表示假(0)。
程序结构:
声明变量及接口名称(例如:
intval;
intledPin=13;
)。
voidsetup()函数在程序开始时使用,初始化变量,管脚模式,调用库函数等(例如:
pinMode(ledPin,OUTUPT);
voidloop()在setup()函数之后,即初始化之后,
loop()让你的程序循环地被执行。
使用它来运转Arduino。
数字
I/O
:
pinMode(pin,
mode)
数字IO口输入输出模式定义函数,pin表示为0~13,
mode表示INPUT或OUTPUT。
digitalWrite(pin,
value)
数字IO口输出电平定义函数,pin表示为0~13,value表示为HIGH或LOW。
必须先定义为输入或输出模式digitalWrite才能生效。
int
digitalRead(pin):
数字IO口读输入电平函数,pin表示为0~13,value表示为HIGH或LOW。
比如可以读数
字传感器。
模拟
:
analogRead(pin):
模拟IO口读函数,pin表示为0~5(Arduino
Diecimila为0~5,Arduino
nano为0~7)。
比
如可以读模拟传感器(10位AD,0~5V表示为0~1023)。
analogWrite(pin,
–
PWM:
数字IO口PWM输出函数,Arduino数字IO口标注了PWM的IO口可使用该函数,pin表示3,
5,
6,
9,
10,
11,value表示为0~255。
比如可用于电机PWM调速或音乐播放。
时间函数:
unsignedlongmillis():
返回时间函数(单位ms),该函数是指,当程序运行就开始计时并返回记录的参数,该参数溢出大概需要50天。
delay(ms):
延时函数(单位ms)。
delayMicroseconds(us):
延时函数(单位us)。
串口收发函数:
Serial.begin(speed):
串口定义波特率函数,speed表示波特率(串行每秒传输数据的速率),如9600,19200等。
intSerial.available():
判断缓冲器状态。
intSerial.read():
读串口并返回收到参数。
Serial.flush():
清空缓冲器。
Serial.print(data):
串口输出数据。
Serial.print:
(数据,数据的进制)默认为十进制(DEC)
Serial.println(data):
串口输出数据并带回车符。
以上为arduino使用过程中常用的函数和语法,其他的函数和库可以参考说明书;
2.3WIFI模块介绍
(图六)wifi串口模块
本设计所使用的Wifi模块(图六)是海凌科电子新推出的低成本嵌入式UART-ETH-WIFI(串口-以太网-无线网)模块。
内置TCP/IP协议栈,能够实现用户串口、以太网、无线网(WIFI)3个接口之间的转换。
通过HLK-RM04模块,传统的串口设备在不需要更改任何配置的情况下,即可通过Internet网络传输自己的数据。
为用户的串口设备通过网络传输数据提供完整快速的解决方案。
(图七)HLK-RM04功能结构图
HLK-RM04模块在使用之前需要做些相应的配置,模块提供两种配置方式:
1.WEB页面;
2.串口AT指令;
访问web配置界面需要确认模块的ip地址,以及web认证的用户名密码。
通过串口AT指令配置参数需要先让模块进入AT指令模式,HLK-RM04_CONFIG串口配置工具即通过AT指令方式提供简单方便的配置过程。
在此就不再做过多的介绍,详细可以参考说明书;
3、硬件连接
3.1温度传感器
温度的测量方式有很多种,本文采用单总线数字式的温度传感器DS18B20,DS18B20是DALLAS公司生产的一线式数字温度传感器,具有3引脚TO-92小体积封装形式(图八);
温度测量范围为-55℃~+125℃,可编程为9位~12位A/D转换精度,测温分辨率可达0.0625℃,被测温度用符号扩展的16位数字量方式串行输出;
其工作电源既可在远端引入,也可采用寄生电源方式产生;
多个DS18B20可以并联到3根或2根线上,CPU只需一根端口线就能与诸多DS18B20通信,占用微处理器的端口较少,可节省大量的引线和逻辑电路。
以上特点使DS18B20非常适用于远距离多点温度检测系统。
(图八)DS18B02封装
DS18B20内部结构如(图九)所示,主要由4部分组成:
64位ROM、温度传感器、非挥发的温度报警触发器TH和TL、配置寄存器。
DQ为数字信号输入/输出端(如图);
GND为电源地;
VDD为外接供电电源输入端。
ROM中的64位序列号是出厂前被激光刻好的,它可以看作是该DS18B20的地址序列码,每个DS18B20的64位序列号均不相同。
这样就可以实现一根总线上挂接多个DS18B20的目的。
(图九)DS18B20内部结构框图
DS18B02供电方式有两种,分别为寄生电源供电方式(图十)和外部电源供电方式(图十一);
(图十)DS18B02寄生电源供电方式
(图十一)外部电源供电方式
独特的寄生电源方式有三个好处:
1)进行远距离测温时,无需本地电源
2)可以在没有常规电源的条件下读取ROM
3)电路更加简洁,仅用一根I/O口实现测温
要想使DS18B20进行精确的温度转换,I/O线必须保证在温度转换期间提供足够的能量,由于每个DS18B20在温度转换期间工作电流达到1mA,当几个温度传感器挂在同一根I/O线上进行多点测温时,只靠4.7K上拉电阻就无法提供足够的能量,会造成无法转换温度或温度误差极大。
因此近寄生电源供电方式只适应于单一温度传感器测温情况下使用,不适宜采用电池供电系统中。
并且工作电源VCC必须保证在5V,当电源电压下降时,寄生电源能够汲取的能量也降低,会使温度误差变大。
因此必须采用独立电源供电方式,本设计及采用外部电源供电方式;
3.2光线传感器
光线测量采用光敏电阻(图十二),光敏电阻,是一种特殊的电阻,简称光电阻,又名光导管。
它的电阻和光线的强弱有直接关系。
光强度增加,则电阻减小;
光强度减小,则电阻增大。
这是由于光照产生的载流子都参与导电,在外加电场的作用下作漂移运动,电子奔向电源的正极,空穴奔向电源的负极,从而使光敏电阻器的阻值迅速下降。
(图十二)光敏电阻实物图
光敏电阻接入arduino的电路图如下:
(图十三)光敏电阻接线图
3.3伺服舵机
舵机(英文叫Servo)(图十四):
它由直流电机、减速齿轮组、传感器和控制电路组成的一套自动控制系统。
通过发送信号,指定输出轴旋转角度。
舵机一般而言都有最大旋转角度(比如180度。
)与普通直流电机的区别主要在,直流电机是一圈圈转动的,舵机只能在一定角度内转动,不能一圈圈转(数字舵机可以在舵机模式和电机模式中切换,没有这个问题)。
普通直流电机无法反馈转动的角度信息,而舵机可以。
用途也不同,普通直流电机一般是整圈转动做动力用,舵机是控制某物体转动一定角度用(比如机器人的关节)。
(图十四)舵机实物图
舵机的伺服系统由可变宽度的脉冲来进行控制,控制线是用来传送脉冲的。
脉冲的参数有最小值,最大值,和频率。
一般而言,舵机的基准信号都是周期为20ms,宽度为1.5ms。
这个基准信号定义的位置为中间位置。
舵机有最大转动角度,中间位置的定义就是从这个位置到最大角度与最小角度的量完全一样。
最重要的一点是,不同舵机的最大转动角度可能不相同,但是其中间位置的脉冲宽度是一定的,那就是1.5ms。
如图十五:
(图十五)
角度是由来自控制线的持续的脉冲所产生。
这种控制方法叫做脉冲调制。
脉冲的长短决定舵机转动多大角度。
例如:
1.5毫秒脉冲会到转动到中间位置(对于180°
舵机来说,就是90°
位置)。
当控制系统发出指令,让舵机移动到某一位置,并让他保持这个角度,这时外力的影响不会让他角度产生变化,但是这个是由上限的,上限就是他的最大扭力。
除非控制系统不停的发出脉冲稳定舵机的角度,舵机的角度不会一直不变。
当舵机接收到一个小于1.5ms的脉冲,输出轴会以中间位置为标准,逆时针旋转一定角度。
接收到的脉冲大于1.5ms情况相反。
不同品牌,甚至同一品牌的不同舵机,都会有不同的最大值和最小值。
一般而言,最小脉冲为1ms,最大脉冲为2ms。
如下图:
(图十六)
伺服舵机接线图如下:
(图十七)舵机控制电路图
3.4灯光控制
对于控制灯光由暗到亮或由亮到暗,采用的是脉宽PWM法。
脉冲宽度调制(PWM),是英文“PulseWidthModulation”的缩写,简称脉宽调制,是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术,本文灯光亮度控制通过arduino输出不同占空比(占空比是指脉冲信号的通电时间与通电周期之比)的方波,然后用去触发固态继电器,达到控制灯光亮度的功能;
原理图如下:
(图十八)灯光亮度控制电路
4、通讯
4.1串行通讯
串行通信是指使用一条数据线,将数据一位一位地依次传输,每一位数据占据一个固定的时间长度。
其只需要少数几条线就可以在系统间交换信息,特别使用于计算机与计算机、计算机与外设之间的远距离通信。
串行接口是一种可以将接受来自CPU的并行数据字符转换为连续的串行数据流发送出去,同时可将接受的串行数据流转换为并行的数据字符供给CPU的器件。
由于wifi模块内部自带TCP/IP协议,能够把网络数据通过串口转发出来,所以我们只需考虑如何接收和发送串口数据,大大的降低了开发的难度。
4.2异步通讯
异步方式通信ASYNC(AsynchronousDataCommunication),又称起止式异步通信,是计算机通信中最常用的数据信息传输方式。
它是以字符为单位进行传输的,字符之间没有固定的时间间隔要求,而每个字符中的各位则以固定的时间传送。
收、发双方取得同步的方法是采用在字符格式中设置起始位和停止位。
在一个有效字符正式发送前,发送器先发送一个起始位,然后发送有效字符位,在字符结束时再发送一个停止位,起始位至停止位构成一帧。
串行异步传输时的数据格式:
⑴起始位:
起始位必须是持续一个比特时间的逻辑"
0"
电平,标志传送一个字符的开始。
⑵
数据位:
数据位为5-8位,它紧跟在起始位之后,是被传送字符的有效数据位。
传送时先传送字符的低位,后传送字符的高位。
数据位究竟是几位,可由硬件或软件来设定。
⑶奇偶位:
奇偶校验位仅占一位,用于进行奇校验或偶校验,也可以不设奇偶位。
⑷停止位:
停止位为1位、1.5位或2位,可有软件设定。
它一定是逻辑"
1"
电平,标志着传送一个字符的结束。
⑸空闲位:
空闲位表示线路处于空闲状态,此时线路上为逻辑"
电平。
空闲位可以没有,此时异步传送的效率为最高。
4.3Arduino与wifi模块连接
(图十九)通讯连接
4.4通讯协议
由于数据在传输过程中容易受到干扰和一些错误,造成接收到的数据丢失和不完整,为保证数据的完整性,必须用一种指定的算法对原始数据计算出的一个校验值。
接收方用同样的算法计算一次校验值,如果和随数据提供的校验值一样,说明数据是完整的,方可利用获取的数据进行运算和控制。
本设计采用的串口设置为:
波特率9600,8个数据位,1个停止位,无奇偶校验;
为保证数据的完整、正常,采用的通讯协议如下:
Arduino端发送的数据协议
包头
温度数据1
温度数据2
光线数据1
光线数据2
异或校验
包尾
0xff
Arduino读取温度值的千位和百位
Arduino读取的温度值的十位和个位
Arduino读取的光线值的千位和百位
Arduino读取的光线值的十位和个位
温度数据1、2和光线数据1、2的异或校验
0xfe
注:
由于arduino的模拟量端为10位的精度;
最大值为1024,但是串口一个数据为8位;
所以把采集到的数据拆分后再组合;
手机客户端发送的数据协议
控制器件编号
舵机角度数据
灯光亮度数据
0xaa或0xee
控制数据1
控制数据2
控制器件和舵机角度以及灯光亮度数据的异或校验
控制器件的编号规则:
舵机控制界面为0xaa,灯光控制界面为0xee;
arduino通过这个数据值来判别当前手机客户端处于哪个器件的控制界面;
5、成品展示
参考文献
[1]网络上查找资料
[2]班兹爱上Arduino人民邮电出版社2011
[3]程晨Arduino开发实战指南机械工业出版社2012
致谢
对于这次毕业论文的撰写,最需要感谢的是余训锋老师。
他在整个过程中都给予了我充分的帮助与支持。
余训锋老师不仅耐心地为我指出论文中的不足之处,对论文的改进提出宝贵的建议,而且还在我遇到困难时尽心地进行指点与解答。
在此借论文完成之际,表示由衷的感谢与敬意。
附录:
#include<
OneWire.h>
//调取单总线库函数
Servo.h>
//舵机库函数
DallasTemperature.h>
stdlib.h>
#defineONE_WIRE_BUS2//初始连接在单总线上的单总线设备
Servomyservo;
OneWireoneWire(ONE_WIRE_BUS);
DallasTemperaturesensors(&
oneWire);
unsignedintRPotPin=0;
//设定模拟输入引脚
unsignedintval=0;
//定义一个变量
unsignedcharservo=0;
//定义一个变量
unsignedchardiandeng=0;
unsignedcharobject=0;
unsignedintwendu=0;
bytewendugao=0;
bytewendudi=0;
bytevalhigh=0;
bytevallow=0;
intled=7;
Stringdata="
"
//字符串缓存
voidsetup(void)
{
myservo.attach(9);
//定义舵机引脚为9脚;
pinMode(led,OUTPUT);
//定义引脚为输出模式;
Serial.begin(9600);
//设置串口通信波特率;
sensors.begin();
//初始库;
}
voidloop(void)
{
data="
//上次接受到的值清0
while(Serial.available()>
0)//等新的串口数据
{
data+=char(Serial.read());
delay
(2);
//稳定作用
}
if(data.length()>
0)//串口数据处理,校验;
{
digitalWrite(led,HIGH);
if(data[0]==0xff&
data[4]==0xfe&
data[3]==data[1]^data[2])
object=data[1];
if(object==0xaa)
{servo=data[2];
if(object==0x