*本文已刊登在《无线电》2014年第6期

《搭建属于你的在线实时採集系统》中已经对HTML5平台有了初步的认识,并基于此向大家展示了怎样将採集到的数据上传至网络。实现实时观測。HTML 5是近十年来Web开发标准最巨大的飞跃。想必你已经体会到了HTML5的便捷之处,为了帮助大家更好在此平台上拓展应用,本文更加深入的探析“智能家居”与HTML5的完美结合,让家庭网络实时监控轻松实现。

关于智能家居 

2013年,太多公司包含三星和飞利浦在内都对智能家居动了念头。在CES的展览上三星展示了他们的新型智能清洁机器人,飞利浦的Hue智能LED灯泡,遭众多模仿的Nest的智能恒温器,结合智能控制、智能终端、智能显示的智能家居,将迎来很多其它创意。

全部这些。都让我们感受到智能家居已经脱离一种概念,进入到了下一个产品化阶段。但从用户的角度出发,很多其它人还是希望体验智能家居最主要的安全保障,便捷、经济、有用依旧是多数人关注的主题,所以家庭远程监护无疑得到很多其它青睐,特别是家中有老人、孩子,或者是你的宠物,发生了紧急状况,如何才干第一时间得知情况并避免事故的发生?

 图1
家庭监控系统示意图

(图片来自:http://dynews.zjol.com.cn/pic/0/11/43/44/11434423_934000.jpg)

从此角度出发,我想到DIY一个家庭网络实时监控系统,用手机或电脑连接网络。就能看到家中各个角落的情况。

今天我们介绍的内容就是,用一个摄像头 + 一块单片机就能够搞定的家居网络实时监控。搭载html5平台。实现更佳效果。

关于HTML5—WebSocket传输数据

网络实时訪问。图像画质是否可以达到理想值呢?

曾经的web界面在数据採集显示方面,都是採用的轮询方式。数据及时性不好,假设轮询过快,不但加大浏览器的负担,并且可能达不到你想要的效果。

这次之所以选择HTML5。因为新增的websocket API函数,差点儿完美的攻克了实时性的问题。

那么介于我们是採用单片机,将採集到的数据上传至网页,所以可负载的数据量收到缓存大小的限制,为解决此问题。 我们将採集到的视频数据直接输出JPEG格式的图片,暂设播放速率设置为5帧/秒,即画面每秒切换5幅。如此我们就能够实现视频的观看了。

网络摄像头系统演示

  1. 系统环境

a) 单片机:STM32F103RC,256K字节Flash,48K字节SRAM,2K字节EEPROM

b) 以太网控制器:W5500。SPI接口与单片机相连

c) 电源:USB供电

d) 硬件外设:OV2640摄像头

图2 W5500EVB与OV2640摄像头连接图

  1. 开发工具: IAR for ARM v5.41,这是我们project所使用的版本号。假设使用不同版本号的IAR,请对STM的库稍作调整。

看代码之前,我们还是先来了解一下整个的程序流程,流程图由一个主流程图和两个子流程图组成。例如以下图所看到的,程序採用轮询机制来处理请求和图像数据。

在硬件初始化完毕之后。将进行网络參数配置,这是要依据自己网络的情况来配置W5500的IP地址等网络參数,确保W5500能连接外网。本程序中,我们会使用W5500的两个socket资源,一个用来创建Http Server,这样在浏览器上输入配置的IP地址。浏览器作为client就能远程訪问我们的硬件了。还有一个用来创建Web Socket Server,与网页端建立通信链路,用来传输我们的摄像头图像数据。

attachment_id=6292" rel="attachment wp-att-6292" style="margin:0px; padding:0px; border:0px; font-family:inherit; font-size:undefined; font-style:inherit; font-variant:inherit; line-height:inherit; vertical-align:baseline; color:rgb(33,117,155); text-decoration:none">

图3 系统主流程图

attachment_id=6293" rel="attachment wp-att-6293" style="margin:0px; padding:0px; border:0px; font-family:inherit; font-size:undefined; font-style:inherit; font-variant:inherit; line-height:inherit; vertical-align:baseline; color:rgb(33,117,155); text-decoration:none">  

