ENC28J60利用ethercard库httpPost函数发送数据到yeelink或者乐联网
本帖最后由 zcbzjx 于 2013-5-29 00:39 编辑2013年5月29日更新:由于库文件更新比较多,以前的帖子有些不适用了,重新开贴又没有必要,所以就直接修改这个帖子,并争取把这个帖子修改成精华帖。
最近研究ethercard库,发觉有个httpPost函数,用这个库函数发送post数据比较省事,而且可以方便获得服务器返回数据。
实验硬件器材和这个帖子的实验器材一样,不再赘述。
ArduinoIDE版本:1.0.4
库文件为最新的ethercard库文件
Yeelink代码
#include <OneWire.h>
#include <EtherCard.h>
#include <DallasTemperature.h>
#define OUT
// Data wire is plugged into port A5 on the Arduino
#define ONE_WIRE_BUS A5
// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);
// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);
#define REQUEST_RATE 15000 // milliseconds
// ethernet interface mac address
static byte mymac[] = {
0x74,0x69,0x69,0x2D,0x30,0x31 };
// ethernet interface ip address
static byte myip[] = {
10,21,0,193 };
// gateway ip address
static byte gwip[] = {
10,21,0,1 };
// remote dns ip address
static byte dnsip[] = {
10,11,5,25 };
// remote website name
char website[] PROGMEM = "api.yeelink.net";
char urlBuf[] PROGMEM = "/v1.0/device/xxx/sensor/xxx/datapoints";
char apiKey[] PROGMEM = "U-ApiKey: xxxxxxxxxxxxxx";
byte Ethernet::buffer; // a very small tcp/ip buffer is enough here
static long timer;
// called when the client request is complete
static void my_result_cb (byte status, word off, word len) {
Serial.print("<<< reply ");
Serial.print(millis() - timer);
Serial.println(" ms");
Serial.println((const char*) Ethernet::buffer + off);
}
void setup () {
sensors.begin();
Serial.begin(57600);
Serial.println("\n");
if (ether.begin(sizeof Ethernet::buffer, mymac) == 0)
Serial.println( "Failed to access Ethernet controller");
ether.staticSetup(myip, gwip, dnsip);
while (ether.clientWaitingGw())
ether.packetLoop(ether.packetReceive());
Serial.println("Gateway found");
timer = - REQUEST_RATE; // start timing out right away
}
void loop () {
ether.packetLoop(ether.packetReceive());
if (millis() > timer + REQUEST_RATE) {
timer = millis();
Serial.println("\n>>> REQ");
static char buf;
get_send_string(buf);
if (!ether.dnsLookup(website))
Serial.println("DNS failed");
ether.printIp("Server: ", ether.hisip);
ether.httpPost (urlBuf, website, apiKey, buf, my_result_cb);
}
}
void get_send_string(OUT char *p){
sensors.requestTemperatures();
uint16_t Tc_100 = sensors.getTempCByIndex(0)*10;
uint8_t whole, fract;
whole = Tc_100/10 ;// separate off the whole and fractional portions
fract = Tc_100 % 10;
sprintf(p,"{\"value\":%d.%d}",whole,fract);
}
串口图如下:
乐联网代码如下:
#include <OneWire.h>
#include <EtherCard.h>
#include <DallasTemperature.h>
#define OUT
// Data wire is plugged into port A5 on the Arduino
#define ONE_WIRE_BUS 7
// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);
// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);
#define REQUEST_RATE 15000 // milliseconds
// ethernet interface mac address 需要根据你的实际网络环境进行更改,我这儿用的是固定ip
static byte mymac[] = {
0x74,0x69,0x69,0x2D,0x30,0x31 };
// ethernet interface ip address
static byte myip[] = {
10,21,0,193 };
// gateway ip address
static byte gwip[] = {
10,21,0,1 };
// remote dns ip address
static byte dnsip[] = {
10,21,0,1 };
// remote website name
char website[] PROGMEM = "www.lewei50.com";
char urlBuf[] PROGMEM = "/api/V1/gateway/UpdateSensors/01"; // 01应该更改为你对应的网关标识
char apiKey[] PROGMEM = "userkey:xxxxxxxxxxxxxxxxxxxxxxxxx"; //需要更改为你的userkey
byte Ethernet::buffer; // a very small tcp/ip buffer is enough here
static long timer;
// called when the client request is complete
static void my_result_cb (byte status, word off, word len) {
Serial.print("<<< reply ");
Serial.print(millis() - timer);
Serial.println(" ms");
Serial.println((const char*) Ethernet::buffer + off);
}
void setup () {
sensors.begin();
Serial.begin(57600);
Serial.println("\n");
if (ether.begin(sizeof Ethernet::buffer, mymac) == 0)
Serial.println( "Failed to access Ethernet controller");
ether.staticSetup(myip, gwip, dnsip);
while (ether.clientWaitingGw())
ether.packetLoop(ether.packetReceive());
Serial.println("Gateway found");
timer = - REQUEST_RATE; // start timing out right away
}
void loop () {
ether.packetLoop(ether.packetReceive());
if (millis() > timer + REQUEST_RATE) {
timer = millis();
Serial.println("\n>>> REQ");
static char buf;
get_send_string(buf);
if (!ether.dnsLookup(website))
Serial.println("DNS failed");
ether.printIp("Server: ", ether.hisip);
ether.httpPost (urlBuf, website, apiKey, buf, my_result_cb);
}
}
void get_send_string(OUT char *p){
sensors.requestTemperatures();
uint16_t Tc_100 = sensors.getTempCByIndex(0)*10;
uint8_t whole, fract;
whole = Tc_100/10 ;// separate off the whole and fractional portions
fract = Tc_100 % 10;
sprintf(p,"[{\"Name\":\"T2\",\"Value\":\"%d.%d\"}]",whole,fract);//T2应该更改为你对应的设备标识
}
以下为串口切图:
相信大家已经看出来来了,代码没什么大的变化。
好快。。。。 嘛意思。。。。 张老师给力 请问这个函数可不可以放到wifi模块上去用?
求指点 感谢分享! 请问MAC地址是如何获取的呢 mac地址可以自己随便编,只要本地没重复的就行。 可以向自己的服务器发送数据吗?比如向192.168.1.222发送数据。 all_heart 发表于 2012-10-28 23:55 static/image/common/back.gif
可以向自己的服务器发送数据吗?比如向192.168.1.222发送数据。
可以,192.168.1.222作为服务器,应该有相应的脚本将数据存储到数据库或者文本文件。 张老师能不能将这个ecard库直接改动一下,封装成直连yeelink的库?提供几个简单的参数就能完成上传? zcbzjx 发表于 2012-10-29 07:49 static/image/common/back.gif
可以,192.168.1.222作为服务器,应该有相应的脚本将数据存储到数据库或者文本文件。
能具体点吗,asp.net我知道该如何做,但arduino我还是比较茫然。望指点。 本帖最后由 zcbzjx 于 2012-10-30 07:55 编辑
all_heart 发表于 2012-10-29 22:48 static/image/common/back.gif
能具体点吗,asp.net我知道该如何做,但arduino我还是比较茫然。望指点。
ardino端用httppost函数,把数据发送到服务器相应页面,asp.net服务器端脚本处理这个post请求就行了。再详细我就要架服务器编服务器代码调试了。。太麻烦,建议你试试yeelink。然后再自己编写服务器端代码。 对照这个研究了数天后终于成功了,感谢楼主的教程 好帖子,再次谢过楼主