肥猫不吃鱼 发表于 2014-6-27 18:25:30

用GSM模块连接乐联网

目前有一版本可以 稳定的上传数据,需要的朋友留下邮箱。
下面的这个程序有点问题,板子是mega2560,我设置定时器为50ms中断,在中断服务函数中读取串口的数据到buffer中。然后在loop里面循环查找字符串,出现的问题是只能找到一次,后面的就不行了。上图:代码如下:
#include <FlexiTimer2.h>
#include <avr/wdt.h>

#define BAUD 115200

#define BufferLength 256                                         //接收缓冲区长度//
char buffer;                                        //接收缓冲区//
int RecieveCount=0;                                                //接收缓冲区计数//

#define TIMERPERIOD60                                       //定时器设置为每50ms中断一次
#define TIMERCOUNT (50000/TIMERPERIOD)                          //每50s发送一次心跳。
int SystemTimeCount=0;                  

#define TRYTIMES 100                                                //发送一条指令,循环检测返回值的次数//

#define SendCmdSpeed3000

#define DEBUG


bool LED=0;
bool LWOnline=0;                                                //乐联网在线标志, LWOnline=1,乐联网在线
bool TCPOnline=0;                                                //TCP 在线标记   TCPOnline=1 TCP在线

int PresentBufferLength=0;

void setup()
{
Serial.begin(BAUD);
pinMode(13,OUTPUT);                                                //上电后需要11秒左右完成相关的网络注册
Serial.println("ATE0");
delay(2000);
FlexiTimer2::set(TIMERPERIOD,TimerISR);                            // 中断设置函数,每 TIMERPERIOD ms 进入一次count
FlexiTimer2::start();                                           //开始计
wdt_enable(WDTO_120MS); //开启看门狗,并设置溢出时间为60MS
interrupts();
}

void TimerISR()
{
wdt_reset(); //喂狗操作,使看门狗定时器复位

//-----------------------------------------------------------//
//读取串口数据到缓冲区,一次性读完当前串口的所有数据//
   while(Serial.available()>0)
   {
       if(RecieveCount >= BufferLength )
         RecieveCount=0;
            buffer=Serial.read();
      digitalWrite(13,(LED^=1));
   }
    // Serial.println("the buffer is:");
    // Serial.println(buffer);
//----------------------------------------------------------------//
}

