(8-1)STM32开发例程 GPS和ESP串口传输 arduino解析GPS数据自写协议

发布时间 2023-03-25 00:07:30作者: MKT-porter

 

 

 

 

 

 

#include "API_Gps.h"






#include <SoftwareSerial.h>
SoftwareSerial Serial_Gps(4, 5);


#define GNRMC_TERM "$GNRMC,"                //定义要解析的指令,因为这条指令包含定位和时间信息
char nmeaSentence[68];
String latitude;                //纬度
String longitude;                //经度
String lndSpeed;                //速度
String gpsTime;                        //UTC时间,本初子午线经度0度的时间,和北京时间差8小时
String beiJingTime;                //北京时间



void Get_Gps(){
  
   // For one second we parse GPS data and report some key values
  for (unsigned long start = millis(); millis() - start < 1000;)        //一秒钟内不停扫描GPS信息
  {
    while (Serial_Gps.available())        //串口获取到数据开始解析
    {
      char c = Serial_Gps.read();        //读取一个字节获取的数据

      switch(c)                                        //判断该字节的值
      {
        case '$':                                        //若是$,则说明是一帧数据的开始
          Serial_Gps.readBytesUntil('*', nmeaSentence, 67);                //读取接下来的数据,存放在nmeaSentence字符数组中,最大存放67个字节
          //Serial_Gps.println(nmeaSentence);
          latitude = parseGNRMcLat(nmeaSentence);        //获取纬度值
          longitude = parseGNRMcLon(nmeaSentence);//获取经度值
          lndSpeed = parseGNRMcSpeed(nmeaSentence);//获取速度值
          gpsTime = parseGNRMcTime(nmeaSentence);//获取GPS时间
  
  
          if(latitude > "")                //当不是空时候打印输出
          {
            Serial.println("------------------------------------");
            Serial.println("latitude: " + latitude);
          }
  
          if(longitude > "")                //当不是空时候打印输出
          {
            Serial.println("longitude: " + longitude);
          }  
  
          if(lndSpeed > "")                //当不是空时候打印输出
          {
            Serial.println("Speed (knots): " + lndSpeed);
          }
  
          if(gpsTime > "")                //当不是空时候打印输出
          {
            Serial.println("gpsTime: " + gpsTime);
            beiJingTime = getBeiJingTime(gpsTime);        //获取北京时间
            Serial.println("beiJingTime: " + beiJingTime);        
          }               
      }//switch(c)  
    }// while
  }//for
  
  
}


void setup()        //初始化内容
{
  Serial.begin(9600);    
  Serial_Gps.begin(9600);  //定义波特率9600,
}

void loop()                //主循环
{
   Get_Gps();


   
 
}//loop()   

  

 

API_Gps.h

String getBeiJingTime(String s)
{
  int hour = s.substring(0,2).toInt();
  int minute = s.substring(2,4).toInt();
  int second = s.substring(4,6).toInt();

  hour += 8;

  if(hour > 24)
    hour -= 24;
  s = String(hour) + String(minute) + String(second);
  return s;
}

//Parse GNRMC NMEA sentence data from String
//String must be GNRMC or no data will be parsed
//Return Latitude
String parseGNRMcLat(String s)
{
  int pLoc = 0; //paramater location pointer
  int lEndLoc = 0; //lat parameter end location
  int dEndLoc = 0; //direction parameter end location
  String lat;
  /*make sure that we are parsing the GNRMC string.
   Found that setting s.substring(0,5) == "GNRMC" caused a FALSE.
   There seemed to be a 0x0D and 0x00 character at the end. */
  if(s.substring(0,4) == "GNRM")
  {
    //Serial.println(s);
    for(int i = 0; i < 5; i++)
    {
      if(i < 3)
      {
        pLoc = s.indexOf(',', pLoc+1);
        /*Serial.print("i < 3, pLoc: ");
         Serial.print(pLoc);
         Serial.print(", ");
         Serial.println(i);*/
      }
      if(i == 3)
      {
        lEndLoc = s.indexOf(',', pLoc+1);
        lat = s.substring(pLoc+1, lEndLoc);
        /*Serial.print("i = 3, pLoc: ");
         Serial.println(pLoc);
         Serial.print("lEndLoc: ");
         Serial.println(lEndLoc);*/
      }
      else
      {
        dEndLoc = s.indexOf(',', lEndLoc+1);
        lat = lat + " " + s.substring(lEndLoc+1, dEndLoc);
        /*Serial.print("i = 4, lEndLoc: ");
         Serial.println(lEndLoc);
         Serial.print("dEndLoc: ");
         Serial.println(dEndLoc);*/
      }
    }
    return lat;
  }
  //}
  //}
}

