物联网跟我动手做系列教程—第三篇 实验三如何用arduino+ethernet shield与yeelink结合5分钟实现web远程家电控制(代码已更新)

作者: · 41条评论 标签:

实验内容:很多朋友都有这样的想法,能不能通过网页,直接从任何一台计算机,控制和访问自己的单片机或者arduino板呢?这个有趣的功能,相信很多的电子爱好者都可能会想,这个功能如果能实现,是不是意味着就能在web页面,直接通过点击按钮,就能够通过互联网完成对arduino板上的资源甚至是挂接到arduino板上的设备的控制。好像听起来有点耳熟?这是不是就是当下很火爆的数字家庭概念吗?是的没错,如果arduino驱动的是继电器或者可控插座,那么,我们就能很容易的在web上控制普通家用电器啦,想象一下,下班之前,在电脑上登陆自己的yeelink账号,然后点击“热水器烧水”,回家就能洗上舒舒服服的热水澡啦!

 

硬件要求:

Arduino主板
以太网板(考虑到官方W5100以太网板的价格比较贵,这次再介绍一款SPI通信方式的低成本小板,ENC28J60,参加下图模块的模样和与arduino的连接方式进行连接,并且从这个链接获取ENC的网络函数驱动库并安装即可:

http://geek-workshop.com/forum.php?mod=attachment&aid=NDc1M3w4OTExYjg1M3wxMzM5MzM4Mzk1fDgwN3wyMDA%3D

原理介绍:

为了实现远程控制,为简便起见,我们先讲讲如何web遥控arduino UNO板上的LED灯开关。

yeelink平台提供了两种方式,一种是arduino/单片机通过直接socket网络连接的办法,连入平台上,保持和服务器的长连接,这种方法控制的实时性相对较强;另外一种办法是arduino作为客户端,定期的向服务器查询传感器(LED)的当前值,如果我们要改变arduino的状态(如点亮LED),只需改变当前传感器的值(其实是发送HTTP的post命令,更新一下当前的设备状态),则arduino在定时周期到的时候,发出(HTTP  get)命令来获取当前LED状态的时候,发现最近的值有变化(从0变为1)的时候,则相应的改变驱动LED的IO口状态,从而实习远程控制,这里注意,在arduino板上,如果是触发性的操作(只操作一次),则可以在get数据并操作好后,直接发送POST改变服务器上吗的传感器状态,保证不会在arduino端重复触发。

首先,照例我们要先申请到yeelink的API-KEY才可以进行:

如何免费获取API-KEY,和如何添加设备,请移步 快速入门 来开始吧。

第一步: 注册之后,增加一个开关类的传感器

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

第二步,获取这次插入的控制设备的设备号和传感器号:如下图来说,就是设备号=63,传感器号=57

 

 

 

 

 

 

 

 

 

第三步,好了,控制按钮安装完毕,下面,将第七个PIN和GND之间连上电阻和LED灯,下载下面的arduino程序,更改三个地方,就可以通过点击网页上的按钮,进行控制了。(居然这么简单???是的,就是这么简单…下面想想你能怎么玩更爽吧)

arduino程序中需要修改的地方有

 

 

 

程序中需要改的地方是:
1.APIKEY: 这个需要更换成你自己账号的APIKEY
2.DEVICEID :这个需要换成设备号
3.SENSORID:这个需要换成传感器号

OK,就这些了,5分钟内学会如何做家庭电器控制,你行的!

另外,需要注意一点,下文中的ethernet shield是需要你家中的路由器开启DHCP功能的,如果没有开启,可以参考将
1. 代码中添加 byte ip[] = { 192, 168, 1, 12 };  (根据网络环境更改)
2. 将Ethernet.begin(mac) 替换成Ethernet.begin(mac, ip);

从这下载程序YeelinkPowerSwitch

具体的程序在下面

/*
Yeelink 网页远程控制Arduino演示代码
1. 使用arduino UNO和 ethernet shield
2.  使用数字7管脚网页控制LED灯

*/

#include <SPI.h>
#include <Ethernet.h>
#include <Wire.h>
#include <math.h>

byte buff[2];

// for yeelink api
#define APIKEY “4bb08000082a070000e2e3c580000000″ //更换 yeelink api key
#define DEVICEID 63 // 更换设备IDreplace your device ID
#define SENSORID 57 // 更换传感器IDreplace your sensor ID

// 分配MAC地址.
byte mac[] = { 0x00, 0x1D, 0x72, 0x82, 0x35, 0x9D};
// 初始化以太网库:
EthernetClient client;
char server[] = “api.yeelink.net”; // yeelink API的域名

unsigned long lastConnectionTime = 0; // last time you connected to the server, in milliseconds
boolean lastConnected = false; // state of the connection last time through the main loop
const unsigned long postingInterval = 3*1000; // delay between 2 datapoints, 30s
String returnValue = “”;
boolean ResponseBegin = false;

void setup() {
pinMode(7, OUTPUT);

Wire.begin();
// start serial port:
Serial.begin(57600);
// start the Ethernet connection with DHCP:
if (Ethernet.begin(mac) == 0) {
Serial.println(“Failed to configure Ethernet using DHCP”);
for(;;)
;
}
else {
Serial.println(“Ethernet configuration OK”);
}
}

void loop() {
// 如果发现有网络数据如何处理

if (client.available()) {
char c = client.read();
// Serial.print(c);
if (c == ‘{‘)
ResponseBegin = true;
else if (c == ‘}’)
ResponseBegin = false;

if (ResponseBegin)
returnValue += c;
}
if (returnValue.length() !=0 && (ResponseBegin == false))
{
Serial.println(returnValue);

if (returnValue.charAt(returnValue.length() – 1) == ‘1’) {
Serial.println(“turn on the LED”);
digitalWrite(7, HIGH);

}
else if(returnValue.charAt(returnValue.length() – 1) == ‘0’) {
Serial.println(“turn off the LED”);
digitalWrite(7, LOW);
}
returnValue = “”;
}
// if there’s no net connection, but there was one last time
// through the loop, then stop the client:
if (!client.connected() && lastConnected) {
Serial.println();
Serial.println(“disconnecting.”);
client.stop();
}

// if you’re not connected, and ten seconds have passed since
// your last connection, then connect again and send data:
if(!client.connected() && (millis() – lastConnectionTime > postingInterval)) {
// read sensor data, replace with your code
//int sensorReading = readLightSensor();
Serial.print(“yeelink:”);
//get data from server
getData();
}
// store the state of the connection for next time through
// the loop:
lastConnected = client.connected();
}

 

// this method makes a HTTP connection to the server and get data back
void getData(void) {
// if there’s a successful connection:
if (client.connect(server, 80)) {
Serial.println(“connecting…”);
// send the HTTP GET request:

client.print(“GET /v1.0/device/”);
client.print(DEVICEID);
client.print(“/sensor/”);
client.print(SENSORID);
client.print(“/datapoints”);
client.println(” HTTP/1.1″);
client.println(“Host: api.yeelink.net”);
client.print(“Accept: *”);
client.print(“/”);
client.println(“*”);
client.print(“U-ApiKey: “);
client.println(APIKEY);
client.println(“Content-Length: 0″);
client.println(“Connection: close”);
client.println();
Serial.println(“print get done.”);

}
else {
// if you couldn’t make a connection:
Serial.println(“connection failed”);
Serial.println();
Serial.println(“disconnecting.”);
client.stop();
}
// note the time that the connection was made or attempted:
lastConnectionTime = millis();
}

 

物联网跟我动手做系列教程—第二篇 Yeelink平台介绍

作者: · 发表评论 标签:

Yeelink平台的设计目的,就是要成为物联网世界的开放服务提供商,完成对传感器数据的接入管理,数据存储,以及将数据随时显示给客户。

为了解决上文中提到的物联网服务器所必须解决的几个关键问题,yeelink开放和运维团队做了大量的工作,来保证可靠,安全,高质量的提供物联网公共服务,下面,先从技术层面上,来分析一下为何Yeelink具备这种提供高性能物联网服务的能力。

首先Yeelink系统在设计之初,就充分考虑了超大并发接入的可能性。在设计接入服务系统的时候,参照新浪微博的标准(峰值3000条/秒,目前Cosm的平均值是300条/秒),Yeelink基于团队多年在开发和维护电信级服务器的经验,进行大量的设计优化,那就是,做到平台与应用服务的隔离,一个http的post服务,在经过接入网关的处理后,交给专门的服务模块进行处理,而一个完整的传感器数据存储操作,由运行在多个机器上的服务组件协同处理,有效的达到了负载上的均衡,而且很容易通过增加机器扩充容量,在理念的实现上,Yeelink采用了Node.js这一比较流行的开发语言用来提供传感器接入服务,随着雅虎,微软,Linkedin,和国内的淘宝网开始大量的采用该技术开发项目,已经证明了该技术在处理高并发,实时性和开发速度上的卓越优势,同时由于Yeelink的前段同样大量使用Javascript,所以在调试时服务器系统和前段可以以同一种语言调试,大大提高了解决问题的速度。

数据接入以后,在解决数据的存储方面,Yeelink使用了Hadoop这个分布式处理框架有针对性的搭建了一个高并发,海量存储,高可扩展性的云存储服务中心,针对传感器数据在时间上具有连续性,数据插入时速度相对恒定,数据需要快速取回(展示)等特点,Yeelink做出大量的优化工作,使得系统能够非常稳定健壮的提供数据存储的优质服务。

在对用户的数据获取手段的支持上,我们使用了基于RESTful架构的开放API体系,通过统一的web service,使得用户在取回和管理自己的传感器数据时,界面非常友好和简单,可以使用各种语言实现客户端系统,这样很很方便在当前的移动智能应用流行的环境下,提供个性化服务,不管是在android,iOS等操作系统上,使用Yeelink提供的界面组件API,可以非常快速的搭建起属于自己独一无二的APP,加速您想法的实现速度,特有的win7桌面Widget,和论坛插件,博客插件,能够方便的将您的传感器数据,共享到社交网络。

另外,除了完成数据存储工作外,通过Yeelink的数据事件引擎,传感器数据不再是冰冷的节点,我们考虑到您的需求,定制了大量的规则触发应用,譬如在传感器达到阈值的时候,自动触发类似电信API如短消息,语言电话,彩信等应用,也能按照您所定制的数据类型,向指定的其他设备转发控制信息,从而方便的实现M2M控制,更让人兴奋的是,实现这一切,无需任何编程,通过点击网页的按钮和填写资料,就能轻松实现。

了解了这么多,是不是想亲自动手试试Yeelink到底有多好玩呢?下面,我们就试试如何通过网页模拟传感器数据来对yeelink平台进行测试吧!是的,如果你能猜到的话,整个测试过程,无需编写任何代码,也不使用任何硬件系统。

下面,我就简单介绍一下,如何使用web浏览器进行开放平台的使用测试:

请跳到yeelink平台快速入门手册,迅速开始您的物联网梦想之旅吧!

http://www.yeelink.net/develop/quickstart

物联网跟我动手做系列教程—第一篇–物联网公共服务平台介绍

作者: · 发表评论 标签:

物联网理念如今已经逐渐深入人心,并随着传感器技术,通信技术和互联网技术的发展逐渐触及到社会的每一个角落,物联网存在的意义在于,它彻底改变了人与人创造的机器世界和周边环境的交流方式,从此,人们能够更自由,更简单的获取各种各样的信息,也更容易的与机器和进行交互,甚至是让机器与机器(M2M)之间,建立通信和对话的桥梁,让机器更好的为人类服务。随着物联网主机进入大数据(Big Data)时代,通过对海量的传感器数据进行存储,并提取有价值的信息和形成模型,对科研,城市管理,自然科学等方面研究,都有着重要的意义。一些大型公司所号召的物联网应用,如IBM的智慧星球,Google的智能眼镜,NASA的星球皮肤等等项目,都已经逐渐获取了市场和人们的认可。

 

那物联网具体有哪些表现形式,他又能为人们提供哪些方面的好处呢?最典型的应用,就是使用RFID或者二维码标签,对各种各样的物体进行唯一性的标示,使得物品从生产和销售,回收流程中,能够被自始至终的监控,譬如对农产品的产地进行精确回溯,对生产机械的制造和运行进行监控,这样除了能够对产品的质量问题快速定位外,还赋予了用户增加更多的能力,比如远程对机械的工作情况采集甚至控制。

 

一个典型意义的物联网应用,一般要完成传感器数据的采集,存储,和数据的加工和处理这三项工作,举例来说,对于驾驶员,希望获取去目的地的路途上的路况,为了完成这个目标,就需要有大量的交通流量传感器对几个可能路线上的车流和天气状况进行实时的采集,并存储到集中的路况处理服务器,应用在服务器上通过适当的算法,从而得出大概的到达时间, 并将处理的结果展示给驾驶员。所以,我们能得出大概的系统架构设计可以分为如下三部分:

  1. 传感器硬件和接入互联网的通信网关(负责将传感器数据采集起来,发送到互联网服务器)。
  2. 高性能的数据接入服务器和海量存储。
  3. 特定应用,处理结果展现服务。

 

从物联网的应用形态中,我们能看出,针对具体应用的不同,我们关心的传感器数据是各有不同的,譬如,对安防应用来说,我们希望能够读取到家庭里布置的门磁,红外灯传感器的数据,而对于海洋研究来说,就希望能够读取到特定海域的气候信息,对制造风电的朋友,则希望能够获取设备的工作状态,所以,针对不同的业务类型,传感器的需求可谓是千差万别,而数据上传的手段,根据对费用,便利程度的要求不同,有GPRS,wifi,网线,工业总线等等多种选择,差别的比较大。

 

在我们成功采集到传感器数据后,需要解决的另外一个问题就是传感器数据的存储,几乎任何一个典型的物联网应用,都需要处理大量的数据,这对服务器的设计提出了相当高的要求,第一,需要能够同时承载数以万计,乃至数十万的同步网络数据传输,就是首先要把这些数据收好;第二能够将这些海量级的数据,以一定的规则存储好,在存的同时,还要考虑和解决数据取回的问题,举例说,500个传感器,以10秒一条的速度上数据,在1年能够达到上亿条的数据记录,这时候,如何实现数据的快速查询和取回就变得极具挑战性,除此之外,服务器还需要考虑解决安全性,可维护性,不间断的服务能力等多种问题。

 

数据的取回和展示也是一个非常关键的问题,随着移动互联网的兴起,人们已经不满足仅仅从web浏览器去获取数据,更多的希望能从智能手机,平板电脑等媒介,便利的获取信息,除了传感器数据给人看之外,物联网的传感器数据还可以为远程的机器或者设备直接获取,并按照既定规则直接执行相应的动作,譬如大型养鸡场,根据鸡笼的文档变化,自动调节恒温系统;办公大楼根据大量光照传感器的读数和感知各个楼层的人数,自动调整灯光系统的水平,这些都是典型的机器直接使用传感器数据的例子。

 

从上面的介绍我们能看出,尽管存在着形形色色的物联网应用,但是它们都需要有一个基于互联网的平台加以支撑,而这个平台的稳定性,可靠性,易用性,对该物联网项目的成功实施,有着非常关键的作用,所以,类如IBM,CISCO,HP等IT基础设施和解决方案提供商,包括国内的一些科技行业巨头和科研院所,都提出了各种各样的平台方案,利用云计算和云存储的理念,解决上述的提到的服务共性问题;但是遗憾的是,到目前为止,这些方案和解决思路都是封闭的,是为了解决特定问题营运而生的,他们并未向社会开放使用,好比天上的神仙,看起来很漂亮,但是百姓们却除了膜拜无事可做。

 

那么,除了国际巨头之外,存不存在这样的公司,他们自己完成物联网服务平台的主要基础功能开发,然后开放接口,为公众,特别是具有一定电子或软件知识的爱好者或者中小企业服务呢?事实上,随着世界上物联网理念的逐渐普及和深入人心,为人群重大的草根阶层量身设计的物联网公共服务平台已经逐渐出现,几个国际上规模比较大的平台有Scinan,Arrayent, COSM/Pachube等,国其中cosm是目前世界上用户量最大的开放物联网平台,他提供了一系列的数据上传手段,让每个人都能通过简单的开源硬件或者单片机,实现传感器数据的上传和存储,还提供了一系列的数据展现方式,比如dashboard,用来按时间轴多个传感器数据到一个同一个平台上(图一),另外,通过和视频识别技术和增强现实技术,移动应用的结合,还能够使用android手机对传感器设备进行识别,并自动将获取的传感器数据叠加到手机显示层上(图二),是不是很神奇呢?

图一:COSM将多个传感器的历史数据反映到通一个WEB数据面板上

图二:增强现实(AR)技术讲传感器数据通过3D投影实时叠加到手机屏幕

国内的yeelink.net平台,是目前国内第一家对公众开放的物联网公共服务平台,目标是服务中国的物联网爱好者,使得中小型的企业和电子爱好者们能够非常简单的使用物联网平台,下面,我们将详细的介绍一下yeelink平台和如何使用它来完成您的梦想。

物联网跟我动手做系列介绍——目录

作者: · 2条评论 标签:

物联网跟我动手做系列教程分为3篇

  1. 物联网公共服务平台介绍篇

a)         主要内容是介绍物联网基本概念,组成,还有物联网服务器在的一些国际发展趋势,以及当前的主要应用领域,使用范围,还有一些案例。

  1. Yeelink平台篇

