本帖最后由 瘦网虫 于 2014-12-24 09:27 编辑
最近陆陆续续很多人玩了乐联网的反向控制功能,实现了自己的反向控制函数的调用,而且可以通过网页控制自己的设备了。
于是很多人想更进一步,通过手机等设备来控制自己的设备。但是发现乐联网里面的“控制设备”这个功能不是那么好用。
这里简单介绍一下,并且附加一些arduino代码,供有兴趣的人参考。
和
同样是反向控制,但是,是有区别的。
它们在乐联网上的实现,也是所不同的。
对于“控制设备”,可以是个继电器、开关、调速器等,它需要向服务器(例如你的手机,或者网页)报告它所有设备的当前状态(通过响应“getAllSensors”命令),例如设备名,id,类型,当前状态等。在进行完“切换”操作后,还要再汇报一次自己的当前状态,已更新服务器端存储的信息。
- /*
- {"method":"response","result":{"successful":true,"message":"null","data":[{"id":"POWER","type":"jdq","name":"POWER","value":"1","status":"ok"}]}}&^!
- 你的控制开关叫 POWER,你就发上面的数据
- 服务器向你发getAllSensors你就返回上面的
- */
复制代码
对于“执行命令”,就没有那么多讲究了。只要接收到服务器发来的命令,跟自己名字匹配上了,就执行就可以了。不需要向请求方发送自己的执行结果等。
下面结合个实例,让玩家可以简单的实现自己的“控制设备”,并且希望能有更深刻的理解:
首先你要有个乐联网的E-KIT,不好意思,嵌入广告了。
或者你可以用个arduino UNO+w5100搭一个平台也可以实现,最好是用arduino mega 2560+w5100来测试这个代码。
然后,你要有乐联网帐号什么的,这个不多说了。
然后下载https://github.com/lewei50/LeweiTcpClient/tree/LeweiTcpClientliteBeta,这个库支持了自定义的“控制设备”。
下面的代码里还用到了自己写的IRremoteLite库,在这里下载
https://github.com/yangbo1979/IRremoteLite
如果你不需要红外控制的话,可以自行删除对应的代码。我这里控制的是“格力”的挂机开关。
下面的代码里面用到了dht11传感器测温湿度,一个红外2极管发射红外指令。
接线如下:
DHT11 vcc pin->+5v
DHT11 data pin->d2(数字引脚2,从d0开始数,第三个孔)
DHT11 gnd pin->gnd
红外接线:
GND->红外的瘦的那个针脚
D3->红外发射管里面那个碗状的针脚。
把下面的代码,改下userkey和gateway后刷入你的设备。
- #include <SPI.h>
- #include <Ethernet.h>
- #include <LeweiTcpClient.h>//乐联网的类库
- #include <EEPROM.h>
- #include <IRremoteLite.h> //红外控制的自定义精简库
- #include <dht11.h>
- //#include <EthernetUdp.h>
- #define LW_USERKEY "your api key here"//change your api key here,这里要改
- #define LW_GATEWAY "01"//change your gateway number here,这里看着改
- //unsigned int localPort = 9959;
- // buffers for receiving and sending data
- //char packetBuffer[UDP_TX_PACKET_MAX_SIZE]; //buffer to hold incoming packet,
- //char ReplyBuffer[] ="{"deviceName":"01","api":"http://tcp.lewei50.com:9965/?method=send&gatewayNo=01","requestType":"get"}"; // a string to send back
- //EthernetUDP Udp;
- dht11 DHT11;
- #define DHT11PIN 2
- IRsend irsend;
- //use PROGMEM to defined the 'large' variables into flash,not using the ram
- //开关格力空调的红外原始编码
- PROGMEM unsigned int rawCodes_ac_open[200] = {4397,4368,561,1578,560,537,557,1581,584,1582,584,486,558,537,584,1554,560,538,558,510,558,1607,557,513,585,511,556,1585,581,1583,583,486,557,1609,556,513,558,538,557,512,558,1607,558,1583,557,1608,558,1608,557,1580,559,1606,559,1581,556,1609,557,512,559,537,558,512,557,539,557,512,558,1607,558,1582,558,537,584,1555,558,1607,556,514,559,537,556,513,558,537,556,514,558,1606,559,511,583,513,558,1582,557,1608,558,1580,585,5154,4419,4347,584,1555,558,539,557,1581,584,1581,571,501,577,516,571,1568,557,541,581,487,557,1608,557,513,558,538,557,1582,583,1582,584,487,557,1608,557,511,611,486,558,510,558,1607,557,1609,556,1583,583,1582,583,1555,558,1607,558,1607,559,1582,557,537,585,486,558,510,558,540,558,509,557,1608,558,1608,557,512,559,1606,559,1581,558,537,581,490,558,510,587,511,557,511,559,1606,559,510,569,527,558,1582,560,1604,561,1605,561};
- PROGMEM unsigned int rawCodes_ac_close[200] ={4193,4096,595,1451,589,432,588,1453,589,1454,587,432,587,434,563,1475,591,433,564,458,586,1453,587,434,587,433,563,1476,590,1454,587,434,565,1475,566,456,563,1476,590,1453,587,1452,564,1477,566,457,585,1453,567,1477,587,1452,564,460,584,434,564,457,562,460,562,1475,587,434,588,433,562,1476,589,1455,563,1476,588,433,586,436,562,459,586,433,563,458,609,410,563,458,586,433,587,1454,587,1453,563,1477,564,1477,565,1476,581,4858,4237,4074,593,1453,562,460,563,1477,563,1477,565,458,587,434,584,1454,590,433,562,458,587,1453,588,436,584,436,562,1476,588,1453,590,434,562,1480,586,435,586,1453,565,1476,589,1453,589,1451,565,461,583,1453,589,1453,588,1454,564,457,587,434,587,433,587,435,561,1479,586,435,562,458,588,1452,590,1452,565,1476,564,458,587,436,584,433,562,458,588,432,562,461,585,434,584,435,589,1451,588,1453,588,1453,590,1453,590,1451,590};
- //下面的地址什么的,根据需要自己改
- byte mac[] = {0x74,0x69,0x69,0x2D,0x30,0x31};
- IPAddress ip(192,168,1, 15);
- IPAddress mydns(8,8,8,8);
- IPAddress gw(192,168,1,1);
- IPAddress subnet(255,255,255,0);
-
- LeweiTcpClient *client;
- long starttime;
- int postInterval = 10000;//10秒更新一次温湿度
- void setup()
- {
- Serial.begin(9600);
- pinMode(3, OUTPUT);
- starttime = millis();
- //you can use 3 ways to init your network
- //1.simplest
- //client = new LeweiTcpClient(LW_USERKEY, LW_GATEWAY);
- //2.set mac only
- //client = new LeweiTcpClient(LW_USERKEY, LW_GATEWAY,mac);
- //3.full setting for your network
- //使用了自定义的ip地址来初始化乐联网的库
- client = new LeweiTcpClient(LW_USERKEY, LW_GATEWAY,mac,ip,mydns,gw,subnet);
- // Udp.begin(localPort);
-
- //test1 is the function you write below to handle your program
- //"testFunction" is the function name you set on website:[url]http://www.lewei50.com/[/url]
- //on "controll command manager" menu
- //we test transfer 1-5 para from website(you defined on it) to your arduino
- //enjoy it
-
- // UserFunction ufChangeLed(changeLed,"changeLed");
- // client->addUserFunction(ufChangeLed);
- //这里是乐联网的“控制命令”的自定义
- UserFunction uf1(openAc,"openMyAC");
- client->addUserFunction(uf1);
- UserFunction uf2 (closeAc,"closeMyAc");
- client->addUserFunction(uf2);
- //这里是乐联网的“控制设备”的自定义,设备的开始默认状态为开(1)
- UserSwitch us1 (switchTest,"swTest",1);
- client->addUserSwitch(us1);
- // client->easySetupMode(true);
- client->checkFreeMem();
- }
- void loop()
- {
- client->keepOnline();
- if ((millis()-starttime) > postInterval)
- {
- sendDht11Value();
- starttime = millis();
- }
- /*
- int packetSize = Udp.parsePacket();
- if(packetSize)
- {
-
- Serial.print("Received packet of size ");
- Serial.println(packetSize);
- Serial.print("From ");
- IPAddress remote = Udp.remoteIP();
- for (int i =0; i < 4; i++)
- {
- Serial.print(remote[i], DEC);
- if (i < 3)
- {
- Serial.print(".");
- }
- }
- Serial.print(", port ");
- Serial.println(Udp.remotePort());
- // read the packet into packetBufffer
- Udp.read(packetBuffer,UDP_TX_PACKET_MAX_SIZE);
- Serial.println("Contents:");
- Serial.println(packetBuffer);
- // send a reply, to the IP address and port that sent us the packet we received
- Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
- Udp.write(ReplyBuffer);
- Udp.endPacket();
- }
- */
- }
- void sendDht11Value()
- {
- //read DHT11 sensor
- int chk = DHT11.read(DHT11PIN);
- switch (chk)
- {
- case DHTLIB_OK:
- // Serial.println("OK");
-
- //Serial.print("*** start data collection ");
- //Serial.println(DHT11.temperature);
-
- // client->sendSensorValue("tcp1","20");
- client->sendSensorValue("temperature",(String)DHT11.temperature);
- client->sendSensorValue("humidity",(String)DHT11.humidity);
-
- client->checkFreeMem();
- 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;
-
- }
-
- }
- //function functionIWrote use 1 parameter,on the website,it point to "p1"
- void changeLed(char * p1)
- {
- client->setRevCtrlMsg("true","ok");
- Serial.println(p1);
- }
- //function without parameter
- void openAc(char* p1)
- {
- client->setRevCtrlMsg("true","o");
- client->checkFreeMem();
- irsend.sendRaw(rawCodes_ac_open,200, 38);
- }
- void closeAc(char* p1)
- {
- client->setRevCtrlMsg("true","c");
- client->checkFreeMem();
- irsend.sendRaw(rawCodes_ac_close,200, 38);
- }
- void switchTest(char* p1)
- {
- Serial.println("switch test");
- client->setRevCtrlMsg("true","switch changed");
- /*
- if(String(p1).equals("1"))
- {
- openAc("1");
- }
- else
- {
- closeAc("0");
- }
- */
- client->checkFreeMem();
- }
复制代码
代码的62、63行指定了网页中你设定的“控制设备”的名字,默认为“开”。 - UserSwitch us1 (switchTest,"swTest",1);
- client->addUserSwitch(us1);
复制代码
网页里是这么设置的
刷入代码后,通过网页应该可以控制你的“控制设备”了。
通过手机控制的话,需要从github下载最新的手机端软件:
https://github.com/lewei50/LeweiApp/
下载bin目录下的LoginActivity.apk
上面代码实现的功能是发布你的温度到乐联网,并且可以控制空调开关。
我的截屏中的其它控制设备的联合使用效果见下面的视频:
Enjoy it~
|