图4a Http处理函数流程图              图4b WebSocket处理函数流程图

当我们在浏览器上訪问硬件的IP地址,会向W5500发送http请求。W5500在收到请求后将html5的网页程序发送给浏览器,在网页程序中,浏览器会主动与硬件建立WebSocket连接。在完毕握手操作后,图像传输的数据通道即建立了。

这样每当硬件轮询到新的图像准备好后,就会通过WebSocket将图像数据发送给浏览器,浏览器收到数据后,在界面上绘制图像。

实际效果图请见图5。接下来将对摄像头的初始化和图像数据缓存程序,html5中在画布上绘制图像的程序以及WebSocket传输数据程序做具体介绍。

图5 系统浏览器端效果图

图6 系统实际工作情况

OV2640介绍

1.OV2640硬件简单介绍

attachment_id=6297" rel="attachment wp-att-6297" style="margin:0px; padding:0px; border:0px; font-family:inherit; font-size:undefined; font-style:inherit; font-variant:inherit; line-height:inherit; vertical-align:baseline; color:rgb(33,117,155); text-decoration:none">

图7 OV2640摄像头

OV2640像素输出最大支持200万像素,支持QCIF(176*144)、QVGA(320*240)、VGA(640*480)、1027*768、1600*1200等像素输出。

具备两种输出格式:

a、原始数据如RGB565,RGB RAW,YUV422。

b、JPEG压缩图像格式(可极大降低传输带宽,比如640*480分辨率的原图片大小在300KB左右, JPEG编码输出后大小仅约为16KB)

在本系统中,因为使用原始数据格式。图像文件过大(以RGB RAW为例。一帧640*480的图像文件大小为640*480*3=900Kbytes)。影响传输数据速率和更新图像的频率,进而影响浏览器的视频显示效果。其次stm32f103RBT6处理能力有限。无法做复杂的图像压缩算法,所以选择OV2640内部DSP压缩后的JPEG压缩图像格式是最好的选择。

MCU与OV2640的通信採用串行与并行结合,OV2640带有SCCB(Serial Camera Control Bus)双线串行接口,MCU通过SCCB接口配置和读取OV2640的信息。MCU通过并行总线的方式来接收OV2640的图像数据。系统的硬件连接图例如以下:

图8 系统硬件电路连接简图

当中,Y(2..9)为8位MSB(Most Significant Bit,最高有效位模式)并行总线,SDIO、SCLK为SCCB接口,PCLK为像素时钟输出管脚(每一个周期从并行总线上输出一个像素),VSYNC为列同步输出管脚(每帧图像发生一次跳变),HERF为行參考输出管脚(每一个周期总线从并行总线上输出一行图像数据)。

SVGA模式时序參考图例如以下:

图9 OV2640 SVGA模式下图像输出时序图

系统上电后,MCU配置OV2640的工作方式。在OV2640准备好图像后,VSYNC会被拉高一段时间。MCU通过PCLK上升沿中断按字节接收图像数据。接下来我们将对OV2640的初始化配置程序和图像数据缓存程序进行介绍。

2.OV2640程序介绍

初始化配置程序:

iic_init();/*初始化MCU I2C_2,与OV2640 SCCB接口通信*/

ov2640_jpeg_config(JPEG_640x480); /*设置输出图像格式*/

/* 设置COMS參数 */

ov2640_brightness_config(0×40); /*设置亮度模式:亮度+2*/

ov2640_auto_exposure(3); /*设置自己主动曝光等级
0-4*/

ov2640_contrast_config(0×28,0x0c); /*设置对照度:对照度+2*/

ov2640_black_white_config(0×00); /*设置黑白彩色模式:正常模式*/

ov2640_color_saturation(0×68,0×68); /*设置色饱和度:饱和度+2*/

ov2640_light_mode_config(OFFICE); /*设置场景模式:办公室*/

o2640_capture_gpio_init();/*初始化并行传输IO管脚*/