a)         主要介绍Yeelink平台的设计理念,使用的开发工具,系统架构,能够提供的服务,如何注册账号,并进行测试性的尝试。

  1. Yeelink平台动手篇
    1. 如何用arduino+PC工具实现光照传感器数据上传和显示。
    2. 如何用arduino+Ethernet shield进行温度数据的上传和如何触发email报警。

物联网跟我动手做系列教程—第三篇 实验一如何用arduino和PC机连接到yeelink

作者: · 43条评论 标签:

对于经常写程序来捕获传感器数据,但是有苦于硬件没法直接联网的你来说,是否期望有款工具,能直接将你从串口上读取到的数据发布到yeelink物联网平台上呢?不用急,我们今天就发布了一款这样的小工具,以期能解决你的烦恼。

这款名为yeelink串口工具的程序已经在Github上开源了(https://github.com/dapingliu/serial_2_yeelink),同时你也可以直接下载可执行程序,目前支持Windows平台(XP, 2003, win7)上运行。

程序运行主界面

如何让它工作?

这应该是你最关心的问题,下面是详细的步骤.

1. 在你的硬件上,将读取到的传感器数据作为字符串独立一行打印出来,在行首加上”yeelink:”. 比如在Arduino上使用

    Serial.print("yeelink:");
    Serial.println(value);

2. 运行yeelink串口工具,选择与你硬件连接的串口和波特率,当然,还少不了要用线缆连起来:)