//Parse GNRMC NMEA sentence data from String
//String must be GNRMC or no data will be parsed
//Return Longitude
String parseGNRMcLon(String s)
{
  int pLoc = 0; //paramater location pointer
  int lEndLoc = 0; //lat parameter end location
  int dEndLoc = 0; //direction parameter end location
  String lon;

  /*make sure that we are parsing the GNRMC string.
   Found that setting s.substring(0,5) == "GNRMC" caused a FALSE.
   There seemed to be a 0x0D and 0x00 character at the end. */
  if(s.substring(0,4) == "GNRM")
  {
    //Serial.println(s);
    for(int i = 0; i < 7; i++)
    {
      if(i < 5)
      {
        pLoc = s.indexOf(',', pLoc+1);
        /*Serial.print("i < 3, pLoc: ");
         Serial.print(pLoc);
         Serial.print(", ");
         Serial.println(i);*/
      }
      if(i == 5)
      {
        lEndLoc = s.indexOf(',', pLoc+1);
        lon = s.substring(pLoc+1, lEndLoc);
        /*Serial.print("i = 3, pLoc: ");
         Serial.println(pLoc);
         Serial.print("lEndLoc: ");
         Serial.println(lEndLoc);*/
      }
      else
      {
        dEndLoc = s.indexOf(',', lEndLoc+1);
        lon = lon + " " + s.substring(lEndLoc+1, dEndLoc);
        /*Serial.print("i = 4, lEndLoc: ");
         Serial.println(lEndLoc);
         Serial.print("dEndLoc: ");
         Serial.println(dEndLoc);*/
      }
    }
    return lon;
  }
}

//Parse GNRMC NMEA sentence data from String
//String must be GNRMC or no data will be parsed
//Return Longitude
String parseGNRMcSpeed(String s)
{
  int pLoc = 0; //paramater location pointer
  int lEndLoc = 0; //lat parameter end location
  int dEndLoc = 0; //direction parameter end location
  String lndSpeed;

  /*make sure that we are parsing the GNRMC string.
   Found that setting s.substring(0,5) == "GNRMC" caused a FALSE.
   There seemed to be a 0x0D and 0x00 character at the end. */
  if(s.substring(0,4) == "GNRM")
  {
    //Serial.println(s);
    for(int i = 0; i < 8; i++)
    {
      if(i < 7)
      {
        pLoc = s.indexOf(',', pLoc+1);
        /*Serial.print("i < 8, pLoc: ");
         Serial.print(pLoc);
         Serial.print(", ");
         Serial.println(i);*/
      }
      else
      {
        lEndLoc = s.indexOf(',', pLoc+1);
        lndSpeed = s.substring(pLoc+1, lEndLoc);
        /*Serial.print("i = 8, pLoc: ");
         Serial.println(pLoc);
         Serial.print("lEndLoc: ");
         Serial.println(lEndLoc);*/
      }
    }
    return lndSpeed;
  }
}


//Parse GNRMC NMEA sentence data from String
//String must be GNRMC or no data will be parsed
//Return Longitude
String parseGNRMcTime(String s)
{
  int pLoc = 0; //paramater location pointer
  int lEndLoc = 0; //lat parameter end location
  int dEndLoc = 0; //direction parameter end location
  String gpsTime;

  /*make sure that we are parsing the GNRMC string.
   Found that setting s.substring(0,5) == "GNRMC" caused a FALSE.
   There seemed to be a 0x0D and 0x00 character at the end. */
  if(s.substring(0,4) == "GNRM")
  {
    //Serial.println(s);
    for(int i = 0; i < 2; i++)
    {
      if(i < 1)
      {
        pLoc = s.indexOf(',', pLoc+1);
        /*Serial.print("i < 8, pLoc: ");
         Serial.print(pLoc);
         Serial.print(", ");
         Serial.println(i);*/
      }
      else
      {
        lEndLoc = s.indexOf(',', pLoc+1);
        gpsTime = s.substring(pLoc+1, lEndLoc);
        /*Serial.print("i = 8, pLoc: ");
         Serial.println(pLoc);
         Serial.print("lEndLoc: ");
         Serial.println(lEndLoc);*/
      }
    }
    return gpsTime;
  }
}

// Turn char[] array into String object
String charToString(char *c)
{

  String val = "";

  for(int i = 0; i <= sizeof(c); i++)
  {
    val = val + c;
  }

  return val;
}