注:以上代码在main.c文件里

图像数据缓存程序:

u8 temp;

EXTI_ClearITPendingBit(EXTI_Line0);/*清除PC0(PCLK)中断*/

if(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_1)==0)/*HREF管脚为低*/

return;

temp =(u8)((GPIOC->IDR)>>8&0x00ff);/*读取一个字节图像数据*/

switch(jpg_flag)

{

case0:

if(temp==0xff)/*图像数据以0xff
0xd8开头*/

{

JPEGBuffer[4]=0xff;

jpg_flag=1;

}

break;

case1:

if(temp==0xd8)

{

JPEGBuffer[5]=0xd8;

jpg_flag=2;

JPEGCnt=6;

}

elseif(temp!=0xff)

jpg_flag=0;

break;

case2:

JPEGBuffer[JPEGCnt++]= temp;/*存储数据*/

if(temp==0xff)

jpg_flag=3;

break;

case3:

JPEGBuffer[JPEGCnt++]= temp;/*图像数据以0xff
0xd9结尾*/

if(temp==0xd9)

{

jpg_flag=4;

counter++;

}

elseif(temp!=0xff)

jpg_flag=2;

break;

case4:

break;

}

注:以上代码在websocket.c文件里

在中断函数中通过以上缓存数据就可以正确读取每一帧图像的数据了。

当中JPEGBuffer为一个全局的图像缓存区,WebSocket数据发送函数中检測到缓存区数据准备完成后,就能够将图像发送给浏览器了。

在Canvas上绘制图片

Canvas API中有趣的一面就是对图片的支持。我们能够借助drawImage函数。通过多种方法操作图片。drawImage有三种格式:

n  drawImage(image, dx, dy):将image URL指定的图片显示在dx,dy位置

n  drawImage(image, dx, dy, dw, dh):依据提供的显示宽度(dw)和显示高度(dh)缩放显示图片

n  drawImage(image, sx, sy, sw, sh, dx, dy, dw, dh):依据X,Y坐标和宽高(sx,sy。sw。sh)剪裁出图片的一部分显示出来。

以下开看看我们的网页程序里是怎样实现绘制图片的吧。

1.首先建立一张画布

<p><canvasclass=‘img filter-drop-shadow’id=‘cam’alt=‘W5500照相机‘></canvas></p>

2.定义画布的边距、宽高等信息

.img{margin:0 auto;display:block;margin-bottom:10px; width:640px;height:480px;cursor:pointer;}

3.为了在JavaScript中对canvas进行绘制。首先须要通过目标canvas的id获取绘制环境。代码须要通过id获取canvas元素,然后使用此元素的getContext方法获取其二维绘制环境的引用。

var canvas =document.getElementById(‘cam’);

var context =canvas.getContext(’2d’);

4.WebSocket接收到数据。并绘制图像

websocket.onmessage= function (evt)/*收到server消息。使用evt.data提取*/

{

var image = new Image();

image.onload= function ()

{

context.clearRect(0,0,canvas.width,canvas.height);/*清除画布矩形区域*/

context.drawImage(image,0,0,canvas.width,canvas.height);/*绘制宽度640px。高度480px的图像*/

}

image.src=URL.createObjectURL(evt.data);/*生成本图像数据的URL信息*/

}

可见我们使用了另外一种drawImage格式,指定缩放大小使其与画布大小刚好匹配,而我们从OV2640获取的图像恰好与画布大小同样。

注:以上代码在webpage.c文件里

WebSocket传输数据程序

在上一期的《搭建属于你的在线实时採集系统》中,我们具体介绍了WebSocket的使用和API函数。并分析了握手流程。在本篇文章中将不再赘述。这里将对数据较大的传输程序进行介绍。

if(handshaked)/*握手成功*/

