极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

楼主: arduino-tinker

Arduino与Yeelink编程

[复制链接]
发表于 2013-7-19 14:21:07 | 显示全部楼层 |阅读模式
本帖最后由 arduino-tinker 于 2013-7-19 15:10 编辑

潜水了好长时间了,出来冒个泡。最近在用Arduino+Yeelink做能推送微博的智能家居,希望能把制作过程和大家分享下。因为论坛里相关的帖子也比较多,所以在这我就重点分析下代码。(PS:本人学疏才浅,如果有错,还望大家多多包涵)

在制作的过程中主要参考了:
1、lemodd 的《uno+w5100向yeelink传数据,经常会没反应》
2、erjiang 的《arduino+yeelink,用传感器数据触发新浪微博吧!》

制作流程:
(一)硬件准备
1、Arduino UNO 一块


2、W5100 一块(网上买的山寨版,50元,不过支持官方的库文件)


3、DHT11 一个


4、传感器扩展板(选用)


(二)注册yeelink账号
可以参考:
http://www.yeelink.net/develop/quickstart

(三)硬件连接
把板子一个落一个,DHT11接PIN3(PS:是不是因为山寨板子的缘故,板子间会卡住啊!)


(四)程序
这是yeelink提供的程序:http://blog.yeelink.net/?p=34
这是DHT11的程序:DHT11 测试

  1. #include <SPI.h>
  2. #include <Ethernet.h>
  3. #include <math.h>
  4. #include <dht11.h>

  5. dht11 DHT11;
  6. #define DHT11PIN 3  // DHT11连接PIN3

  7. // 配置你的yeelink api
  8. #define APIKEY         "xxxxxxxx"  // 输入你的 yeelink api key
  9. #define DEVICEID       xx  // 输入你的设备ID
  10. #define TEMPERATURE_SENSORID       xx  // 输入你的温度传感器ID
  11. #define HUMIDITY_SENSORID       xx  // 输入你的湿度传感器ID

  12. byte mac[] = { 0x00, 0x1D, 0x72, 0x82, 0x35, 0x9D};  // 为Ethernet分配MAC地址
  13. // 初始化库
  14. EthernetClient client;
  15. char server[] = "api.yeelink.net";   // yeelink API的地址

  16. unsigned long lastConnectionTime = 0;          // 初始化连接时间
  17. boolean lastConnected = false;
  18. const unsigned long postingInterval = 30*1000;

  19. int sensor = 0;   // 初始化传感器编号
  20.                   // 0为温度传感器
  21.                   // 1为湿度传感器
  22.                   
  23. void setup()
  24. {
  25.   Serial.begin(9600);  //开启串口
  26.   // 开启Ethernet的连接
  27.   if (Ethernet.begin(mac) == 0) {
  28.     Serial.println("Failed to configure Ethernet using DHCP");
  29.     for(;;)
  30.       ;
  31.   }
  32.   else {
  33.     Serial.println("Ethernet configuration OK");
  34.   }
  35.   // 打印DHT11的库文件版本
  36.   Serial.print("LIBRARY VERSION: ");
  37.   Serial.println(DHT11LIB_VERSION);
  38.   Serial.println();
  39.   
  40. }

  41. void loop() {
  42.   // 如果有来自互联网的数据,发送到串口
  43.   if (client.available()) {
  44.     char c = client.read();
  45.     Serial.print(c);
  46.   }

  47.   // 如果无连接且存在lastConnected,关闭客户端
  48.   if (!client.connected() && lastConnected) {
  49.     Serial.println();
  50.     Serial.println("disconnecting.");
  51.     client.stop();
  52.   }

  53.   // 如果当前无连接,10秒后继续连接并发送数据
  54.   if(!client.connected() && (millis() - lastConnectionTime > postingInterval)) {
  55.   // 分别发送温度、湿度数值
  56.   switch(sensor){
  57.         case 0:
  58.           sendData(readSensor(HUMIDITY_SENSORID), HUMIDITY_SENSORID);
  59.           break;
  60.         case 1:
  61.           sendData(readSensor(TEMPERATURE_SENSORID), TEMPERATURE_SENSORID);
  62.           break;
  63.   }
  64.   if(++sensor > 1) sensor = 0;
  65.   }
  66.   
  67.   // 储存经历整个循环的时间
  68.   lastConnected = client.connected();
  69. }

  70. // 定义接受数据函数
  71. int readSensor(int sensor_id)
  72. {
  73.   Serial.println("\n");

  74.   int chk = DHT11.read(DHT11PIN); // 从PIN3读取数值
  75.   // 判断传感器是否正常
  76.   Serial.print("Read sensor: ");  
  77.   switch (chk)
  78.   {
  79.     case DHTLIB_OK:
  80.                 Serial.println("OK");
  81.                 break;
  82.     case DHTLIB_ERROR_CHECKSUM:
  83.                 Serial.println("Checksum error");
  84.                 break;
  85.     case DHTLIB_ERROR_TIMEOUT:
  86.                 Serial.println("Time out error");
  87.                 break;
  88.     default:
  89.                 Serial.println("Unknown error");
  90.                 break;
  91.   }
  92.   // 打印温度、湿度
  93.   if(sensor_id == HUMIDITY_SENSORID){
  94.     Serial.print("Humidity (%): ");
  95.     Serial.println(DHT11.humidity);
  96.     return DHT11.humidity;
  97.   }else{
  98.     Serial.print("Temperature (oC): ");
  99.     Serial.println(DHT11.temperature);
  100.     return DHT11.temperature;
  101.   }
  102. }

  103. // 定义发送数据函数
  104. void sendData(int thisData) {
  105.   // 如果成功连接
  106.   if (client.connect(server, 80)) {
  107.     Serial.println("connecting...");
  108.     // 发送HTTP PUT请求
  109.     client.print("POST /v1.0/device/");
  110.     client.print(DEVICEID);
  111.     client.print("/sensor/");
  112.     client.print(SENSORID);
  113.     client.print("/datapoints");
  114.     client.println(" HTTP/1.1");
  115.     client.println("Host: api.yeelink.net");
  116.     client.print("Accept: *");
  117.     client.print("/");
  118.     client.println("*");
  119.     client.print("U-ApiKey: ");
  120.     client.println(APIKEY);
  121.     client.print("Content-Length: ");

  122.     // 计算http包里面内容部分的长度,即content-length长度
  123.     int thisLength = 10 + getLength(thisData);
  124.     client.println(thisLength);

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

  128.     // PUT回复内容
  129.     client.print("{"value":");
  130.     client.print(thisData);
  131.     client.println("}");
  132.   }
  133.   else {
  134.     // 如果连接失败
  135.     Serial.println("connection failed");
  136.     Serial.println();
  137.     Serial.println("disconnecting.");
  138.     client.stop();
  139.   }
  140.    // 标注连接时间
  141.   lastConnectionTime = millis();
  142. }

  143. // 以下内容没看懂啊,还望大虾指点
  144. // This method calculates the number of digits in the
  145. // sensor reading.  Since each digit of the ASCII decimal
  146. // representation is a byte, the number of digits equals
  147. // the number of bytes:
  148. int getLength(int someValue) {
  149.   // there's at least one byte:
  150.   int digits = 1;
  151.   // continually divide the value by ten,
  152.   // adding one to the digit count for each
  153.   // time you divide, until you're at 0:
  154.   int dividend = someValue /10;
  155.   while (dividend > 0) {
  156.     dividend = dividend /10;
  157.     digits++;
  158.   }
  159.   // return the number of digits:
  160.   return digits;
  161. }
