string - 解析 GNSS - NMEA 字符串

标签 string parsing arduino gps nmea

您好,我编写了一个代码来解析 GNSS - NMEA 字符串,但目前我遇到了麻烦,因为 strtok 似乎有时会错过该字符,因此无法正确拆分字符串。

这段代码有什么问题?

奇怪的是,我基本上从来没有得到过Fixstatus。 GNSSrunstatus 也是如此,这就是我从 Serial.println(Fixstatus) 和 strcpy(Fixstatus) 开始的原因。

附注:它适用于 Arduino 项目。

#include <SoftwareSerial.h>

char frame[100];
char GNSSrunstatus[1];
char Fixstatus[1];
char UTCdatetime[18];
char latitude[10];
char logitude[11];
char altitude[8];
char speedOTG[6];
char course[6];
char fixmode[1];
char HDOP[4];
char PDOP[4];
char VDOP[4];
char satellitesinview[2];
char GNSSsatellitesused[2];
char GLONASSsatellitesused[2];
char cn0max[2];
char HPA[6];
char VPA[6];

boolean state;
double serialnr;

SoftwareSerial mySerial(10, 11); // RX, TX

void setup() {
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }


  Serial.println("Alles OK");

  // set the data rate for the SoftwareSerial port
  mySerial.begin(9600);
  mySerial.println("AT");
  mySerial.println("AT+CGNSPWR=1");
}

void loop() { // run over and over

  get_GPS();

}

int8_t get_GPS() {

  int8_t counter, answer;
  long previous;

  // First get the NMEA string
  // Clean the input buffer
  while ( mySerial.available() > 0) mySerial.read();
  // request Basic string
  mySerial.println("AT+CGNSINF"); //sendATcommand("AT+CGNSINF", "AT+CGNSINF\r\n\r\n", 2000);

  counter = 0;
  answer = 0;
  memset(frame, '\0', sizeof(frame));    // Initialize the string
  previous = millis();
  // this loop waits for the NMEA string
  do {

    if (mySerial.available() != 0) {
      frame[counter] = mySerial.read();
      counter++;
      // check if the desired answer is in the response of the module
      if (strstr(frame, "OK") != NULL)
      {
        answer = 1;
      }
    }
    // Waits for the asnwer with time out
  }
  while ((answer == 0) && ((millis() - previous) < 2000));

  frame[counter - 3] = '\0';

  // Parses the string
  strtok(frame, ",");
  strcpy(Fixstatus, strtok(NULL, ",")); // Gets Fix status
  strcpy(UTCdatetime, strtok(NULL, ",")); // Gets UTC date and time
  strcpy(latitude, strtok(NULL, ",")); // Gets latitude
  strcpy(logitude, strtok(NULL, ",")); // Gets longitude
  strcpy(altitude, strtok(NULL, ",")); // Gets MSL altitude
  strcpy(speedOTG, strtok(NULL, ",")); // Gets speed over ground
  strcpy(course, strtok(NULL, ",")); // Gets course over ground
  strcpy(fixmode, strtok(NULL, ",")); // Gets Fix Mode
  strtok(NULL, ",");
  strcpy(HDOP, strtok(NULL, ",")); // Gets HDOP
  strcpy(PDOP, strtok(NULL, ",")); // Gets PDOP
  strcpy(VDOP, strtok(NULL, ",")); // Gets VDOP
  strtok(NULL, ",");
  strcpy(satellitesinview, strtok(NULL, ",")); // Gets GNSS Satellites in View
  strcpy(GNSSsatellitesused, strtok(NULL, ",")); // Gets GNSS Satellites used
  strcpy(GLONASSsatellitesused, strtok(NULL, ",")); // Gets GLONASS Satellites used
  strtok(NULL, ",");
  strcpy(cn0max, strtok(NULL, ",")); // Gets C/N0 max
  strcpy(HPA, strtok(NULL, ",")); // Gets HPA
  strcpy(VPA, strtok(NULL, "\r")); // Gets VPA

Serial.println("Fixstatus");
  Serial.println(Fixstatus);
Serial.println("UTCdatetime");
  Serial.println(UTCdatetime);
Serial.println("latitude");  
  Serial.println(latitude);
Serial.println("logitude");
  Serial.println(logitude);
Serial.println("altitude");
  Serial.println(altitude);
Serial.println("speedOTG");
  Serial.println(speedOTG);
Serial.println("course");
  Serial.println(course);
Serial.println("fixmode");
  Serial.println(fixmode);
Serial.println("HDOP");
  Serial.println(HDOP);
Serial.println("PDOP");
  Serial.println(PDOP);
Serial.println("VDOP");
  Serial.println(VDOP);
Serial.println("satellitesinview");
  Serial.println(satellitesinview);
Serial.println("GNSSsatellitesused");
  Serial.println(GNSSsatellitesused);
Serial.println("GLONASSsatellitesused");
  Serial.println(GLONASSsatellitesused);
Serial.println("cn0max");
  Serial.println(cn0max);
Serial.println("HPA");
  Serial.println(HPA);
Serial.println("VPA");
  Serial.println(VPA);

  return answer;
}

如果我不解析字符串,输出看起来像这样:

AT

OK
AT+CGNSPWR=1

OK
AT+CGNSINF

+CGNSINF: 1,1,20160501124254.000,47.199897,9.442750,473.500,0.35,36.8,1,,1.1,1.9,1.6,,13,7,,,39,,

OK

解析代码的输出(不是每次):

Fixstatus

UTCdatetime
20160501124554.000
latitude
47.199923
logitude
9.442710
altitude
474.100
speedOTG
0.37
course