{

uint32jpgLen=0;

uint32 send_len=0;

uint8firstByte=0×82;//FIN=1,
opcode=0×02: binary

uint8secondByte=126;//no
mask, extend length=2 bytes

uint8 extend[2]={0×00};//extend
header

while(jpg_flag!=4);/*图像缓存完成*/

jpgLen=JPEGCnt;

extend[0]=(jpgLen-4)/256;/*提取payload高8位*/

extend[1]=(jpgLen-4)%256;/*提取payload低8位*/

/*打包websocket数据包*/

JPEGBuffer[0]=firstByte;

JPEGBuffer[1]=secondByte;

JPEGBuffer[2]=extend[0];

JPEGBuffer[3]=extend[1];

while(jpgLen)

{

if(jpgLen>WS_PACKET_LEN)/*长度大于W5500发送缓存区大小(4K默认)*/

{

send(s,(uint8*)(JPEGBuffer+send_len), WS_PACKET_LEN);

send_len+= WS_PACKET_LEN;

jpgLen-= WS_PACKET_LEN;

}

else/*将数据包剩余的字节所有发送出去*/

{

send(s,(uint8*)(JPEGBuffer+send_len),jpgLen);

send_len+=jpgLen;

jpgLen-=jpgLen;

}

}

if(jpg_flag==4)/*发送完成后,重置图像採集标志位*/

jpg_flag=0;

printf(“.%d\r\n”,send_len);/*调试口打印本次数据包长度*/

}

上一篇中,因为数据包长度较小仅仅有7个字节,所以没有使用到扩展长度字节,因为OV2640採集到的图像经过压缩后,一帧图像的数据远大于125个字节,所以就须要用到扩展字节来表征数据长度,经过实測,本系统中OV2640在JPEG_480*640模式下,一帧图像大概12Kbytes左右,所以使用两个扩展字节(16位,最大可表示65535个字节)就能够了。依据上一篇数据包帧格式定义。当数据包第二个字节secondByte的后7位为126时表示使用2字节长度扩展,为127时表示使用8字节长度扩展。这里我们没有使用掩码,所以secondByte的第一位为0。在扩展字节后就是数据包的payload(图像数据)。在发送时,因为W5500每一个socket有自己的收发缓存区,在设备初始化时可配置,默认设置4K。所以一帧大小为12K的图像是无法一次发送出去的,程序的后半部分就是将数据包分割分几次发送。W5500也再次展示它硬件协议栈易于使用,高速传输的优越性能。使远程监控轻松实现。

总结

于此,摄像头 + 单片机 + HTML5的组合完毕了家庭网络监控的作品。

事实上非常多创意和想法都是源于各种功能组合,非常乐意与你分享我们的程序,希望你能发挥自己的想象力。组合出很多其它新鲜的web功能,体会DIY的价值与乐趣。

程序下载地址:

f=91&t=733" style="margin:0px; padding:0px; border:0px; font-family:inherit; font-size:undefined; font-style:inherit; font-variant:inherit; line-height:inherit; vertical-align:baseline; color:rgb(33,117,155); text-decoration:none">http://wizwiki.net/forum/viewtopic.php?f=91&t=733