复制代码


(五)连接及网页设定
可以参考:
http://www.yeelink.net/develop/quickstart
http://www.geek-workshop.com/forum.php?mod=viewthread&tid=1294


(PS:微博授权时间太短了,有木有啊!隔三差五就要去授权一次)

(六)评价
因为目前只有温度、湿度传感器,且上网时间不固定,所以没发挥出太大的作用,基本处于试运行阶段。等楼主9月开始去南航上学,有固定的场所和网络,再加一些传感器,相信不仅可以服务自己,也可以给大家提供便利。

附:
1、我的yeelink主页:板栗家的小A(昆明站)
2、用于推送数据的微博:@板栗家的小A(新浪微博)

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复

使用道具 举报

发表于 2013-7-20 10:14:49 | 显示全部楼层
请问enc28j60用法也一样吗?为什么我的就是不能成功
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-7-20 23:48:09 | 显示全部楼层
sangyingahua 发表于 2013-7-20 10:14
请问enc28j60用法也一样吗?为什么我的就是不能成功

你可以参考一下这里 http://www.geek-workshop.com/for ... thread&tid=1165 这就是用ENC28J60的!
回复 支持 反对

使用道具 举报

发表于 2013-7-21 21:54:03 | 显示全部楼层
最后代码为计算发送数据的长度,用于yeelink端校验。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-7-21 23:03:36 | 显示全部楼层
hp198969 发表于 2013-7-21 21:54
最后代码为计算发送数据的长度,用于yeelink端校验。

明白,非常感谢!我再去研究下!
回复 支持 反对

使用道具 举报

发表于 2013-10-11 15:39:16 | 显示全部楼层
sendData函数缺了一个变量
回复 支持 反对

使用道具 举报

发表于 2014-6-20 16:24:04 | 显示全部楼层
jjkason 发表于 2013-10-11 15:39
sendData函数缺了一个变量

请问这个问题解决了吗?
回复 支持 反对

使用道具 举报

发表于 2014-12-21 17:23:39 | 显示全部楼层
为啥我编译不能通过提示sendData()没有声明
回复 支持 反对

使用道具 举报

发表于 2015-5-30 17:13:35 | 显示全部楼层
编译出错!。。。
回复 支持 反对

使用道具 举报

发表于 2015-9-10 09:18:03 | 显示全部楼层
sendData()编译出错  怎么解决
回复 支持 反对

使用道具 举报

发表于 2016-4-15 22:27:00 | 显示全部楼层
您好,请问W5100的库文件能给一个么?我实在是找了很久找不到
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则 需要先绑定手机号

Archiver|联系我们|极客工坊

GMT+8, 2024-4-24 11:21 , Processed in 0.045122 second(s), 26 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表