void loop()
{   
    if(TCPOnline == 0)
      {
      InitGsm();
         if(TCPOnline)
          Serial.println("TCPOnline");   
      }
    if(LWOnline == 0)
      {
         RegisterLewei();
         if(LWOnline)
          Serial.println("LWOnline");
          TCPOnline=0;
      }
}
//-----------------------------------------------------------------------------------------------------------------//
/*
函数作用:发送cmd给GSM模块,目标返回respond ,enter是否发送回车,enter=1发送回车,否则不发
函数说明:如果在指定次数内没有得到
*/
char SendCmd(String cmd,boolean enter,boolean mulrespond,char *respond,char *respond2,char *ErrorCode)
{
bool SearchRusult=0;
unsigned char i=0;
char *add1=NULL;
char *add2=NULL;
char *add3=NULL;
//------------------------------------------------------------------//
//发送数据
if(enter==1)
    {
      Serial.println(cmd);
    }
else
    {
       Serial.print(cmd);
    }
   delay(SendCmdSpeed);
//----------------------------------------------------------------//
//等待GSM模块返回响应//
   add1=add2=add3=NULL;
    for(i=0;i<TRYTIMES;i++)
      {
            add1 = strstr(buffer,respond);               
      if(mulrespond == 1)
                  add2 = strstr(buffer,respond2);
      add3 = strstr(buffer,ErrorCode);                                                                                        //等待缓冲区更新一次数据//
      if(add1 != NULL )
          {
            add1 = NULL;
            CleanBuffer1(buffer,respond);
            return 1;
          }
          if(add2 != NULL && mulrespond==1)
          {
            add2 = NULL;
            //CleanBuffer1(buffer,add2);
            CleanBuffer1(buffer,respond2);
            return 1;
          }
      if(add3 != NULL)
          {
            add3 = NULL;
         // SendCmd("ATE0",1,0,"OK",NULL,"ERROR");                        //发送ATE0 可以让整个系统重新,回归正常//
            CleanBuffer1(buffer,ErrorCode);
            return 0;
          }
         //delay(50);      
      }
    return 0;
   //--------------------------------------------------------------//
}
//---------------------------------------------------------------------------------------------------------------------//
/*
函数作用:清除当前字符串占用的缓存
函数说明:null
*/
int CleanBuffer1(char *str,char const *substr)
{
if(str == NULL || substr == NULL)
    {
      return 0;
    }
//标记str中substr开始的位置
char * begin = str;
//标记str中substr结束的位置
char * end = str;
//substr用于比较的游标指针
char const * index = substr;
while(*begin != '\0' && *end != '\0')
    {
      //在str中寻找substr
      while(*begin != *index)
        {
          begin++;
        }
      end = begin + 1;
      index++;
      while(*index == *end && *index != '\0' && *end != '\0')
        {
          index++;
          end++;
        }
      //如果index和end同时到达各自的字符串尾部,substr子串在str中被找到
      //例如str:"abcdeXYZ",substr:"XYZ"
      if(*index == '\0' && *end == '\0')
        {
          *begin = '\0';
          //printf(str);
          return 1;
        }
      /* 如果index到达substr字符串尾部,而end没有到达str的尾部,substr子串在str中被找到
       * 例如str:"abcdeXYZmn",substr:"XYZ"
      */
      else
      if(*index == '\0' && *end != '\0')
          {
             while(*begin++ = *end++);
             //printf(str);
             return 1;
          }
      /* 如果index未到达substr字符串尾部,而end有到达str的尾部,substr子串在str中未被找到
       * 例如str:"abcdeXYZmn",substr:"XYZmnST"
       */
      else
      if(*index != '\0' && *end == '\0')
          {
          //printf(str);
          return 0;
          }
        /*字符串匹配尚未完成
        * 例如str:"XYZabcdeXYZmnSTghd",substr:"XYZmnST"
        */
          else
          {
              begin++;
              end = begin;
              index = substr;
             }
        }
    return 0;
}
//---------------------------------------------------------------------------------------------------------------------//
/*
函数功能:注册乐联网,也是心跳//
函数说明:注册成功,LWOnline=1 否则LWOnline=0//
*/
void RegisterLewei()
{
char i=0;
if(TCPOnline==1)
    {
      i=SendCmd("AT+CIPSEND",1,0,"FAN",">","ERROR");
      if(i)
      LWOnline=SendCmd("{\"method\":\"update\",\"gatewayNo\":\"01\",\"userkey\":\"b8ad506aa60a4326a4d1365fc75e07bc\"}&^!32",0,0,"SEND OK"," ","ERROR");
    }
}
//---------------------------------------------------------------------------------------------------------------------//
/*
函数功能:初始化GSM模块,使其进入TCP数据传输模式//
函数说明:初始化成功 TCPOnline=1,否则TCPOnline=0
*/
voidInitGsm()
{
TCPOnline=SendCmd("AT+CIPSTART=\"TCP\",\"42.121.128.216\",\"9960\"",1,1,"CONNECT","ALREADY CONNECT","ERROR");
// TCPOnline=SendCmd("AT+CIPSEND",1,1,">",">","ERROR");
}
//---------------------------------------------------------------------------------------------------------------------//

ifanr 发表于 2016-5-3 20:23:13

:)学习了,程序不错

一路向西 发表于 2016-10-1 21:41:09

[email protected]    谢谢
页: [1]
查看完整版本: 用GSM模块连接乐联网