|
|
最近用ArduinoUNO和QUECTEL M26做了个GPRS远程控制模块,现在模块跟服务器建立TCP连接,每隔5秒上报一次I/O口状态给服务器,并且可以根据服务器给他的指令对I/O口进行操作,M26模块的指令集都上传在附件里。现在的问题是,差不多跑一个礼拜,程序就挂了,不再上传数据到服务器,服务器也无法控制模块了,TCP连接就断开了,是不是我重启的代码写的不对?搞不明白,请大神帮我看一下代码,谢谢~
下面是代码:
//程序检测4~19脚数据并上传服务器 上传格式为id+时间+IO口状态
String inputString = ""; // a string to hold incoming data
String recvdata;
String rtime;
String orderID="";
unsigned long recvTime = 0;
unsigned long sendTime = 0;
unsigned long delayTime = 0;
int index = -1;
int index0 = -1;
int index1=-1;
int index2=-1;
int GPRSStep = 0; //初始化GPRS模块步骤
int TCPStep = 0; //TCP连接步骤
int SENDStep = 0; //发送数据步骤
int timestep = 0; //获取时间
bool response=false;
void connGPRS() //初始化GPRS模块的函数
{
if (GPRSStep == 0) //测试AT指令
{
index = inputString.indexOf("AT\r\r\nOK\r\n");
if (index > -1)
{
GPRSStep++;
}
else
{
inputString = "";
Serial.print("AT\r\n");
}
}
else if (GPRSStep == 1) //第二步,重置模块,确保复位等操作可以正常运行
{
index = inputString.indexOf("AT+QPOWD=1\r\r\nNORMAL POWER DOWN \r\n");
if (index > -1)
{
GPRSStep++;
}
else
{
inputString = "";
Serial.print("AT+QPOWD=1\r\n");
}
}
else if (GPRSStep == 2) //重置之后,再确认AT指令可以运行
{
index = inputString.indexOf("AT\r\r\nOK\r\n");
if (index > -1)
{
GPRSStep++;
}
else
{
inputString = "";
Serial.print("AT\r\n");
}
}
else if (GPRSStep == 3) //查询网络注册状态,确保GPRS可用
{
index = inputString.indexOf("AT+CGREG?\r\r\n+CGREG: 0,1\r\n\r\nOK\r\n"); //0,1代表本地网
if (index == -1)
{
index = inputString.indexOf("AT+CGREG?\r\r\n+CGREG: 0,5\r\n\r\nOK\r\n"); //0,5代表漫游
}
if (index > -1)
{
GPRSStep++;
}
else
{
inputString = "";
Serial.print("AT+CGREG?\r\n");
}
}
else if (GPRSStep == 4) //同步RTC时间
{
index = inputString.indexOf("AT+CTZU=3\r\r\nOK\r\n");
if (index > -1)
{
GPRSStep++;
}
else
{
inputString = "";
Serial.print("AT+CTZU=3\r\n");
}
}
else if (GPRSStep == 5) //同步网络时间并上报
{
index = inputString.indexOf("AT+QNITZ=1\r\r\nOK\r\n");
if (index > -1)
{
GPRSStep++;
}
else
{
inputString = "";
Serial.print("AT+QNITZ=1\r\n");
}
}
else if (GPRSStep == 6) //接收数据时显示IP头
{
index = inputString.indexOf("AT+QIHEAD=1\r\r\nOK\r\n");
if (index > -1)
{
GPRSStep++;
}
else
{
inputString = "";
Serial.print("AT+QIHEAD=1\r\n");
}
}
else if (GPRSStep == 7) //AT+QISEND时不允许数据回显
{
index = inputString.indexOf("AT+QISDE=0\r\r\nOK\r\n");
if (index > -1)
{
GPRSStep++;
}
else
{
inputString = "";
Serial.print("AT+QISDE=0\r\n");
}
}
else if (GPRSStep == 8) //设置上传到域名服务器
{
index = inputString.indexOf("AT+QIDNSIP=1\r\r\nOK\r\n");
if (index > -1)
{
GPRSStep++;
}
else
{
inputString = "";
Serial.print("AT+QIDNSIP=1\r\n");
}
}
}
void connTCP(String ip, String port) //连接TCP服务器的函数
{
if (TCPStep == 0)
{
String tstr = "AT+QIOPEN=\"TCP\",\""; //AT+QIOPEN="TCP","
String tstr2 = "\","; //",
String tstr3 = "\r\n";
String t = tstr + ip + tstr2 + port + tstr3;
inputString = "";
Serial.print(t);
TCPStep++;
delayTime = millis(); //系统运行时间,单位毫秒
}
else if (TCPStep == 1)
{
if (millis() - delayTime >= 10000) //设置连接超时时间,超时了就重新连接
{
TCPStep = 0;
}
else
{
index = inputString.indexOf("CONNECT OK\r\n"); //TCP连接成功
if (index > -1)
{
TCPStep++;
}
}
}
}
void sendStr(String str, int len) //发送字符串的函数
{
String tmp1 = (String)len; //强制转换
if (SENDStep == 0)
{
inputString = "";
Serial.print("AT+QISEND=");
Serial.print(tmp1); //指定长度发送
Serial.print("\r\n");
SENDStep++;
}
else if (SENDStep == 1)
{
index = inputString.indexOf("> ");
if (index > -1)
{
inputString = "";
Serial.print(str); //发送字符串str
SENDStep++;
}
}
else if (SENDStep == 2)
{
index = inputString.indexOf("SEND OK"); //发送成功
if (index > -1)
{
SENDStep++;
}
}
}
String recv() //读取输入数据的函数,返回值是String型
{
int index = -1, index2 = -1;
index = inputString.indexOf("IPD"); //接收数据时,显示IP头,格式为"IPD(data length):XXXXXXX"
index2 = inputString.indexOf(":");
int len = 0;
String lenStr;
lenStr.reserve(5); //设置为:lenStr的字符串容量至少是5
if (index > -1)
{
if (index2 > index)
{
index += 3; //跳过了IPD这三个字符
lenStr = inputString.substring(index, index2); //截取字符串,从IPD后一位到:(包含IPD后一位,不包含:),该字符串是输入字符串的长度
len = lenStr.toInt(); //把刚获得的字符串转换成INT型!!就获得了输入字符串的长度,INT型
if (inputString.length() >= index2 + len)
{
return inputString.substring(index2 + 1, index2 + len + 1); //index2+1,是跳过了:,这样截取的就是正确的输入的字符串
}
}
}
return ""; //否则返回空
}
String retime() //读取实时时间的函数
{
if (timestep == 0) {
index = inputString.indexOf("+CCLK:");
if (index > -1)
{
timestep++;
return inputString.substring(index + 8, index + 25); //截取时间
}
else
{
inputString = "";
Serial.print("AT+CCLK?\r\n");
return "";
}
}
}
void setup() {
for (int i = 4; i < 12; i++) { //4~11脚为输出脚,初始化是0
pinMode(i, OUTPUT);
digitalWrite(i, LOW);
}
for (int i = 12; i < 20; i++) { //12~19脚为输入脚,内部上拉
pinMode(i, INPUT_PULLUP);
}
inputString.reserve(200); //初始化inputstring的容量至少是200
Serial.begin(115200); //波特率115200!
}
void loop() {
if (GPRSStep < 9)
{
connGPRS(); //初始化设置GPRS模块
delay(200);
}
else if (TCPStep < 2)
{
connTCP("test.glotrol.com", "23000"); //设置上传服务器
SENDStep = 0;
sendTime = 0;
recvTime = 0;
timestep = 0;
}
else
{
String recvString = recv();
if ( recvString.startsWith("$%%") && recvString.endsWith("#*")) { //$%%IOOP2,5,-1233(32位指令ID)#*
index1=recvString.indexOf(",-")+2;
index2=recvString.indexOf("#*");
orderID=recvString.substring(index1, index2);
if (recvString.indexOf("IOOF") > -1) { //IOOFXXXXXXXX X=[0,1]
index0 = recvString.indexOf("IOOF") + 4;
recvdata = recvString.substring(index0, index0 + 8);
digitalWrite(4, recvdata[0] - '0');
digitalWrite(5, recvdata[1] - '0');
digitalWrite(6, recvdata[2] - '0');
digitalWrite(7, recvdata[3] - '0');
digitalWrite(8, recvdata[4] - '0');
digitalWrite(9, recvdata[5] - '0');
digitalWrite(10, recvdata[6] - '0');
digitalWrite(11, recvdata[7] - '0');
}
if (recvString.indexOf("IOOP") > -1) { //IOOPX,Y X=[0,7] Y=[1,9]
index0 = recvString.indexOf("IOOP") + 4;
recvdata = recvString.substring(index0, index0 + 3);
digitalWrite(recvdata[0] - '0' + 4, HIGH);
delay((recvdata[2] - '0') * 1000);
digitalWrite(recvdata[0] - '0' + 4, LOW);
}
response=true;
}
if (SENDStep < 3)
{
if(response==true)
{
if (SENDStep == 0)
{
sendTime = millis();
}
sendStr(orderID+"OK", 34);
if (millis() - sendTime > 60000) //发送数据超时,重发
{
GPRSStep=0;
TCPStep = 0;
SENDStep=0;
timestep = 0;
}
}
else if (timestep < 1) {
rtime = retime(); //读取当前时间
delay(200);
}
else {
String sid = "$00000001"; //模块ID,独一无二
String sbuf = ""; //存储IO口数据
String uploaddata = "";
if (SENDStep == 0)
{
sendTime = millis();
}
for (int i = 4; i < 20; i++) //读取4~19脚的数据,并存入sbuf
{
if (digitalRead(i) == HIGH)
{
sbuf += "1";
}
else
{
sbuf += "0";
}
}
uploaddata = sid + rtime + sbuf + "#";
sendStr(uploaddata, 43); //发送数据给服务器,注意字符串长度!!(这步完成之后SENDStep=3)
if (millis() - sendTime > 60000) //发送数据超时,重发
{
GPRSStep=0;
TCPStep = 0;
SENDStep=0;
timestep = 0;
}
}
}
else
{
if (millis() - sendTime > 5000) //5秒之后再次发送
{
SENDStep = 0;
timestep = 0;
}
if(response==true)
{
response=false;
}
}
}
}
void serialEvent() {
while (Serial.available()) {
char inChar = (char)Serial.read(); //每当串口缓存区有数据,就读取数据
delay(2);
inputString += inChar;
}
}
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有帐号?注册
x
|