3. 登录yeelink.net网站,进入用户中心,在 我的设备 >> 设备管理 中找到即将要上传的数据的传感器,如果你还没有添加,这里有快速开始手册教你如何添加。将其中的URL复制到工具的上传地址一栏。

在网站用户中心,帐户 >> 我的帐户设置 中找到API KEY一栏。将其复制到工具的API-KEY中,然后点击连接服务器。

至此,你的工作已经完成了,程序会打印出log供你分析出现的问题。如果没有异常,你应该会见到如前面主界面所示的结果。这时候,当你的硬件往串口上写入数据,本工具就会检测到,并提取出来,然后上传到yeelink上你指定的传感器地址。

结束语

程序上传的数据会在网页上绘制出曲线图,当你看到这样的数据图是是不是很激动呢。原本很复杂的过程现在变得如此简单,没错,就是如此简单。还犹豫什么,马上试一试。

 

物联网跟我动手做系列教程—第三篇 实验二如何用arduino+ethernet shield与yeelink结合5分钟实现传感器数据web上传

作者: · 31条评论 标签:

本文介绍如何在Arduino上实现自己的Yeelink客户端,以便将采集到的传感器数据上传到Yeelink平台上。该例程会每隔30s采集一次传感器数据并发送到yeelink服务器。

硬件需求
Arduino主板
Ethernet板
BH1750光强传感器模块(你可以替换成自己的传感器)

