本帖最后由 pzg123 于 2015-7-9 18:03 编辑
#include <SoftwareSerial.h>//声明软串口库
#include <EEPROM.h>
#define reset_8266 4//定义引脚
#define httpled 5
#define led1_pin 6
#define led2_pin 7
#define led3_pin 8
SoftwareSerial mySerial(9, 10); // RX, TX
//请到m.znck007.com申请登陆->家中环境->网关,里可以看到!
char apiKey[] = "****************"; //设置apikey
char server[] = "api.znck007.com"; //声明API网址
//char server[] = "192.168.12.85"; //声明服务器
String ssid="*****";//登陆路由器需要的ssid名称以及密码
String pwd="********";
unsigned long timer,last_http;
int sid=3,count_busy=0;
int state1=0,state2=0,state3=0;
bool ishttpget,isUpdate;
char updateData[20]={0};
void setup(){
Serial.begin(115200);
mySerial.begin(9600);
pinMode(httpled,OUTPUT);
pinMode(reset_8266,OUTPUT);
pinMode(led1_pin,OUTPUT);
pinMode(led2_pin,OUTPUT);
pinMode(led3_pin,OUTPUT);
digitalWrite(reset_8266,LOW);
state1 = EEPROM.read(0);//读EEPROM
state2 = EEPROM.read(1);
state3 = EEPROM.read(2);
digitalWrite(led1_pin,state1);//设置开关状态
digitalWrite(led2_pin,state2);
digitalWrite(led3_pin,state3);
//Serial.println("ATE0");
//delay(1000);
if(conf_JAP(ssid,pwd));//登陆路由器
mySerial.println("setup success");
}
void loop(){
String str = "";
while (Serial.available()){
str = Serial.readString();//Serial.readString()返回的是一个String,很长的字符串时也不会出现丢失
}
if(str.length()){
if(str.indexOf("Apache/2.2.15")>0){//查找字符串
mySerial.print("\n<<< reply ");
mySerial.print(millis() - timer);
mySerial.println(" ms");
ishttpget=true;
digitalWrite(httpled,LOW);
}
char body[12]={0};
get_znck_body(str,body);//获取只是{xxxxxxxx}的字符
mySerial.println(body);
int s=get_sid(body); //获取sid
int n=get_nid(body);//获取nid
int d=get_data(body);//获取data
if(s==sid){
switch(n){
case 0:
EEPROM.write(0,d);//保存到EEPROM
digitalWrite(led1_pin,d);//设置开关状态
break;
case 1:
EEPROM.write(1,d);
digitalWrite(led2_pin,d);
break;
case 2:
EEPROM.write(2,d);
digitalWrite(led3_pin,d);
break;
default:break;
}
isUpdate=true;//是否更新标记
char front[10]={0};
memcpy(front,body,9);
sprintf(updateData,"%supdate}",front);//创建更新字符串
}
}
if(isUpdate){//更新
isUpdate=false;
last_http = millis();
mySerial.println("\n>>> UPDATE");
static char buf[20]={0};
sprintf(buf,"%s",updateData);
Post_Data(buf); //POST到网址,apiKey,字符
return;
}
if(millis()-last_http>=5000){//间隔5秒
if(ishttpget || millis() - last_http >= 20000){//获取有数据或间隔20秒
last_http = millis();
ishttpget=false;
digitalWrite(httpled,HIGH);
mySerial.print(count_busy);
mySerial.println(" >>> REQ");
static char buf[20]={0};
sprintf(buf,"{ck001000000000}"); //%s ,updateData
Post_Data(buf); //POST到网址,apiKey,字符
}
}
}
void get_znck_body(String p,char *s){ //获取只是{ckxxxxxx}的字符
char rechar[12]={0};
int bufi=0;
bool isend=false;
int charnum=0;
for(bufi=0;bufi<p.length();bufi++){
if(p[bufi]=='{') isend=true;
if(isend) rechar[charnum++]=p[bufi];
if(p[bufi]=='}'){
isend=false;
break;
}
}
sprintf(s,"%s",rechar);
}
void Post_Data(char* thisData){//send the HTTP PUT request:
if(start_Mux(1,server,80)){//建立tcp链接
mySerial.println("connecting ok");
String cmd; //创建发送字符串
cmd = "POST /index.php HTTP/1.0\r\n";
cmd += "Host: ";
cmd += server;
cmd += "\r\n";
cmd += "apikey: ";
cmd += apiKey;
cmd += "\r\n";
cmd += "Accept: *";
cmd += "/";
cmd += "*\r\n";
cmd += "Content-Length: ";
size_t thisLength = strlen(thisData);
cmd += String(thisLength);
cmd += "\r\n";
cmd += "Content-Type: application/x-www-form-urlencoded\r\n";
cmd += "\r\n";
cmd += String(thisData);
cmd += "\r\n";
count_busy = 0;
timer = millis();
if(Send(cmd)) mySerial.println("Send ok");//发送字符串
else mySerial.println("Send fail");
}
else{
mySerial.println("connection failed");
count_busy++;
if(count_busy>=22){//网络掉线或ESP8266无响应(死机)3-5分钟重启ESP8266
count_busy = 0;
mySerial.println("ESP8266_RESET WAIT...");
digitalWrite(reset_8266,HIGH);
delay(200);
digitalWrite(reset_8266,LOW);
delay(5000);
}
}
}
boolean Send(String str){//发送
Serial.print("AT+CIPSEND=");
Serial.println(str.length());
unsigned long start;
bool found=false;
start = millis();
while(millis()-start<3000){//设置超时,3秒内没有找到">"字符,退出,返回false
if(Serial.find(">")==true ){
found = true;
break;
}
}
if(found) Serial.print(str);
else return false;
start = millis();
while(millis()-start<4500){
if(Serial.available()>0){
if(Serial.find("SEND OK")==true)
return true;
}
}
return false;
}
boolean conf_JAP(String ssid , String pwd){ //配置登陆路由器需要的ssid名称以及密码
Serial.print("AT+CWJAP=");
Serial.print("\"");
Serial.print(ssid);
Serial.print("\"");
Serial.print(",");
Serial.print("\"");
Serial.print(pwd);
Serial.println("\"");
unsigned long start = millis();
while (millis()-start<18000){
if(Serial.find("OK")==true) return true;
}
return false;
}
boolean start_Mux(byte type, String addr, int port){ //建立tcp链接或者注册UDP端口号(单路模式)
Serial.print("AT+CIPSTART=");
if(type>0) Serial.print("\"TCP\"");
else Serial.print("\"UDP\"");
Serial.print(",");
Serial.print("\"");
Serial.print(addr);
Serial.print("\"");
Serial.print(",");
Serial.println(String(port));
String data;
unsigned long start = millis();
while(millis()-start<4500){ //当串口有完成数据返回时,结束语句
if(Serial.available()>0){
char a =Serial.read();
data=data+a;
}
if(data.indexOf("OK")!=-1||data.indexOf("ALREAY CONNECT")!=-1) return true;
}
return false;
}
int get_sid(char *buff){ //获取sid
if(strstr(buff,"{ck")&&strstr(buff,"}")&&strlen(buff)>10){
char charsid[4]={0};
memcpy(charsid,buff+3,3);
int intsid=atoi(charsid);
return intsid;
}
else return 0;
}
int get_nid(char *buff){ //获取nid
if(strstr(buff,"{ck")&&strstr(buff,"}")&&strlen(buff)>10){
char charNid[4]={0};
memcpy(charNid,buff+6,3);
int intNid=atoi(charNid);
return intNid;
}
else return 0;
}
int get_data(char *buff){ //获取data
if(strstr(buff,"{ck")&&strstr(buff,"}")&&strlen(buff)>10){
char charData[4]={0};
memcpy(charData,buff+9,1);
int intData=atoi(charData);
return intData;
}
else return 0;
} |