|
本帖最后由 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 测试
- #include <SPI.h>
- #include <Ethernet.h>
- #include <math.h>
- #include <dht11.h>
- dht11 DHT11;
- #define DHT11PIN 3 // DHT11连接PIN3
- // 配置你的yeelink api
- #define APIKEY "xxxxxxxx" // 输入你的 yeelink api key
- #define DEVICEID xx // 输入你的设备ID
- #define TEMPERATURE_SENSORID xx // 输入你的温度传感器ID
- #define HUMIDITY_SENSORID xx // 输入你的湿度传感器ID
- byte mac[] = { 0x00, 0x1D, 0x72, 0x82, 0x35, 0x9D}; // 为Ethernet分配MAC地址
- // 初始化库
- EthernetClient client;
- char server[] = "api.yeelink.net"; // yeelink API的地址
- unsigned long lastConnectionTime = 0; // 初始化连接时间
- boolean lastConnected = false;
- const unsigned long postingInterval = 30*1000;
- int sensor = 0; // 初始化传感器编号
- // 0为温度传感器
- // 1为湿度传感器
-
- void setup()
- {
- Serial.begin(9600); //开启串口
- // 开启Ethernet的连接
- if (Ethernet.begin(mac) == 0) {
- Serial.println("Failed to configure Ethernet using DHCP");
- for(;;)
- ;
- }
- else {
- Serial.println("Ethernet configuration OK");
- }
- // 打印DHT11的库文件版本
- Serial.print("LIBRARY VERSION: ");
- Serial.println(DHT11LIB_VERSION);
- Serial.println();
-
- }
- void loop() {
- // 如果有来自互联网的数据,发送到串口
- if (client.available()) {
- char c = client.read();
- Serial.print(c);
- }
- // 如果无连接且存在lastConnected,关闭客户端
- if (!client.connected() && lastConnected) {
- Serial.println();
- Serial.println("disconnecting.");
- client.stop();
- }
- // 如果当前无连接,10秒后继续连接并发送数据
- if(!client.connected() && (millis() - lastConnectionTime > postingInterval)) {
- // 分别发送温度、湿度数值
- switch(sensor){
- case 0:
- sendData(readSensor(HUMIDITY_SENSORID), HUMIDITY_SENSORID);
- break;
- case 1:
- sendData(readSensor(TEMPERATURE_SENSORID), TEMPERATURE_SENSORID);
- break;
- }
- if(++sensor > 1) sensor = 0;
- }
-
- // 储存经历整个循环的时间
- lastConnected = client.connected();
- }
- // 定义接受数据函数
- int readSensor(int sensor_id)
- {
- Serial.println("\n");
-
- int chk = DHT11.read(DHT11PIN); // 从PIN3读取数值
- // 判断传感器是否正常
- Serial.print("Read sensor: ");
- switch (chk)
- {
- case DHTLIB_OK:
- Serial.println("OK");
- break;
- case DHTLIB_ERROR_CHECKSUM:
- Serial.println("Checksum error");
- break;
- case DHTLIB_ERROR_TIMEOUT:
- Serial.println("Time out error");
- break;
- default:
- Serial.println("Unknown error");
- break;
- }
- // 打印温度、湿度
- if(sensor_id == HUMIDITY_SENSORID){
- Serial.print("Humidity (%): ");
- Serial.println(DHT11.humidity);
- return DHT11.humidity;
- }else{
- Serial.print("Temperature (oC): ");
- Serial.println(DHT11.temperature);
- return DHT11.temperature;
- }
- }
- // 定义发送数据函数
- void sendData(int thisData) {
- // 如果成功连接
- if (client.connect(server, 80)) {
- Serial.println("connecting...");
- // 发送HTTP PUT请求
- 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: ");
- // 计算http包里面内容部分的长度,即content-length长度
- int thisLength = 10 + getLength(thisData);
- client.println(thisLength);
- client.println("Content-Type: application/x-www-form-urlencoded");
- client.println("Connection: close");
- client.println();
- // PUT回复内容
- client.print("{"value":");
- client.print(thisData);
- client.println("}");
- }
- else {
- // 如果连接失败
- Serial.println("connection failed");
- Serial.println();
- Serial.println("disconnecting.");
- client.stop();
- }
- // 标注连接时间
- 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;
- }
复制代码
(五)连接及网页设定
可以参考:
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
|