软件需求
Yeelink帐号(注册新用户
增加一个设备和一个传感器(参考快速开始)

电路
Ethernet板和主板的插接略去。
传感器插接线:
VCC-5v
GND-GND
SCL-SCL(analog pin 5)
SDA-SDA(analog pin 4)
ADD-NC

实物图

Yeelink网站上生成的数据曲线
 

源码
同时也被开源至了Github
https://github.com/dapingliu/arduino_client_4_yeelink 

/*
 Yeelink sensor client example
 */

#include <SPI.h>
#include <Ethernet.h>
#include <Wire.h>
#include <math.h>

int BH1750address = 0x23;
byte buff[2];

// for yeelink api
#define APIKEY         "9cdf51696fa9ddfacdf819033a5f2f63" // replace your yeelink api key here
#define DEVICEID       4 // replace your device ID
#define SENSORID       7 // replace your sensor ID

// assign a MAC address for the ethernet controller.
byte mac[] = { 0x00, 0x1D, 0x72, 0x82, 0x35, 0x9D};
// initialize the library instance:
EthernetClient client;
char server[] = "api.yeelink.net";   // name address for yeelink API

unsigned long lastConnectionTime = 0;          // last time you connected to the server, in milliseconds
boolean lastConnected = false;                 // state of the connection last time through the main loop
const unsigned long postingInterval = 30*1000; // delay between 2 datapoints, 30s

void setup() {
  Wire.begin();
  // start serial port:
  Serial.begin(57600);
  // start the Ethernet connection with DHCP:
  if (Ethernet.begin(mac) == 0) {
    Serial.println("Failed to configure Ethernet using DHCP");
    for(;;)
      ;
  }
  else {
    Serial.println("Ethernet configuration OK");
  }
}

void loop() {
  // if there's incoming data from the net connection.
  // send it out the serial port.  This is for debugging
  // purposes only:
  if (client.available()) {
    char c = client.read();
    Serial.print(c);
  }

  // if there's no net connection, but there was one last time
  // through the loop, then stop the client:
  if (!client.connected() && lastConnected) {
    Serial.println();
    Serial.println("disconnecting.");
    client.stop();
  }

  // if you're not connected, and ten seconds have passed since
  // your last connection, then connect again and send data:
  if(!client.connected() && (millis() - lastConnectionTime > postingInterval)) {
    // read sensor data, replace with your code
    int sensorReading = readLightSensor();
    //send data to server
    sendData(sensorReading);
  }
  // store the state of the connection for next time through
  // the loop:
  lastConnected = client.connected();
}

// this method makes a HTTP connection to the server:
void sendData(int thisData) {
  // if there's a successful connection:
  if (client.connect(server, 80)) {
    Serial.println("connecting...");
    // send the HTTP PUT request:
    client.print("POST /v1.0/device/");
    client.print(DEVICEID);
    client.print("/sensor/");
    client.print(SENSORID);
    client.print("/datapoints");
    client.println(" HTTP/1.1");
    client.println("Host: api.yeelink.net");
    client.print("Accept: *");
    client.print("/");
    client.println("*");
    client.print("U-ApiKey: ");
    client.println(APIKEY);
    client.print("Content-Length: ");

    // calculate the length of the sensor reading in bytes:
    // 8 bytes for {"value":} + number of digits of the data:
    int thisLength = 10 + getLength(thisData);
    client.println(thisLength);

    client.println("Content-Type: application/x-www-form-urlencoded");
    client.println("Connection: close");
    client.println();

    // here's the actual content of the PUT request:
    client.print("{\"value\":");
    client.print(thisData);
    client.println("}");
  }
  else {
    // if you couldn't make a connection:
    Serial.println("connection failed");
    Serial.println();
    Serial.println("disconnecting.");
    client.stop();
  }
   // note the time that the connection was made or attempted:
  lastConnectionTime = millis();
}

// This method calculates the number of digits in the
// sensor reading.  Since each digit of the ASCII decimal
// representation is a byte, the number of digits equals
// the number of bytes:
int getLength(int someValue) {
  // there's at least one byte:
  int digits = 1;
  // continually divide the value by ten,
  // adding one to the digit count for each
  // time you divide, until you're at 0:
  int dividend = someValue /10;
  while (dividend > 0) {
    dividend = dividend /10;
    digits++;
  }
  // return the number of digits:
  return digits;
}

///////////////////////////////////////////////////////////////////////////
// get data from light sensor
// you can replace this code for your sensor
int readLightSensor()
{
  uint16_t val=0;
  BH1750_Init(BH1750address);
  delay(200);
  if(2==BH1750_Read(BH1750address))
  {
    val=((buff[0]<<8)|buff[1])/1.2;
  }

  Serial.print("Sensor value is: ");
  Serial.println((int)val);

  return val;
}

int BH1750_Read(int address) //
{
  int i=0;
  Wire.beginTransmission(address);
  Wire.requestFrom(address, 2);
  while(Wire.available()) //
  {
    buff[i] = Wire.read();  // receive one byte
    i++;
  }
  Wire.endTransmission();
  return i;
}

void BH1750_Init(int address)
{
  Wire.beginTransmission(address);
  Wire.write(0x10);//1lx reolution 120ms
  Wire.endTransmission();
}