ARDUINO UNO + SIM808(GPS / GSM)同步

时间:2016-04-29 07:39:00

标签: arduino

我最近开始了一个项目,我打算将arduino uno和sim808模块结合在一起,将gps / gsm / gprs整合在一起。

只使用gps功能工作正常,只需接收和发送消息的gsm也可以正常工作。但是根据我的意图将它们结合起来会使整个系统崩溃。

我打算能够注册一些坐标,让我们说位置A位置B和位置c,我打算设计的系统放在一个移动的,让我们说的车上,现在任何人任何一个位置都会发送一条带有字母的消息,表示该位置为一个数字,让我们说" A TO +23 ******* 98,并且可以从该位置得到汽车当前时间的回复

如果所有部分组合在一起,程序有时甚至不会指示接收任何消息,即使它确实gps部分甚至无法工作。

我做错了什么事情,或者我使用的组件不是可行的,请帮助我,因为我现在非常困惑。

`#include <SoftwareSerial.h>
SoftwareSerial GPRS(7, 8); // RX, TX

  String BUSNUM="A";  // THIS SIM IS TO BE INSTALLED ON BUS A
  static String sendersnumber;
  char* key;
  char MESSAGE[280];
  String latitude;
  String longitude;

  String Speed;

enum _parseState 
{


    PS_DETECT_MSG_TYPE,
      PS_IGNORING_COMMAND_ECHO,

      PS_READ_CMTI_STORAGE_TYPE,
      PS_READ_CMTI_ID,
      PS_DETECT_MSG_TYPE2,
      PS_IGNORING_COMMAND_ECHO2,
      PS_READ_CMGR_STATUS2,
      PS_READ_CMGR_CONTENT2,
      PS_READ_CMGR_DATE2,

      PS_READ_CMGR_STATUS,
      PS_READ_CMGR_NUMBER2,
      PS_READ_CMGR_NUMBER,
      PS_READ_CMGR_SOMETHING,
      PS_READ_CMGR_DATE,
      PS_READ_CMGR_CONTENT,
      PS_READ_VIDEO_CONTENT,
      PS_READ_VIDEO2_CONTENT,
      PS_READ_CMGR_SOMETHING2,
      PS_READ_VIDEO_CONTENT2,
    };

    byte state = PS_DETECT_MSG_TYPE; // KEEP TRACK OF WHAT STATE WE ARE IN RIGHT NOW

    char buffer[100]; // WHAT WE ARE READING INTO

    byte pos = 0;  //WHAT POSITION WE ARE AT IN THAT BUFFER

    int lastReceivedSMSId = 0;  // LAST RECIEVED SMS ID
    boolean validSender = false; //SOO NOT JUST ANYONE HAS ACESS TO SEND A COMMAND


    void resetBuffer() 
    {
      memset(buffer, 0, sizeof(buffer));
      pos = 0;
    }//BASICALLY TO RESET THE BUFFER


    void setup()
    {

      GPRS.begin(9600);
      Serial.begin(9600);
      GPRS.println("AT+CGNSPWR=1");
      delay(290);
      GPRS.println("AT+CGNSURC=0");
      delay(300);
      GPRS.println("AT");
      delay(300);
      GPRS.println("AT+CMGF=1"); // INITIALIZE SMS
      delay(300);

      for (int i = 1; i <= 15; i++) 
      {
        GPRS.print("AT+CMGD=");
        GPRS.println(i);
        delay(300);
        // Not really necessary but prevents the serial monitor from dropping any input SINCE WE KNOW LIMIT TO STORE IS 15, THIS JUST DELETES IT CLEARS IT
        while(GPRS.available()) 
          Serial.write(GPRS.read());
      }   
        delay(2000);
       GPRS.println("AT+CGNSURC=1");     

    }

    void loop()
    {

     while(GPRS.available()) //ONLY WHEN THERE IS SOMETHING AVAILABLE,
      {


       GSM_NUM1(GPRS.read());  
       //delay(50);
       GPRS.println("AT+CGNSINF");
      // delay(40);    

        GPSAnalyzer(GPRS.read());

        sendSMS();

      }

    }
    // END OF VOID LOOP



    void GSM_NUM1(byte b)
    {

      buffer[pos++] = b;

     if ( pos >= sizeof(buffer) )
        resetBuffer(); // just to be safe

     switch (state) 
      {
      case PS_DETECT_MSG_TYPE: 
        {
          if ( b == '\n' )
            resetBuffer();
          else {        
            if ( pos == 3 && strcmp(buffer, "AT+") == 0 ) {
              state = PS_IGNORING_COMMAND_ECHO;
            }
            else if ( pos == 6 ) {
              //Serial.print("Checking message type: ");
              //Serial.println(buffer);

              if ( strcmp(buffer, "+CMTI:") == 0 ) {
                Serial.println("Received CMTI");
                state = PS_READ_CMTI_STORAGE_TYPE;
              }
              else if ( strcmp(buffer, "+CMGR:") == 0 ) {
                Serial.println("Received CMGR");            
                state = PS_READ_CMGR_STATUS;
              }
              resetBuffer();
            }
          }
        }
        break;

      case PS_IGNORING_COMMAND_ECHO:
        {
          if ( b == '\n' ) {
            //Serial.print("Ignoring echo: ");
            //Serial.println(buffer);
            state = PS_DETECT_MSG_TYPE;
            resetBuffer();
          }
        }
        break;

      case PS_READ_CMTI_STORAGE_TYPE:
        {
          if ( b == ',' ) {
            Serial.print("SMS storage is ");
            Serial.println(buffer);
            state = PS_READ_CMTI_ID;
            resetBuffer();
          }
        }
        break;

      case PS_READ_CMTI_ID:
        {
          if ( b == '\n' ) {
            lastReceivedSMSId = atoi(buffer);
            Serial.print("SMS id is ");
            Serial.println(lastReceivedSMSId);

            GPRS.print("AT+CMGR=");
            GPRS.println(lastReceivedSMSId);
            //delay(500); don't do this!

            state = PS_DETECT_MSG_TYPE;
            resetBuffer();
          }
        }
        break;

      case PS_READ_CMGR_STATUS:
        {
          if ( b == ',' ) {
            Serial.print("CMGR status: ");
            Serial.println(buffer);
            state = PS_READ_CMGR_NUMBER;
            resetBuffer();
          }
        }
        break;

      case PS_READ_CMGR_NUMBER:
        {
          if ( b == ',' ) {
            Serial.print("CMGR MSSG SENDERS Number: ");
           Serial.println(buffer);
           String sendersnumber=buffer;
            // Uncomment these two lines to check the sender's cell number
            //validSender = false;
            //if ( strcmp(buffer, "\"+0123456789\",") == 0 )
            validSender = true;

            state = PS_READ_CMGR_SOMETHING;
            resetBuffer();
          }
        }
        break;

      case PS_READ_CMGR_SOMETHING:
        {
          if ( b == ',' ) {
            Serial.print("CMGR something A.K.A SENDER'S NAME: ");
            Serial.println(buffer);
            state = PS_READ_CMGR_DATE;
            resetBuffer();
          }
        }
        break;

      case PS_READ_CMGR_DATE:
        {
          if ( b == '\n' ) {
            Serial.print("CMGR date: ");
            Serial.println(buffer);
            state = PS_READ_CMGR_CONTENT;
            resetBuffer();
          }
        }
        break;

      case PS_READ_CMGR_CONTENT:
        {
          if ( b == '\n' ) {
            Serial.print("CMGR MESSAGE Content: ");
            Serial.print(buffer);
             String key=buffer;

           //  sendSMS();
           // GPSAnalyzer();

            GPRS.print("AT+CMGD=");
            GPRS.println(lastReceivedSMSId);

            //delay(500); don't do this!

            state = PS_DETECT_MSG_TYPE;
            resetBuffer();
          }
        }
        break;
      }

    }



      void GPSAnalyzer(byte b) 
     {

       buffer[pos++] = b;

      if ( pos >= sizeof(buffer) )
        resetBuffer();// just to be safe

        switch (state) 
      {
      case PS_DETECT_MSG_TYPE2: 
        {
          if ( b == '\n' )
            resetBuffer();
          else {        

            if ( pos == 9 ) {
             // Serial.print("Checking message type: ");
             // Serial.println(buffer);

              if ( strcmp(buffer, "+UGNSINF:") == 0 ) {
                Serial.println("Received CGNSINF:");            
                state = PS_READ_CMGR_STATUS2;
              }
              resetBuffer();
            }
          }
        }
        break;

        //CHECK
        case PS_IGNORING_COMMAND_ECHO2:
        {
          if ( b == '\n' ) {
            //Serial.print("Ignoring echo: ");
            //Serial.println(buffer);
            state = PS_DETECT_MSG_TYPE2;
            resetBuffer();
          }
        }
        break;

    //THIS WOULD READ FROM +CGNSINF: (TO THE COMMA),
      case PS_READ_CMGR_STATUS2:
        {
          if ( b == ',' ) {
            Serial.print("RUN STATUS: ");
            Serial.println(buffer);
            String runstatus=buffer;


            state = PS_READ_CMGR_NUMBER2;
            resetBuffer();
          }
        }
        break;

      case PS_READ_CMGR_NUMBER2:
        {
          if ( b == ',' ) {
            Serial.print("FIX STATUS : ");
           Serial.println(buffer);

           String fixstatus=buffer;
          fixstatus.replace(","," ");
            validSender = true;

            state = PS_READ_CMGR_SOMETHING2;
            resetBuffer();
          }
        }
        break;
    // this is DATE AND TIME i dont need this
      case PS_READ_CMGR_SOMETHING2:
        {
          if ( b == ',' ) {
            Serial.print("DATE AND TIME : ");
            Serial.println(buffer);
            String dateandtime=buffer;

            state = PS_READ_CMGR_DATE2;
            resetBuffer();
          }
        }
        break;

      case PS_READ_CMGR_DATE2:
        {
          if ( b == ',' ) {
            Serial.print("LATITUDE: ");
            Serial.println(buffer);
              latitude=buffer;
              latitude.replace(","," ");

            state = PS_READ_CMGR_CONTENT2;
            resetBuffer();
          }
        }
        break;

      case PS_READ_CMGR_CONTENT2:
        {
          if ( b == ',' ) {
            Serial.print("LONGITUDE: ");
            Serial.println(buffer);
            longitude=buffer;
            longitude.replace(","," ");

            state = PS_READ_VIDEO_CONTENT2;
            resetBuffer();
            //delay(500); don't do this!

          }
        }
        break;

       case PS_READ_VIDEO_CONTENT2:
       {
          if ( b == ',' ) {
            Serial.print("ALTITUDE: ");
            Serial.println(buffer);
            String Altitude=buffer;

            state = PS_READ_VIDEO2_CONTENT;
            resetBuffer();
            //delay(500); don't do this!
         }
        }
        break;

        case PS_READ_VIDEO2_CONTENT:
        {
         if ( b == ',' ) {
            Serial.print("SPEED(KM/HR): ");
            Serial.println(buffer);
            String Speed=buffer;
            Speed.replace(","," ");

                   state =PS_DETECT_MSG_TYPE2;
            resetBuffer();

          }
        }
        break;
      //use goto to put it at sms begining
      }
     }  

     void sendSMS() 
      {
        if ( strcmp(key,"A") == 0 )
    {
     float lati=7.200970;
     float longi=5.181782;
     float Speed1 = atof(Speed.c_str());
     float latituded = atof(latitude.c_str());
     float longituded = atof(longitude.c_str());
     float Distance = HaverSine(lati,longi,latituded,longituded);
     float duration=Distance/Speed1; 
     const int StrLen = 10; 
     char * duration_new ;
     double Value = duration; 
     (void) dtostrf (Value, StrLen, 6, duration_new); 

     String MESSAGE="BUS A";
     MESSAGE+=duration_new ; 
     Serial.print("THE MESSAGE SENT IS ");
     Serial.println(MESSAGE);
    }

     else if ( strcmp(key,"B") == 0 )
    {
     float lati=7.290970;
     float longi=5.141782;
     float Speed1 = atof(Speed.c_str());
     float latituded = atof(latitude.c_str());
     float longituded = atof(longitude.c_str());
     float Distance = HaverSine(lati,longi,latituded,longituded);
     float duration=Distance/Speed1; 
     const int StrLen = 10; 
     char * duration_new ;
     double Value = duration; 
     (void) dtostrf (Value, StrLen, 6, duration_new); 

     String MESSAGE="BUS B";
     MESSAGE+=duration_new ; 
     Serial.print("THE MESSAGE SENT IS ");
     Serial.println(MESSAGE);
    }


      delay(300);
      GPRS.print("AT+CMGF=1\r\n");                                                       
      delay(100);
      GPRS.println("AT+CMGS=\""+sendersnumber+"\"\r\n");                                   
      delay(100);
      GPRS.println(MESSAGE);       
      delay(100);
      GPRS.println((char)26);                       
      delay(100);
      GPRS.println();
      delay(100);
    }



    float HaverSine(float lat1,float lon1,float lat2,float lon2)
    {
      String fixstatus;
     float ToRad = PI / 180.0;
     float R = 6371;   // radius earth in Km

     float dLat = (lat2-lat1) * ToRad;
     float dLon = (lon2-lon1) * ToRad;

     float a = sin(dLat/2) * sin(dLat/2) +
           cos(lat1 * ToRad) * cos(lat2 * ToRad) *
           sin(dLon/2) * sin(dLon/2);
           String o= fixstatus + "8";


     float c = 2 * atan2(sqrt(a), sqrt(1-a));

     float d = R * c;
     return d;
    }

说明在所有声明和初始化之后,整个代码的第一个活动部分是for循环,只删除来自sim卡memory的所有以前的消息。它运行15次

for(int i = 1; i&lt; = 15; i ++){GPRS.print(&#34; AT + CMGD =&#34;); GPRS.println(ⅰ);延迟(300); while(GPRS.available())Serial.write(GPRS.read()); } 现在,具有功能GSM_NUM1(); GPSAnalyzer();发送短信();这些在代码

中定义如下

GSM_NUM1(); GPSAnalyzer();两者同样工作,他们提取所需的数据,这些数据以逗号分隔。对于进入的gps,格式为

+ UGNSINF:,,,,, ,,,,,,,,,,,,

提取了lathitude,speed和任何其他重要参数。

对于GSM_NUM1();它将发件人的消息和号码变为变量。

sendSMS();这只是基于收到的消息进行一些计算,并将一定的结果发送给请求它的号码。

OBERVATIONS

当程序启动时没有任何事情发生,这是好事,因为在新事物进入之前没有任何事情。因此,void loop(){while(GPRS.available())//只有当有可能时,{GSM_NUM1( GPRS.read()); //延迟(50); GPRS.println(&#34; AT + CGNSINF&#34); //延迟(40); GPSAnalyzer(GPRS.read());发送短信();现在这是事情变得糟糕,因为第一个函数运行良好,它等待获取消息并提取发件人号码和消息&#34; key&#34;变量,但之后我想要一次返回下面显示的gps信息,这就是我使用的原因(&#34; AT + CGNSINF&#34;);而不是(&#34; AT + CGNSURC = 1&#34;);因为后者提供了连续的gps数据,例如

+ UGNSINF:,,,,, ,,,,,,,,,,,,

但不是要获得gps数据的一行,而是将其他一些参数提取到变量&#34;程序中的HANGS / STOPS由于某种未知原因。

怀疑

由于SIM808在同一模块上具有gps / gsm。在某种意义上将它们分开是很棘手的。

如果我希望GPS能够接通但未读取任何数据,直到有效请求进入,以短信形式发送,然后需要GPS信息,并且已经完成了一些计算以获得将要发送的参数要求的相同数字。

PERSONNALY,我觉得让GPS和GSM在手上工作,而不是以某种方式取消其他方式,这将成为我的问题的终结。而且我认为它会降低到命令的位置

GPRS.println(&#34; AT + CGNSURC = 1&#34);和/或GPRS.println(&#34; AT + CGNSINF&#34;);因为前者在调用一次时连续吐出每个GNSS FIX的gps数据,而LATER每个命令只吐出一次。

附图显示了(&#34; AT + CGNSURC = 1&#34;)输出的连续性质; ,就像(&#34; AT + CGNSINF&#34;);用+ CGNSINF吐出一行:在开头而不是

2 个答案:

答案 0 :(得分:0)

请检查是否存在溢出SRAM,这会在执行程序时产生异常情况。当您声明这么多变量时会发生这种情况,您可以使用此library来检查sram的使用。

答案 1 :(得分:0)

我遇到了类似的问题,试图通过串行方式从模块中获取GPS数据,但经过数小时的努力才弄清楚了。本质上,您需要验证每个命令的每个响应,并在每次写入之前刷新串行端口。

在编写任何命令之前刷新串行端口缓冲区将确保您在尝试获取刚刚运行的命令的输出时不会意外读取上一个命令的剩余字符。大多数TA(终端适配器)使用EOL字符(如OK)转换为“ \ r \ nOK \ r \ n”。如果您没有全部阅读它们,它们可能会徘徊并干扰您发送/读取响应的下一个命令。 发送命令之前,请使用GPRS.flush()消除串行缓冲区中多余的垃圾字符。

此外,创建一个通用命令函数来传递所有AT命令并验证其输出将为您节省很多时间。

类似

git mv Dir/

我写这个是为了与simcom5320通信,但是我没有使用软件串行,所以对您来说会有些不同。对所有at命令使用此功能,以确保一切都成功完成,例如:

int sendCommand(int fd, char* message, char* eol, char* response){
 int wlen, rlen;
 char buf[1024];

 tcflush(fd, TCIOFLUSH); //flush the serial port to remove anything left over

 wlen = write(fd, message, strlen(message)); //write command to terminal

   tcdrain(fd); //delay until 1st readable character is written by modem
   delay(100); //delay a little longer until all characters are written(hopefully)

   rdlen = read(fd, buf, sizeof(buf) - 1); //read from serial port

   if(rdlen > 0){ //if readable characters
     if(strstr(buf, eol) != NULL){ //if my end of line character is present then 
       int i = 0;                  //output from TA is complete
       while(buf[i] != '\0'){ //while buffer has more characters
        response[i] = buf[i]; //copy string into the string I passed, char by char
       }
       return 1; //return 1 (i.e.true aka success)
     }
   }
   return 0; //return 0 (i.e. false aka failure)
}

希望这会有所帮助!