《物联网智能家居系统结业毕业论文.doc》由会员分享,可在线阅读,更多相关《物联网智能家居系统结业毕业论文.doc(49页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、-_天津电子信息职业技术学院天津电子信息职业技术学院毕业论文毕业论文题目题目 物联网智能家居系统物联网智能家居系统 姓姓 名名 专业班级专业班级 指导教师指导教师 完成时间完成时间 天津电子信息职业技术学院天津电子信息职业技术学院 制制2017.12017.1-_摘 要:随着经济的高速增长。建立一个低成本、高效率的智能家居系统已成为当今世界的一个热点话题。目前越来越多的智能家居产品出现在市场上,其中以基于电话网的智能安防系统居多。目前在我国,使用家庭电话的用户越来越少,而且电话线路受地域的影响严重容易损坏,所以这类产品局限性很大。随着电信 GSM 网络覆盖范围的无缝化、广阔化以及手机的日益普及
2、为基于 GSM 网络的智能家居系统提供了巨大的应用空间。本文设计了一种基于 GSM 网络的智能家居系统。本系统采用 cortexA8 为系统控制核心,对家庭中出现的意外情况使用各种传感器进行采集,然后通过 GSM 模块把采集到的信息发送给管理人员,管理员根据收到的信息发送相关指令给 GSM 模块来控制现场执行机构,完成意外情况的排除。关键词:智能家居 GSM 传感器 远程控制-_目录一、 绪论 -1(一) 智能家居概述-1(二) 智能家居网络构成-21、家居网络控制平台 -22、智能家居子系统 -23、智能家居网络的信号传输介质 -34、远程控制技术概括 -45、智能家居控制系统的国内外发展现
3、状 -5二、系统需求分析及方案 -6(一)应用程序功能需求分析-6(二)开发环境需求分析-61、 硬件环境 -62、 软件环境 -7三、硬件模块及其驱动设计实现 -7(一) 主控模块-7(二) 通信模块 -71、 TC35 模块简介-72、 TC35 模块与 cortexA8 连接方式-73、传感器模块 -8四、系统软件部分 -36(一)主程序及大致流程-361、温度监测线程 -372、视频监测线程 -383、报警流程 -39(二)短消息程序设计-401、 AT 指令介绍-402、PDU 编码规则-423、短信模式设置 -42-_4、短信的发送方法 -43五、测试及结论 -43(一)测试原则-
4、43(二)测试方案-43(三)结论-44参 考 文 献 -44-_一、 绪论21 世纪是信息化的时代,物联网新技术推动了人类文明的进步。随着人们生活水平的提高以及科技的高速发展,智能化家居已成为一种必然趋势而深入千家万户。智能化家居是利用电力自动化、计算机、网络通信、信息、结构化布线、无线等技术将多种设备应用和综合功能组成一个强大的完善的系统。它以住房为平台,同时兼备网络家电、家电设备自动化、建筑、通信、远程医疗、家庭办公、娱乐等功能,集结构、服务、系统、管理为一体的舒适、节能、安全、便利、高效、娱乐、环保的居住环境。本文介绍的智能化家居控制系统可以使得人们通过手机在任何时候、任意地点对家中的
5、任意电器(例如:热水器、空调、电饭煲、灯光等)进行远程控制。你可以在下班途中,预先将家中的空调打开、电饭煲煮好香喷喷的米饭、让热水器提前烧好热水,而这一切的实现都仅仅是靠一条短信完成。本系统采用 cortexA8 作为主控器件,远程控制是基于 GSM 网络短消息通信方式,AT 指令作为系统控制命令,cortexA8 通过对收到的信息进行解码来识别控制信号,用户只需向 TC35 模块发送相应指令即可实现远程控制操作。温度传感器完成现场信息的采集,cortexA8 对数据进行及时的处理,实现实时测控;短消息发送部分采用基于 GSM 模块 TC35 和 IT 公司的电平转换芯片MAX232 等器件构
6、成的移动终端的硬件电路,完成短消息收发功能。(一)(一) 智能家居概述智能家居概述进入 21 世纪,科学技术与生产力加速了社会的发展创造能力,随之而来的也是人类对于物质水平的大力需求,而居住的环境要求也成为了人们关注的领域,所以“智能化”这一概念也促使科技工作者们将其引入智能家居民应用方面的小区住宅以及小区建筑技术之中。由于计算机控制系统发展迅速,以及电子信息行业的发展成长快速,也大力促进了智能家居控制系统的产生。因为固定电话和互联网技术基本上是传统智能家居控制系统的技术核心,所以安装固定电话以及互联网成为了达到家庭用户传统智能家居控制系统的产生的根本硬件技术、以及硬件要求。但是随着电子技术、
7、智能通信技术以及网络技术发展日新月异的今天,基于 GSM 网络通讯体统的低成本无限制智能家居控制系统成为广大居民以及中国居民享受新一代智能家居控制系统的变革捷径。智能家居系统成为一种新兴的综合技术学科。智能家居系统也可被定义为-_一个控制过程,或者控制系统,利用现在被大多数科技人员已掌握的计算机技术、网络布线技术、网络通信系统将其糅合,使之成为融合在家居控制中的多个子系统,并使其智能的结合在一起。目前相比较其他时分多址技术手段而言,更加完美、成熟、应用更广泛的一种普及率很高的系统是 GSM(Global System for Mobile communication)系统。在我国,已建成的基本
8、覆盖全国的 GSM 数字蜂窝移动技术信息网,早已成为我国公众移动生活密不可分的一种技术之一。在 GSM 短信服务的基础上,智能家居控制系统是在移动网络通讯技术的短信应用功能的技术运用。由于 GSM 网络通讯系统在全国范围实现了联网以及漫游能力,所以它的网络功能很强大,用户无需另外搭建网络,因此,在 GSM 网络覆盖率达到全国范围的情况下,为客户省下了昂贵的网络搭建费用以及维护网络费用。同时,它对用户数量的限制也十分少,也为客户克服了一般智能家居控制系统中系统成本高、维护艰难、并且网络覆盖范围小以及用户组数量少的缺点。相比传统网络智能家居控制系统在网络通信覆盖率上具有较大的优势,加之 GSM 本
9、身就具有数据的输送功能,这也促成了 GSM 应用在广大生活中得到迅速普及。基于GSM 的无线通讯智能系统还具有双线传送数据的功能、性能稳定。为客户在远程操控以及用户控制设备提供了强大技术平台。远程操控系统应用广泛,遍及中国经济生活发展的各大领域。而且目前人们正在使用中的操控系统从成本、性能、稳定性、便捷性以及维护的难易方面基本都不能使人们最大程度的满意。所以,GSM 网络通信技术的提出大大的提升了智能家居控制系统的完善程度。(二)(二) 智能家居网络构成智能家居网络构成1、家居网络控制平台智能家居主控制平台是智能家居控制系统的“心脏”部分,等效的可以说是智能家居的核心。对方可以通过手机短信的方
10、式接受用户命令并实时操作,或者对对用户手机发送控制电器运转情况,对家庭总线和各个网络子系统实施连接,完成智能家居控制系统平台的链接构成。2、智能家居子系统智能家居系统的连接一般均为家电网络中的耗电类型的家电电器。例如冰箱、空调、电磁炉、热水器、电饭煲、电灯等家用电器。这些消耗电类型的家-_庭电器可以在现场立即布线互联构成智能家居系统,与主控家居智能平台相连接,再进行现场网络综合布线连接智能家居子系统,就可以由用户利用协议中的操作指令短信操作家庭中电器设备了。3、智能家居网络的信号传输介质智能家居网络通讯形式多彩多样,可以采用不同的传输介质传输网络通讯信号,大体上有电力线、电话线、双绞线、无线方
11、式。(1) 电力线基于电力线为传输介质的通信网络可以说是最方便的,因为现在家庭基本都已铺设供电源的电源线而且家中的电源线已经延伸到家庭生活的每个角落。而且,现在大部分家用电器设备都离不开电源。所以利用家中的电力线完成智能家居控制系统网络方案方便而且经济便宜。在国际上,首个实现家庭电器智能化的方案便是通过电力线作为信息传输载体的而达成的。(2) 电话线利用电话线作为网络信息传输载体起步虽然相较于电力线稍微晚一些,但是因为它具有布局简单、使用方便、安全性能好和易于大规模推广等优点,而且近期电话线的传输速率也完成了大幅度提升,所以它的应用和发展非常快,在美国已有成熟的产品。其中包括:3COM、Adv
12、anced MicroDevices、ATstatic int led_probe(struct platform_device *devices)struct resource *r;int ret;dev_t dev = MKDEV(led_major, led_minor);if(led_major)ret = register_chrdev_region(dev, count, devname);else-_ret = alloc_chrdev_region(led_major = MAJOR(dev);if(ret)return ret;cdev_init(ret=cdev_add(
13、if(ret)goto out_unreg_chrdev;atomic_set(myclass = class_create(THIS_MODULE, devname);if (IS_ERR(myclass)goto out_cdevdel;device_create(myclass, NULL, dev, NULL, “%s“%d“, devname, led_minor);r = platform_get_resource(devices, IORESOURCE_MEM, 0);if (r = NULL) goto out_class_destroy;GPG3_CON=r-start;r
14、= platform_get_resource(devices, IORESOURCE_MEM, 1);if (r = NULL) goto out_class_destroy;GPG3_DAT=r-start;return 0;-_out_class_destroy:device_destroy(myclass, dev);class_destroy(myclass);out_cdevdel:cdev_del(out_unreg_chrdev:unregister_chrdev_region(dev, count);return -EINVAL;int led_ioctl(struct in
15、ode *inode, struct file *filp, unsigned int cmd, unsigned long arg)unsigned int m=0x0;int tmp;if(cmd=CMDINIT)if(atomic_sub_and_test(1,if(NULL = gpg3con)return -ENOMEM;gpg3dat = ioremap(GPG3_DAT, 4);if(NULL = gpg3dat)return -ENOMEM;tmp=ioread32(gpg3con);tmp=tmpiowrite32(0x1111|tmp, gpg3con);tmp=iorea
16、d32(gpg3dat);tmp=tmp-_iowrite32(0x0|tmp, gpg3dat);atomic_inc(return 0;else m=cmd tmp=ioread32(gpg3dat);tmp=tmpiowrite32(m, gpg3dat);return 0;led 应用程序设计void led_init(void);函数功能:打开 led 设备并int led_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)函数功能:LED 报警输入参数:cmd 参数表示
17、那个灯亮void led_exit(void);函数功能:关闭 led 设备(2) 蜂鸣器-_图 3.2 pwm 电路图采用 platform 框架 自动获取设备号,生成设备节点。由于这个蜂鸣器是无源的,所以要想使其产生声音必须给他提供一个有一定频率的高低电平。所以这里我们采用 S5PC100 的 PWM 定时器来使蜂鸣器发出声音。static int pwm_probe(struct platform_device *devices)struct resource *r;int ret;dev_t dev = MKDEV(pwm_major, pwm_minor);if(pwm_major)
18、ret = register_chrdev_region(dev, count, devname);elseret = alloc_chrdev_region(pwm_major = MAJOR(dev);-_if(ret)return ret;cdev_init(ret=cdev_add(if(ret)goto out_unreg_chrdev;atomic_set(myclass = class_create(THIS_MODULE, devname);if (IS_ERR(myclass)goto out_cdevdel;device_create(myclass, NULL, dev,
19、 NULL, “%s“%d“, devname, pwm_minor);r = platform_get_resource(devices, IORESOURCE_MEM, 0);if (r = NULL) goto out_class_destroy;GPD_CON1=r-start;r = platform_get_resource(devices, IORESOURCE_MEM, 1);if (r = NULL) goto out_class_destroy;TCFG0=r-start;r = platform_get_resource(devices, IORESOURCE_MEM,
20、2);if (r = NULL) goto out_class_destroy;TCFG1=r-start;-_r = platform_get_resource(devices, IORESOURCE_MEM, 3);if (r = NULL) goto out_class_destroy;TCNTB1=r-start;r = platform_get_resource(devices, IORESOURCE_MEM, 4);if (r = NULL) goto out_class_destroy;TCMPB1=r-start;r = platform_get_resource(device
21、s, IORESOURCE_MEM, 5);if (r = NULL) goto out_class_destroy;TCON=r-start;return 0;out_class_destroy:device_destroy(myclass, dev);class_destroy(myclass);out_cdevdel:cdev_del(out_unreg_chrdev:unregister_chrdev_region(dev, count);return -EINVAL;int pwm_ioctl(struct inode *inode, struct file *filp, unsig
22、ned int cmd, unsigned long arg)int tmp;-_if(cmd=CMDINIT)if(atomic_sub_and_test(1,if(NULL = gpdcon1)return -ENOMEM;tcfg0 = ioremap(TCFG0, 4);if(NULL = tcfg0)return -ENOMEM;tcfg1 = ioremap(TCFG1, 4);if(NULL = tcfg1)return -ENOMEM;tcntb1 = ioremap(TCNTB1, 4);if(NULL = tcntb1)return -ENOMEM;tcmpb1 = ior
23、emap(TCMPB1, 4);if(NULL = tcmpb1)return -ENOMEM;gtcon = ioremap(TCON, 4);if(NULL = gtcon)return -ENOMEM;tmp=ioread32(gpdcon1);tmp=tmpdata = kzalloc(sizeof(struct lm75_data), GFP_KERNEL);if (!data)return -ENOMEM;i2c_set_clientdata(client, data);mutex_init(set_mask = 0;clr_mask = (1 dev, “Cant read co
24、nfig? %dn“, status);goto exit_free;data-orig_conf = status;new = status new |= set_mask;if (status != new)lm75_write_value(client, LM75_REG_CONF, new);dev_dbg(devn = MKDEV(lm75_major, lm75_minor);-_if(lm75_major)status = register_chrdev_region(devn, count, devname);elsestatus = alloc_chrdev_region(l
25、m75_major = MAJOR(devn);if(status)return status;cdev_init(status=cdev_add(if(status)goto out_unreg_chrdev;myclass = class_create(THIS_MODULE, devname);if (IS_ERR(myclass)goto out_cdevdel;device_create(myclass, NULL, devn, NULL, “%s“%d“, devname, lm75_minor);goto out;out_cdevdel:cdev_del(out_unreg_ch
26、rdev:unregister_chrdev_region(devn, count);exit_free:kfree(data);out:-_return status;static int lm75_read_value(struct i2c_client *client, u8 reg)int value;if (reg = LM75_REG_CONF)return i2c_smbus_read_byte_data(client, reg);value = i2c_smbus_read_word_data(client, reg);return (value 7;n=n-1;n=n;n=n
27、n=-n;elsen=n7;tmp=n*0.5;(4)视屏模块-_图 3.4 V4L2 流程V4L2 采用流水线的方式,操作更简单直观,基本遵循打开视频设备、设置格式、处理数据、关闭设备,更多的具体操作通过 ioctl 函数来实现。打开视频设备在 Linux 中,设备被看做一个文件。使用 open 函数打开视频设备。打开设备有两种方式:1、用非阻塞模式打开int Fd;Fd = open(“/dev/video2“, O_RDWR | O_NONBLOCK, 0);2 用阻塞模式打开:Fd = open(“/dev/video2“, O_RDWR, 0);应用程序能够使用阻塞模式或非阻塞模式打
28、开视频设备,如果使用非阻塞模式调用视频设备,即使尚未捕获到信息,驱动依旧会把缓存(DQBUFF)里的-_东西返回给应用程序。设定属性及采集方式打开视频设备后,可以设置该视频设备的属性,例如裁剪、缩放等。这一步是可选的。在 Linux 编程中,一般使用 ioctl 函数来对设备的 I/O 通道进行管理:int ioctl (int _fd, unsigned long int _request, ./*args*/) ;在进行 V4L2 开发中,常用的命令标志符如下(some are optional): VIDIOC_REQBUFS: 分配内存 VIDIOC_QUERYBUF:把 VIDIOC
29、_REQBUFS 中分配的数据缓存转换成物理地址 VIDIOC_QUERYCAP:查询驱动功能 VIDIOC_ENUM_FMT:得到视频设备支持的视频格式 VIDIOC_S_FMT: 设置视频设备的频捕获格式 VIDIOC_G_FMT: 得到视频设备的频捕获格式 VIDIOC_TRY_FMT: 视频设备支持的显示格式 VIDIOC_QBUF: 从缓存中读取数据 VIDIOC_DQBUF: 数据重新进入缓存队列 VIDIOC_STREAMON:开始视频获取VIDIOC_STREAMOFF:结束视频获取 VIDIOC_QUERYSTD:检查当前视频设备支持的标准,例如 PAL 或 NTSC。 在亚
30、洲,一般使用 PAL(720X576)制式的摄像头,而欧洲一般使用NTSC(720X480) ,使用 VIDIOC_QUERYSTD 来检测:v4l2_std_id std;do ret = ioctl(fd, VIDIOC_QUERYSTD, while (ret = -1 switch (std) case V4L2_STD_NTSC:/case V4L2_STD_PAL:/-_设置视频捕获格式当检测完视频设备支持的标准后,还需要设定视频捕获格式,结构如下:struct v4l2_format fmmt;memset ( fmmt.type = V4L2_BUF_TYPE_VIDEO_CA
31、PTURE;fmmt.fmt.pix.width = 720;fmmt.fmt.pix.height = 576;fmmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;fmmt.fmt.pix.field = V4L2_FIELD_INTERLACED;if (ioctl(Fd, VIDIOC_S_FMT, v4l2_format 结构定义:struct v4l2_formatenum v4l2_buf_type type; unionstruct v4l2_pix_format pix; struct v4l2_window win; struct v4l
32、2_vbi_format vbi; _u8 raw_data200; fmt;struct v4l2_pix_format_u32 width; -_u32 height; _u32 pixelformat; enum v4l2_field field;_u32 bytesperline; _u32 sizeimage;enum v4l2_colorspace colorspace;_u32 priv; ;分配内存然后为从摄像头捕获的图像分配内存:struct v4l2_requestbuffers req;if (ioctl(Fd, VIDIOC_REQBUFS, v4l2_requestb
33、uffers 结定义:struct v4l2_requestbuffers_u32 count; enum v4l2_buf_type type; enum v4l2_memory memory; _u32 reserved2;得到视频缓存的内存空间使用 VIDIOC_REQBUFS 命令,来得到 count 个缓存,然后通过使用VIDIOC_QUERYBUF 命令来得到分配的缓存的地址,再用 mmap 函数把地址映射为应用程序中的绝对地址,最后把得到的缓存放入缓存队列以便循环利用。typedef struct VideoBuffer void *start;-_size_t length;
34、VideoBuffer;VideoBuffer* buffers = calloc( req.count, sizeof(*buffers) );struct v4l2_buffer buf;for (numBufs = 0; numBufs 255) r0 = 255;if (r0 255) g0 = 255;if (g0 255) b0 = 255;-_if (b0 255) r1 = 255;if (r1 255) g1 = 255;if (g1 255) b1 = 255;if (b1 3)2)3)3)2)3)dest;dest-buffer = (JOCTET *) (*cinfo-
35、mem-alloc_small)(j_common_ptr) cinfo,JPOOL_IMAGE, OUTPUT_BUF_SIZE * sizeof(JOCTET);*(dest-written) = 0;dest-pub.next_output_byte = dest-buffer;dest-pub.free_in_buffer = OUTPUT_BUF_SIZE;METHODDEF(boolean) empty_output_buffer(j_compress_ptr cinfo) mjpg_dest_ptr dest = (mjpg_dest_ptr) cinfo-dest;memcpy
36、(dest-outbuffer_cursor, dest-buffer, OUTPUT_BUF_SIZE);dest-outbuffer_cursor += OUTPUT_BUF_SIZE;*(dest-written) += OUTPUT_BUF_SIZE;dest-pub.next_output_byte = dest-buffer;dest-pub.free_in_buffer = OUTPUT_BUF_SIZE;return TRUE;METHODDEF(void) term_destination(j_compress_ptr cinfo) mjpg_dest_ptr dest =
37、(mjpg_dest_ptr) cinfo-dest;size_t datacount = OUTPUT_BUF_SIZE - dest-pub.free_in_buffer;-_memcpy(dest-outbuffer_cursor, dest-buffer, datacount);dest-outbuffer_cursor += datacount;*(dest-written) += datacount;void dest_buffer(j_compress_ptr cinfo, unsigned char *buffer, int size,int *written) mjpg_de
38、st_ptr dest;if (cinfo-dest = NULL) cinfo-dest =(struct jpeg_destination_mgr *) (*cinfo-mem-alloc_small)(j_common_ptr) cinfo, JPOOL_PERMANENT,sizeof(mjpg_destination_mgr);dest = (mjpg_dest_ptr) cinfo-dest;dest-pub.init_destination = init_destination;dest-pub.empty_output_buffer = empty_output_buffer;
39、dest-pub.term_destination = term_destination;dest-outbuffer = buffer;dest-outbuffer_size = size;dest-outbuffer_cursor = buffer;dest-written = written;摄像头采集的 YUYV 格式转换为 JPEG 格式:buf 为设备获取的原始数据首地址,buffer 为压缩后的数据首地址。size 为像素值。quality 为压缩质量。int compress_yuyv_to_jpeg(unsigned char *buf, unsigned char *buf
40、fer, int size,int quality) struct jpeg_compress_struct cinfo;struct jpeg_error_mgr jerr;JSAMPROW row_pointer1;-_unsigned char *line_buffer, *yuyv;int z;static int written;line_buffer = calloc(WIDTH * 3, 1);yuyv = buf; /将 YUYV 格式的图片数据赋给 YUYV 指针printf(“compress start.n“);cinfo.err = jpeg_std_error(jpe
41、g_create_compress(dest_buffer(cinfo.image_width = WIDTH;cinfo.image_height = HEIGHT;cinfo.input_components = 3;cinfo.in_color_space = JCS_RGB;jpeg_set_defaults(jpeg_set_quality(jpeg_start_compress(z = 0;while (cinfo.next_scanline 8;-_g = (y - (88 * u) - (183 * v) 8;b = (y + (454 * u) 8;*(ptr+) = (r
42、255) ? 255 : (r 255) ? 255 : (g 255) ? 255 : (b 打开设备函数;static FB *get_fb_msg(FB *fb);-_-得到屏幕信息;static FB *fb_mmap(FB *fb);-将设备映射到用户空间;static FB *clean_screen(FB *fb,POINT *start,POINT *end,unshort color);-清除 start 到 end 之间的块儿装屏幕为 color 颜色;static int show_word(FB *fb,const unchar *word,POINT *point,u
43、nshort color);-在给定的点 location 显示 color 颜色的字符;static int drow_horizontal_line(FB *fb,POINT *start,POINT *end,unshort color);-在给定的 start 到 end 之间画一条横线 static int drow_vertical_line(FB *fb,POINT *start,POINT *end,unshort color);-在给定的 start 到 end 之间画一条竖线static unchar *find_word(const char *str);-在 09(包含小数点)之间找字库中对应的数组static FB *fb_munmap(FB *fb)-解除映射封装给应用层的函数FB *screen_init(FB *fb):将打开设备到映射以及显示固定文字以及屏幕划线分割这些准备工作做好;