fixmode
1
HDOP
1.3
PDOP
0.8
VDOP
?>0

此外还有 SIM808 和 GNSS NEMA 字符串的手册(第 9-10 页): Manual

最佳答案

这段代码现在可以完美地解决我的问题:

#include <SoftwareSerial.h>

char frame[200];
char GNSSrunstatus[2];
char Fixstatus[2];
char UTCdatetime[19];
char latitude[11];
char logitude[12];
char altitude[9];
char speedOTG[7];
char course[7];
char fixmode[2];
char HDOP[5];
char PDOP[5];
char VDOP[5];
char satellitesinview[3];
char GNSSsatellitesused[3];
char GLONASSsatellitesused[3];
char cn0max[3];
char HPA[7];
char VPA[7];

boolean state;
double serialnr;

SoftwareSerial mySerial(10, 11); // RX, TX

void setup() {
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }

  Serial.println("Alles OK");

  // set the data rate for the SoftwareSerial port
  mySerial.begin(9600);
  mySerial.println("AT");
  mySerial.println("AT+CGNSPWR=1");
}

void loop() { // run over and over
  get_GPS();
}

int8_t get_GPS() {

  int8_t counter, answer;
  long previous;

  // First get the NMEA string
  // Clean the input buffer
  strcpy(frame, "+CGNSINF: 1,1,20160501124254.000,47.199897,9.442750,473.500,0.35,36.8,1,,1.1,1.9,1.6,,13,7,,,39,, OK");

  // Parses the string
  strtok_single(frame, " ");
  strcpy(GNSSrunstatus, strtok_single(NULL, ","));// Gets GNSSrunstatus
  strcpy(Fixstatus, strtok_single(NULL, ",")); // Gets Fix status
  strcpy(UTCdatetime, strtok_single(NULL, ",")); // Gets UTC date and time
  strcpy(latitude, strtok_single(NULL, ",")); // Gets latitude
  strcpy(logitude, strtok_single(NULL, ",")); // Gets longitude
  strcpy(altitude, strtok_single(NULL, ",")); // Gets MSL altitude
  strcpy(speedOTG, strtok_single(NULL, ",")); // Gets speed over ground
  strcpy(course, strtok_single(NULL, ",")); // Gets course over ground
  strcpy(fixmode, strtok_single(NULL, ",")); // Gets Fix Mode
  strtok_single(NULL, ",");
  strcpy(HDOP, strtok_single(NULL, ",")); // Gets HDOP
  strcpy(PDOP, strtok_single(NULL, ",")); // Gets PDOP
  strcpy(VDOP, strtok_single(NULL, ",")); // Gets VDOP
  strtok_single(NULL, ",");
  strcpy(satellitesinview, strtok_single(NULL, ",")); // Gets GNSS Satellites in View
  strcpy(GNSSsatellitesused, strtok_single(NULL, ",")); // Gets GNSS Satellites used
  strcpy(GLONASSsatellitesused, strtok_single(NULL, ",")); // Gets GLONASS Satellites used
  strtok_single(NULL, ",");
  strcpy(cn0max, strtok_single(NULL, ",")); // Gets C/N0 max
  strcpy(HPA, strtok_single(NULL, ",")); // Gets HPA
  strcpy(VPA, strtok_single(NULL, "\r")); // Gets VPA

Serial.println("GNSSrunstatus");
  Serial.println(GNSSrunstatus);
Serial.println("Fixstatus");
  Serial.println(Fixstatus[0]);
Serial.println("UTCdatetime");
  Serial.println(UTCdatetime);
Serial.println("latitude"); 
  Serial.println(latitude);
Serial.println("logitude");
  Serial.println(logitude);
Serial.println("altitude");
  Serial.println(altitude);
Serial.println("speedOTG");
  Serial.println(speedOTG);
Serial.println("course");
  Serial.println(course);
Serial.println("fixmode");
  Serial.println(fixmode);
Serial.println("HDOP");
  Serial.println(HDOP);
Serial.println("PDOP");
  Serial.println(PDOP);
Serial.println("VDOP");
  Serial.println(VDOP);
Serial.println("satellitesinview");
  Serial.println(satellitesinview);
Serial.println("GNSSsatellitesused");
  Serial.println(GNSSsatellitesused);
Serial.println("GLONASSsatellitesused");
  Serial.println(GLONASSsatellitesused);
Serial.println("cn0max");
  Serial.println(cn0max);
Serial.println("HPA");
  Serial.println(HPA);
Serial.println("VPA");
  Serial.println(VPA);

  return answer;
}

/* strtok_fixed - fixed variation of strtok_single */
static char *strtok_single(char *str, char const *delims)
{
    static char  *src = NULL;
    char  *p,  *ret = 0;

    if (str != NULL)
        src = str;

    if (src == NULL || *src == '\0')    // Fix 1
        return NULL;

    ret = src;                          // Fix 2
    if ((p = strpbrk(src, delims)) != NULL)
    {
        *p  = 0;
        src = ++p;
    }
    else
        src += strlen(src);

    return ret;
}

关于string - 解析 GNSS - NMEA 字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36967099/

相关文章:

java - 删除数组中的重复项,Java

android - 能否通过SAX解析器快速获取指定标签的值?

serial-port - Pharo:从 Arduino 串口读取字节

c++ - 无法调整缓冲区以适应数据

Python - 为什么它不发送值 incomingState?

c++ - 用 const char* 填充 wstring 的最佳方法

c# - c#中如何从一个字符串中提取一个字符串

string - 对某些情况的按位运算澄清

java - 在服务器端为 ColdFusion 实现 Showdown.js markdown 解析器

python dateutil.parser 错误(??)解析