搭建属于你的家庭网络实时监控–HTML5在嵌入式系统中的应用&#183;高级篇的更多相关文章

  1. 海康威视频监控设备Web查看系统(三):Web篇

    声明:本系列文章只提供交流与学习使用.文章中所有涉及到海康威视设备的SDK均可在海康威视官方网站下载得到.文章中所有除官方SDK以为的代码均可随意使用,任何涉及到海康威视公司利益的非正常使用由使用者自 ...

  2. 海康威视频监控设备Web查看系统(二):服务器篇

    声明:本系列文章只提供交流与学习使用.文章中所有涉及到海康威视设备的SDK均可在海康威视官方网站下载得到.文章中所有除官方SDK意外的代码均可随意使用,任何涉及到海康威视公司利益的非正常使用由使用者自 ...

  3. Linux网络实时监控配置

    Linux监控邮件发送配置 网络状态监控 网络状态:netstat 各个状态的总计,详情:以及重点端口的详细连接情况(22,25,80,3306,8080),打印客户端连接数最多的ip. 邮件报告当前 ...

  4. 搭建jmeter+influxdb+grafana压测实时监控平台(超详细,小白适用)

    1.前言 在使用jmeter做性能测试的时候,监控系统性能的时候,无论是使用插件还是报告生成,都没法实现实时监控.使用JMeter+Influxdb+Grafana可以实现实时监控. 本次环境搭建各软 ...

  5. 海康威视频监控设备Web查看系统(一):概要篇

    声明:本系列文章只提供交流与学习使用.文章中所有涉及到海康威视设备的SDK均可在海康威视官方网站下载得到.文章中所有除官方SDK意外的代码均可随意使用,任何涉及到海康威视公司利益的非正常使用由使用者自 ...

  6. 一步步教你用Prometheus搭建实时监控系统系列(一)——上帝之火,普罗米修斯的崛起

    上帝之火 本系列讲述的是开源实时监控告警解决方案Prometheus,这个单词很牛逼.每次我都能联想到带来上帝之火的希腊之神,普罗米修斯.而这个开源的logo也是火,个人挺喜欢这个logo的设计. 本 ...

  7. 一步步教你用Prometheus搭建实时监控系统系列(二)——详细分析拉取和推送两种不同模式

    前言 本系列着重介绍Prometheus以及如何用它和其周边的生态来搭建一套属于自己的实时监控告警平台. 本系列受众对象为初次接触Prometheus的用户,大神勿喷,偏重于操作和实战,但是重要的概念 ...

  8. 动环监控系统中B接口的实现

    动环监控系统简述 1.术语介绍 1.1 省集中监控中心-Province Supervision Center(PSC) 面向多FSU管理的高级监控层次,即省集中监控中心,通过开放的数据协议,连接监控 ...

  9. ntopng网络流量实时监控

    ntopng is the next generation version of the original ntop, a network traffic probe that monitors ne ...

随机推荐

  1. [POI2006]Periods of Words

    题目大意: 给定一个长度为$n(n\leq10^6)$的字符串$S$,定义一个串$S$的最大周期为一个不为$S$的字符串$Q$,满足$Q$为$S$的前缀且$S$为$QQ$的前缀.求字符串$S$的每一个 ...

  2. SpringAop名词解释+基于xml的配置

    1,AOP名词解释 2,AOP演示 (1)导包: (2)准备目标对象 package com.songyan.service; import org.aspectj.lang.ProceedingJo ...

  3. MySQL类型转换 使用CAST将varchar转换成int类型排序

    --使用CAST将varchar转换成int类型排序 select distinct(zone_id) from guild_rank_info order by CAST(zone_id as SI ...

  4. linux-设置环境变量-export

    Linux export命令用于设置或显示环境变量. 在shell中执行程序时,shell会提供一组环境变量.export可新增,修改或删除环境变量,供后续执行的程序使用.export的效力仅及于该次 ...

  5. Android开发之onCreate

    最近看了一些开发人员做的APP开发,虽然都实现了比较完美的功能,不过很多地方很是牵强!我觉得:作为一个合格软件工程师,最重要的不是你写过多少代码,而是你研究过多少代码!所以,我更倡导多研究系统原本定制 ...

  6. setSystemUiVisibility() 与 getSystemUiVisibility() 显示隐藏状态栏

    Android  4.4  Camera 源码里面有一个操作界面的方法: /** * If {@param visible} is false, this hides the action bar a ...

  7. ylb:事务处理

    ylbtech_sqlserver --1.定义三个变量分别保存你的姓名,年龄和身高,然后赋值并且输出 --DECLARE @name varchar(10) , @age int , @height ...

  8. 在eclipse中使用Lombok

    1.下载Lombok.jar http://projectlombok.googlecode.com/files/lombok.jar2.运行Lombok.jar: java -jar  D:\001 ...

  9. SQL语言中的COMMENT添加字段的注释

  10. java int转String全部方式的效率对照与深入解析

    在java中,大家肯定都会遇到int类型转String类型的情形,知其然知其所以然.总结加分析一下,int类型转String类型有下面几种方式: a+"" String.value ...