用面包板搭了个简易测试环境,包括以下内容:
1、Arduino Nano主板
2、Esp8266 Wifi 模块
3、DHT11温湿度模块
4、按钮、蜂鸣器
测试要点:
1、Esp8266连接
2、硬件与云平台互动
环境功能:
1、LED、温湿度等信息变化时,与云平台实时同步。
2、按钮可控制LED状态,用于测试互动情况。
3、蜂鸣器用于反映Esp8266 AT指令执行结果。
4、云平台远程控制本地设备。
代码如下:
#include <DHT.h>
#include <Esp.h>
//定义wifi数据
String Qwifi="MY";
String Qpass="MY121212";
String Qip="192.168.100.188";
String Qport="8081";
//定义后台数据
String Qapikey="c2366e5a95a25695";
//按钮、蜂鸣器
int Qbutton=3;
int QpinBeep=4;
//定义设备针脚
int Qled=13;//板载LED灯
int QpinDht11=5;//DHT11温湿度
//定义设备did
String Qdid_led="3578";
String Qdid_tem="3589";
String Qdid_hum="3590";
//定义温湿度变量
int Qcurtem,Qcurhum;
DHT Qdht(QpinDht11, DHT11);
//定义其他变量
int Qlivetime=0; //心跳时间
String Qcmd=""; //命令文本
int Qbstatus=0; //按钮状态
int Qlstatus=0; //灯状态
void setup() {
//定义设备输入输出模式
pinMode(Qled,OUTPUT);
pinMode(QpinBeep,OUTPUT);
pinMode(Qbutton,INPUT_PULLUP);
//启动温湿度传感器
Qdht.begin();
//上电等待esp模块启动
delay(5000);
Serial.begin(115200);
while (!Serial) delay(1);
//设置Station模式
Beep(QpinBeep,EspStation());
delay(1000);
//连接wifi
Beep(QpinBeep,EspWifi(Qwifi,Qpass));
delay(1000);
//连接服务器
Beep(QpinBeep,EspTcp(Qip,Qport));
delay(1000);
//发送绑定请求
Beep(QpinBeep,SendBind(Qapikey));
delay(1000);
//发送设备当前状态
Beep(QpinBeep,SendUp(Qapikey,Qdid_led,"0"));
}
void loop() {
String Ldid="",Ldata="";
// 先处理串口接收的远程控制指令
Ldata=GetData();
if (Ldata!=""){ // 如果收到指令,则进行处理。
// 获取led灯控制指令
Qcmd=GetDidData(Qdid_led,Ldata); //取led灯指令数据
if(Qcmd=="1" || Qcmd=="0"){
if(Qcmd=="1"){
digitalWrite(Qled,HIGH); //改变设备状态
Qlstatus=1;
}else{
digitalWrite(Qled,LOW); //改变设备状态
Qlstatus=0;
}
Ldid=Ldid+Qdid_led+",";
Ldata=Ldata+Qcmd+",";
}
// 获取led灯控制指令处理完毕
// 获取其他设备控制指令
//Qcmd=GetDidData(Qdid_other,Ldata); // 取其他设备指令数据
//if(Qcmd!=""){
//}
// 获取其他设备控制指令处理完毕
// 发送反馈数据
if(Ldid!=""){
Ldid=Ldid.substring(0,Ldid.length()-1);
Ldata=Ldata.substring(0,Ldata.length()-1);
SendOk(Qapikey,Qdid_led,Qcmd); //发送反馈指令
}
}
Ldid="";
Ldata="";
// 获取温湿度数据
int Lhum =(int)Qdht.readHumidity();//读湿度
int Ltem =(int)Qdht.readTemperature();//读温度,默认为摄氏度
if(Ltem!=Qcurtem){
Qcurtem=Ltem;
Ldid=Ldid+Qdid_tem+",";
Ldata=Ldata+(String)Ltem+",";
}
if(Lhum!=Qcurhum){
Qcurhum=Lhum;
Ldid=Ldid+Qdid_hum+",";
Ldata=Ldata+(String)Lhum+",";
}
// 检测按钮状态,获取LED灯数据
if(digitalRead(Qbutton)==LOW){
if( Qbstatus==0 ){
Qbstatus=1;
Qlstatus=1-Qlstatus;
digitalWrite(Qled,Qlstatus==0?LOW:HIGH);
Ldid=Ldid+Qdid_led+",";
Ldata=Ldata+(String)Qlstatus+",";
}
} else{ Qbstatus=0;}
// 如果设备数据发生变化,则更新服务器数据
if(Ldid!=""){
Ldid=Ldid.substring(0,Ldid.length()-1);
Ldata=Ldata.substring(0,Ldata.length()-1);
SendUp(Qapikey,Ldid,Ldata); // 更新设备数据
}
// 计算心跳时间
Qlivetime+=1;
if(Qlivetime>60){ //60秒心跳一次
Qlivetime=0;
Ldid=Qdid_led+","+Qdid_tem+","+Qdid_hum;
SendLive(Qapikey,Ldid); // 发送心跳指令
}
// Loop循环间隔1秒
delay(1000);
}
void Beep(int Cbeep,boolean Ctype){
if (Ctype){
digitalWrite(Cbeep,HIGH);delay(500);digitalWrite(Cbeep,LOW);
}else{
digitalWrite(Cbeep,HIGH);delay(100);digitalWrite(Cbeep,LOW);
}
}
其中,我封装了一个Esp.h,代码如下:
// 取串口数据
String GetData(){
String Ldata="";
while (Serial.available())
{
Ldata+=char(Serial.read());
delay(2);
}
return Ldata;
}
// 取did的指令数据
String GetDidData(String Cdid,String Cdata){
if( Cdata.indexOf("{")!=-1 && Cdata.indexOf("}")!=-1){
String Ldata=Cdid+":";
int Lstart = Cdata.indexOf(Ldata);
if (Lstart<1){ return ""; }
Lstart+=Ldata.length();
int Lend=Cdata.indexOf(",",Lstart);
if (Lend<Lstart){ Lend=Cdata.length()-1; }
return Cdata.substring(Lstart,Lend);
}
return "";
}
// 发送指令,等待时间自定义
boolean SendATCmd(String CcmdString,int CdelaySecond){
String cmdString=CcmdString;
cmdString.replace("'","\"");
unsigned long Lstart,Lend,Ldelay;
Ldelay = CdelaySecond * 1000;
while (Serial.available()){Serial.read();delay(2);}
Serial.println(cmdString);
char LOK[] = "OK\r\n";
char LERROR[] = "ERROR\r\n";
char LFAIL[] = "FAIL\r\n";
Lstart=millis();
Lend=millis();
while ((Lend-Lstart)<Ldelay)
{
if(Serial.find(LOK))return true;//成功:返回0
if(Serial.find(LERROR))return false;//错误:返回1
if(Serial.find(LFAIL))return false;//失败:返回2
delay(2);
Lend=millis();
}
return false;//其他:返回-1
}
// 发送指令,等待时间5秒
boolean SendATCmd(String CcmdString){
return SendATCmd(CcmdString,5);
}
// 发送wifi数据
boolean SendWifiString(String CWifiString){
unsigned long Lstart,Lend,Ldelay=5000;
while (Serial.available()){Serial.read();delay(2);}
String len=(String)(CWifiString.length());
Serial.println("AT+CIPSEND="+len);
Lstart=millis();
Lend=millis();
while ((Lend-Lstart)<Ldelay)
{
if(Serial.find('>')){
delay(1);
while (Serial.available()){Serial.read();delay(2);}
Serial.println(CWifiString);
char LOK[] = "OK\r\n";
char LERROR[] = "ERROR\r\n";
char LFAIL[] = "FAIL\r\n";
Lstart=millis();
Lend=millis();
while ((Lend-Lstart)<Ldelay)
{
if(Serial.find(LOK))return true;//成功:返回0
if(Serial.find(LERROR))return false;//错误:返回1
if(Serial.find(LFAIL))return false;//失败:返回2
delay(2);
Lend=millis();
}
return false;//其他:返回-1
}
delay(2);
Lend=millis();
}
return false;//其他:返回-1
}
// 发送绑定指令boolean
boolean SendBind(String CapiKey){
String Ldata="mode=bind&apikey="+CapiKey;
return (SendWifiString(Ldata));
}
// 发送上传指令
boolean SendUp(String CapiKey,String Cdid,String Cdata){
String Ldata="mode=up&apikey="+CapiKey+"&did="+Cdid+"&data="+Cdata;
return (SendWifiString(Ldata));
}
// 发送心跳指令
boolean SendLive(String CapiKey,String Cdid){
String Ldata="mode=live&apikey="+CapiKey+"&did="+Cdid;
return (SendWifiString(Ldata));
}
// 发送反馈指令(不带数据)
boolean SendOk(String CapiKey,String Cdid){
String Ldata="mode=ok&apikey="+CapiKey+"&did="+Cdid;
return (SendWifiString(Ldata));
}
// 发送反馈指令(带数据)
boolean SendOk(String CapiKey,String Cdid,String Cdata){
String Ldata="mode=ok&apikey="+CapiKey+"&did="+Cdid+"&data="+Cdata;
return (SendWifiString(Ldata));
}
// 置Station+单链接模式
boolean EspStation(){
String Ldata="AT+CWMODE=1";
if (!SendATCmd(Ldata)) return false;
Ldata="AT+CIPMUX=0";
return (SendATCmd(Ldata));
}
// 复位重启
boolean EspRst(int CwiteTime){
unsigned long Lstart,Lend,Ldelay;
Ldelay = CwiteTime * 1000;
while (Serial.available()){Serial.read();delay(2);}
Serial.println("AT+RST");
char Lready[] = "ready\r\n";
Lstart=millis();
Lend=millis();
while ((Lend-Lstart)<Ldelay)
{
if(Serial.find(Lready))return true;//成功:返回0
delay(2);
Lend=millis();
}
return false;//其他:返回-1
}
//连接wifi
boolean EspWifi(String CwifiName,String CwifiPass){
String Ldata="AT+CWJAP='"+CwifiName+"','"+CwifiPass+"'";
return (SendATCmd(Ldata));
}
//连接tcp
boolean EspTcp(String Cip,String Cport){
String Ldata="AT+CIPSTART='TCP','"+Cip+"',"+Cport;
return (SendATCmd(Ldata));
}
keywords如下:
#######################################
Methods and Functions 方法和函数
#######################################
SendBind KEYWORD2
SendUp KEYWORD2
SendLive KEYWORD2
SendOk KEYWORD2
GetData KEYWORD2
GetDidData KEYWORD2
EspStation KEYWORD2
EspRst KEYWORD2
EspWifi KEYWORD2
EspTcp KEYWORD2
SendATCmd KEYWORD2
SendWifiString KEYWORD2