[C] 纯文本查看 复制代码
#include <iBoardRF24Network.h>
#include <iBoardRF24.h>
#include <digitalWriteFast.h>
#include <SPI.h>
#include <Ethernet.h>
//请到m.znck007.com申请登陆-》家中环境-》网关,里可以看到!
#define APIKEY "xxxxxxxxxxxxxxxx" //设置apikey
uint16_t sid=001;//设置sid(设备号)
//NRF24l01发送接收节点
const uint16_t this_node = 0;
const uint16_t other_node = 1;
//NRF24l01收发数据
struct payload_t
{
uint32_t ms;
uint32_t data;
char sendchar[20];
};
//NRF24l01脚针设置
iBoardRF24 radioSend(3,8,5,6,7,2);
iBoardRF24Network networkSend(radioSend);
bool ispayload=false;//NRF24l01收发判断
uint16_t sendChannel=1;//NRF24l01发送频道
uint32_t sendCount=0;//NRF24l01发送次数
char incomingData[20]={0};//NRF24l01接收到的字符(其它设置发过来)
//设置MAC地址,如果有二个请改为不同(随意)
static byte mymac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
EthernetClient client;//声明网关类
char server[] = "api.znck007.com";//声明API网址
//char urlBuf[] = "/index.php";
static long timer;//用于规定时间间隔
unsigned long last_http;//记录http时间,用于http超时判断,目前20秒无响应则重新GET。
bool ishttpget=false;//标示http是否已经结束
bool isUpdate=false;//成功则更新服务器数据为正常
char updateData[20]={0};//更新的字符(服务器通过字符分析指定某个设备)
//串口通信处理(主要用于zigbee通信)
unsigned long serialnowlast;
char serialbuff[80]={0};
char serialData;
int seriali=0;
void setup(void)
{
//设置串口波特率
Serial.begin(115200);
Serial.println("IBOARD_GATEWAY_ZIGBEE/RF24Network");
//NRF24l01初始化
SPI.begin();
radioSend.begin();
//获取IP DNS等
Serial.println("\n[getDHCPandDNS]");
if (Ethernet.begin(mymac) == 0)
{
Serial.print(F("Failed to configure Ethernet using DHCP\n"));
while(1);
}
else
{
Serial.print("My IP address: ");
for (byte thisByte = 0; thisByte < 4; thisByte++) {
// print the value of each byte of the IP address:
Serial.print(Ethernet.localIP()[thisByte], DEC);
Serial.print("."); }
Serial.println("Ethernet configuration OK");
}
//连接web服务器
// if you get a connection, report back via serial:
if (client.connect(server, 80)) {
Serial.println("connected");
client.println("GET /index.php HTTP/1.1");
client.println("Host: api.znck007.com");
client.println("Connection: close");
client.println();
}
else {
// kf you didn't get a connection to the server:
Serial.println("connection failed");
client.stop();
}
//判断web服务器是否正常
timer=millis();
while ((!client.available()) && (millis()-timer)<2000);
if (client.available()) {
char c = client.read();
Serial.print(c);
client.stop();
}
timer = millis();
//完成setup
Serial.println("setup success");
}
void loop(void)
{
// //NRF24l01检测接收数处理
// //如果使用NRF24l01,请启动这里(并删除ZIGBEE检测接收数据处理)
// networkSend.begin(/*channel*/ sid, /*node address*/ this_node);
// // Pump the network regularly
// networkSend.update();
//
// // Is there anything ready for us?
// timer=millis();
// //while ((!networkSend.available()) && (millis()-timer)<2000);
// while(networkSend.available())
// {
// // If so, grab it and print it out
// RF24NetworkHeader header;
// payload_t payload;
// memset(payload.sendchar, 0, 20);
// networkSend.read(header,&payload,sizeof(payload));
// Serial.print("Received packet #");
// Serial.print(payload.data);
// Serial.print(" at ");
// Serial.print(payload.ms);
// Serial.print(" getchar ");
// Serial.println(payload.sendchar);
//
// ispayload = true;
//
// get_html_body(payload.sendchar,incomingData);
// Serial.println(incomingData);
// }
//
// if(!ishttpget)
// {
// if(ispayload)
// {
// ispayload = false;
//
// if(strstr(incomingData,"{ck") && strstr(incomingData,"}") )
// {
// last_http = millis();
// ishttpget=true;
//
// Serial.println("\n>>> POST");
// static char buf[20]={0};
// sprintf(buf,"%s",incomingData);
//
// client_post(server,APIKEY,buf);
// my_result_cb();
//
// return;
// }
//
// }
//
//
// }
//ZIGBEE检测接收数据处理
if(!ishttpget)
{
unsigned long serialnow = millis();//获取现在的时间
if(serialnow - serialnowlast >= 5000)//如果数据间隔超过5秒而清空字符(为了防止数据错乱)
{
serialnowlast = millis();
memset(serialbuff, 0, 80);
seriali=0;
}
bool isSerial=false;
while( Serial.available() )//如果串口有数据(ZIGBEE或电脑发过来的)
{
if(seriali==0)
{
Serial.println("Serial->");//打印出来方便调试
}
serialData=(char)Serial.read();//读取串口数据
//Serial.print(serialData);////这里不打印,否则ZIGBEE检测到{ckxxxx}就认为是命令
serialbuff[seriali]=serialData;////保存到数组
seriali++;////数组长度+1
if(serialData=='}' || seriali>=80)//如果发现}而说明命令结束(并少于80个字符,太长会出错)
{
isSerial=true;
break;
}
}
//开始处理{ckxxxxx}字符,如POST上传到web服务器
if(isSerial)
{
serialnowlast = millis(); //更新当前时间,不然5秒就超时了
//Serial.println(serialbuff);
char body[81]={0};
get_html_body(serialbuff,body);//获取只是{ckxxxxxx}的字符,因为这是我们的命令格式
//Serial.println(body);
Serial.println("-------------------");
//如果命令格式真确则POST到web服务器了
if(strstr(body,"{ck") && strstr(body,"}") )
{
last_http = millis();
ishttpget=true;
timer = millis();
Serial.println("\n>>> POST");
//static char buf[81]={0};
//sprintf(buf,"%s",body);
client_post(server,APIKEY,body);//POST到网址,APIKEY,字符
my_result_cb();//接收web服务器返回的字符
}
memset(serialbuff, 0, 80);//清空字符
seriali=0;//字符长度为0
return;
}
}
//delay(200);
//更新web服务器命令的状态(比如发送成功还是失败还是异常等,NRF24l01用到,ZIGBEE不用这里而是直接发送{ck00xxxxxxupdate}命令就行)
if( isUpdate )
{
isUpdate=false;
last_http = millis();
ishttpget=true;
Serial.println("\n>>> UPDATE");
static char buf[20]={0};
sprintf(buf,"%s",updateData);
//Serial.println(buf);
client_post(server,APIKEY,buf);//POST到网址,APIKEY,字符
my_result_cb();//接收web服务器返回的字符
isUpdate=false;
return;
}
//每2秒钟查看web服务器是有命令数据
unsigned long now = millis();
if(now - last_http >= 2000)
{
if(!ishttpget || (now - last_http) >= 20000)//20秒超时会执行,为了防卡死问题
{
last_http = millis();
ishttpget=true;
Serial.println("\n>>> REQ");
static char buf[20]={0};
sprintf(buf,"{ck001000000000}"); //这个字符串代表获取新命令数据
client_post(server,APIKEY,buf);//POST到网址,APIKEY,字符
my_result_cb();//接收web服务器返回的字符
timer = millis();
}
}
}
//接收web服务器返回的字符
static void my_result_cb(){
char eth_buffer[350];
timer=millis();
while ((!client.available()) && (millis()-timer)<1000);
if (client.available()) {
for(int j=0;client.available()>0;j++)
{
char c = client.read();
eth_buffer[j]=c;
Serial.print(c);
}
client.stop();
}
Serial.println();
char body[81]={0};
get_html_body(eth_buffer,body);//获取只是{ckxxxxxx}的字符,因为这是我们的命令格式
//Serial.println(body);
sendChannel=get_channel(body);//获取是哪个sid,这是m.znck007.com手机客服端里的sid
// //如果使用NRF24l01,请启动这里
// if( sendChannel>0 )
// {
// networkSend.begin(/*channel*/ sendChannel, /*node address*/ other_node);
//
// networkSend.update();
// Serial.println("");
// Serial.print("Sending...");
// if(sendCount>1000000) sendCount=0;
// payload_t payload = { sendChannel, sendCount++, "{ck000000000000}" };//millis()
// sprintf(payload.sendchar,"%s",body);
// RF24NetworkHeader header(/*to node*/ this_node);
// bool ok = networkSend.write(header,&payload,sizeof(payload));
// if (ok)
// {
// Serial.println("ok.");
//
// isUpdate=true;
// char front[10]={0};
// memcpy(front,body,9);
// sprintf(updateData,"%supdate}",front);
// Serial.println(updateData);
//
// }
// else
// {
// Serial.println("failed.");
// }
// }
ishttpget=false;
last_http = millis();
networkSend.begin(/*channel*/ sid, /*node address*/ this_node);
networkSend.update();
}
//获取只是{ckxxxxxx}的字符,因为这是我们的命令格式
void get_html_body(char *p,char *s){
char rechar[81]={0};
int bufi=0;
bool isend=false;
int charnum=0;
for(bufi=0;bufi<strlen(p);bufi++){
//Serial.print(p[bufi]);
if(p[bufi]=='{'){
isend=true;
}
if(p[bufi]=='}' && isend==true){
isend=false;
rechar[charnum]=p[bufi];
break;
}
if(isend){
if(charnum<80)
{
rechar[charnum]=p[bufi];//Serial.print(rechar[charnum]);
charnum++;
}
}
}
Serial.println("");
//memcpy(s,rechar,17);
sprintf(s,"%s",rechar);
}
//获取是哪个sid,这是m.znck007.com手机客服端里的sid
int get_channel(char *buff){
if( strstr(buff,"{ck") && strstr(buff,"}") && strlen(buff)>10)
{
char charChannel[4]={0};
memcpy(charChannel,buff+3,3);
Serial.println(charChannel);
int intChannel=atoi(charChannel);
Serial.println(intChannel);
return intChannel;
}
else
{
return 0;
}
}
//W5100芯片POST字符数据到web服务器
int client_post(char *server, char *apikey, char *buf){
if (client.connect(server, 80))
{
Serial.println("connecting...");
// send the HTTP PUT request:
client.print("POST /index.php");
client.println(" HTTP/1.1");
client.println("Host: api.znck007.com");
client.print("apikey: ");
client.println(APIKEY);
client.print("Accept: *");
client.print("/");
client.println("*");
client.print("Content-Length: ");
// calculate the length of the sensor reading in bytes:
// 8 bytes for {"value":} + number of digits of the data:
size_t thisLength = strlen(buf);
client.println(thisLength);
client.println("Content-Type: application/x-www-form-urlencoded");
client.println("Connection: close");
client.println();
client.println(buf);
client.println();
}
else
{
// kf you didn't get a connection to the server:
Serial.println("connection failed");
Serial.println();
Serial.println("disconnecting.");
client.stop();
}
}