物联网跟我动手做系列教程—第三篇 实验三如何用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();
}

 

评论列表

  1. cheer 说:

    为什么上面的程序,我编译提述错误呢?
    编译环境 arduino 0023
    已经删除了自带的libraries中的Ethernet文件夹,将下载好的ENC28J60解压后的文件夹放入了libraries,编译时提示:

    WebServer:19: error: ‘EthernetClient’ does not name a type
    WebServer:21: error: ‘IPAddress’ does not name a type
    WebServer.cpp: In function ‘void setup()':
    WebServer:36: error: no matching function for call to ‘EthernetClass::begin(byte [6])’
    E:\TDDownload\arduino-0023\libraries\ENC28J60/Ethernet.h:16: note: candidates are: void EthernetClass::begin(uint8_t*, uint8_t*)
    E:\TDDownload\arduino-0023\libraries\ENC28J60/Ethernet.h:17: note: void EthernetClass::begin(uint8_t*, uint8_t*, uint8_t*)
    E:\TDDownload\arduino-0023\libraries\ENC28J60/Ethernet.h:18: note: void EthernetClass::begin(uint8_t*, uint8_t*, uint8_t*, uint8_t*)
    WebServer.cpp: In function ‘void loop()':
    WebServer:51: error: ‘client’ was not declared in this scope
    WebServer:79: error: ‘client’ was not declared in this scope
    WebServer:87: error: ‘client’ was not declared in this scope
    WebServer:96: error: ‘client’ was not declared in this scope
    WebServer.cpp: In function ‘void getData()':
    WebServer:104: error: ‘client’ was not declared in this scope
    WebServer:104: error: ‘server’ was not declared in this scope

  2. cheer 说:

    经测试:这个帖子中提到的程序,其实就是W5100以太网板的,用ENC28J60的库,肯定编译通不过,提示的错误如上。

  3. cheer 说:

    你们可以先编译下试试。编译根本就通不过,用了官方的5100的库,倒是可以编译成功。

  4. 飞翔 说:

    yeelink平台提供了两种方式,一种是arduino/单片机通过直接socket网络连接的办法,连入平台上,保持和服务器的长连接,这种方法控制的实时性相对较强.

    这种方式相当灵活,通信协议随意定义。

    不知道如何实现?

  5. a123456 说:

    能不能出个enc28J60的教程呢,亲

  6. keaihhj 说:

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

  7. xl_1120 说:

    就是说现在如果用单片机还不能实现连续的传送吗,

  8. Noslepums 说:

    设备连接图片怎么看不到啊,跪求设备连接图片

  9. xuebao579 说:

    跪求如何实现第二步标出设备号和传感器号

  10. simonfromage 说:

    我的串口显示输出是不断显示:

    disconnecting.
    yeelink:connecting…
    print get done.

  11. xberlino 说:

    和一楼一样的问题,看了下官方例程将,ethernetclient改为client.但是又有新问题。
    ethernet:28: error: no matching function for call to ‘EthernetClass::begin(byte [6])’
    F:\Program Files\arduino\arduino-0023\libraries\Ethernet/Ethernet.h:16: note: candidates are: void EthernetClass::begin(uint8_t*, uint8_t*)
    F:\Program Files\arduino\arduino-0023\libraries\Ethernet/Ethernet.h:17: note: void EthernetClass::begin(uint8_t*, uint8_t*, uint8_t*)
    F:\Program Files\arduino\arduino-0023\libraries\Ethernet/Ethernet.h:18: note: void EthernetClass::begin(uint8_t*, uint8_t*, uint8_t*, uint8_t*)

    是不是只能用mac+ip的参数方式

  12. B_chenchen 说:

    请问点完网页上的开关之后,为什么IDE串口接收的是几个乱码啊,,我用的是w5100

  13. dh43215 说:

    另外,需要注意一点,下文中的ethernet shield是需要你家中的路由器开启DHCP功能的,如果没有开启,可以参考将
    1. 代码中添加 byte ip[] = { 192, 168, 1, 12 }; (根据网络环境更改)
    2. 将Ethernet.begin(mac) 替换成Ethernet.begin(mac, ip);
    我家路由器DHCP功能是开启的 用的是w5100 按照教程上的做 不能实现远程控制
    另外按照上面的改 也没说清楚到底怎么改

  14. yangDL 说:

    如果我添加多一个传感器、程序要怎么写呢?

  15. yanshiyonghu 说:

    前面有人提到的串口乱码是因为串口监视器的波特率与程序里的波特率设置不一致造成的吧

  16. yanshiyonghu 说:

    如果单纯的控制一个开关的话,好像用不到wire和math的库吧

  17. windpsp15 说:

    能出enc28j60的库和代码吗

  18. cjj208 说:

    为什么我用W5100按上述的方法改过了也用不了呢。。官方能不能出一个更细一点的说明啊。。。试了N遍了

  19. baibianxiaomi 说:

    我用的是arduino1.0.5版本的,我的一开始 Blink都编译不过去,后来我删了两个子文件才能编译过去,然后我按上面的步骤,yeelink的程序也变异不过去,具体错误如下:

    ketch_may20a.cpp.o: In function `__static_initialization_and_destruction_0′:
    D:\Arduino/sketch_may20a.ino:26: undefined reference to `String::String(char const*)’
    D:\Arduino/sketch_may20a.ino:26: undefined reference to `String::~String()’
    sketch_may20a.cpp.o: In function `String::operator+=(char)':
    D:\Arduino\hardware\arduino\cores\arduino/WString.h:108: undefined reference to `String::concat(char)’
    sketch_may20a.cpp.o: In function `loop':
    D:\Arduino/sketch_may20a.ino:66: undefined reference to `String::charAt(unsigned int) const’
    D:\Arduino/sketch_may20a.ino:71: undefined reference to `String::charAt(unsigned int) const’
    D:\Arduino/sketch_may20a.ino:75: undefined reference to `String::operator=(char const*)’
    Ethernet\Dhcp.cpp.o: In function `DhcpClass::request_DHCP_lease()':
    D:\Arduino\libraries\Ethernet/Dhcp.cpp:43: undefined reference to `random(long, long)’
    core.a(Print.cpp.o): In function `Print::print(String const&)':
    D:\Arduino\hardware\arduino\cores\arduino/Print.cpp:58: undefined reference to `String::operator[](unsigned int) const’

  20. HJWWPS 说:

    正对实时性好的socket连接的开发进度如何了?

  21. zgrss 说:

    这个程序在我这编译出现这个错误是怎么回事啊

    Yeelink.cpp: In function ‘void setup()':
    Yeelink:27: error: ‘Wire’ was not declared in this scope

  22. escblue 说:

    我用的W5100以太网板的。。换了了那要改的三个地方为什么没有用呢?

  23. ggc18 说:

    IDE1.5.2编译根本就通不过,好多符号都要改

  24. chenliuyang1228 说:

    例子中有使用ARDUINO+W5100以太网扩展板实现WEB控制,我想请问可不可以使用其他的无线模块代替以太网,有没有这方面的教程?请指教!

  25. msource 说:

    对于后台数据平台,这样设计不太合理。
    无法保证可扩展性, 耦合性太大。

    用户的使用情景无非是读数据和 Command and control.
    可以采用notification 和 reverse DNS 解决。

  26. ZLIT 说:

    学习

Trackbacks

Check out what others are saying about this post...
  1. […] http://blog.yeelink.net/?p=94 此条目发表在 未分类 分类目录。将固定链接加入收藏夹。 ← yeelink现在支持传感器数据触发新浪微博啦 […]



我也来说两句