通过串口从GPS传感器读取

时间:2019-11-09 12:36:00

标签: c++ serial-port gps

我是C ++的初学者,请保持友善,

我想读取gps传感器发送的数据。

我的代码现在看起来像这样:

#include <iostream>
#include <stdio.h>      // standard input / output functions
#include <stdlib.h>
#include <string.h>     // string function definitions
#include <unistd.h>     // UNIX standard function definitions
#include <fcntl.h>      // File control definitions
#include <errno.h>      // Error number definitions
#include <termios.h>    // POSIX terminal control definitions
#include <string>
#include <sstream>
#include <vector>

char * testSerialComm(int USB)
{
    /* *** Configure Port *** */
        struct termios tty;
        memset (&tty, 0, sizeof tty);

    /* Error Handling */
        if ( tcgetattr ( USB, &tty ) != 0 )
        {
            std::cout << "Error " << errno << " from tcgetattr: " << strerror(errno) << std::endl;
        }

    /* Set Baud Rate */
        cfsetospeed (&tty, B9600);
        cfsetispeed (&tty, B9600);

    /* Setting other Port Stuff */
        tty.c_cflag     &=  ~PARENB;        // Make 8n1
        tty.c_cflag     &=  ~CSTOPB;
        tty.c_cflag     &=  ~CSIZE;
        tty.c_cflag     |=  CS8;
        tty.c_cflag     &=  ~CRTSCTS;       // no flow control
        tty.c_lflag     =   0;          // no signaling chars, no echo, no canonical processing
        tty.c_oflag     =   0;                  // no remapping, no delays
        tty.c_cc[VMIN]      =   0;                  // read doesn't block
        tty.c_cc[VTIME]     =   15;                  // 0.5 seconds read timeout

        tty.c_cflag     |=  CREAD | CLOCAL;     // turn on READ & ignore ctrl lines
        tty.c_iflag     &=  ~(IXON | IXOFF | IXANY);// turn off s/w flow ctrl
        tty.c_lflag     &=  ~(ICANON | ECHO | ECHOE | ISIG); // make raw
        tty.c_oflag     &=  ~OPOST;              // make raw

    /* Flush Port, then applies attributes */
        tcflush( USB, TCIFLUSH );

        if ( tcsetattr ( USB, TCSANOW, &tty ) != 0)
        {
            std::cout << "Error " << errno << " from tcsetattr" << std::endl;
        }

    /* *** WRITE *** */

        unsigned char cmd[] = {'I', 'N', 'I', 'T', ' ', '\r', '\0'};
        int n_written = write( USB, cmd, sizeof(cmd) -1 );

    /* Allocate memory for read buffer */
        char buf [1024];
        memset (&buf, '\0', sizeof buf);

    /* *** READ *** */
        int n = read( USB, &buf , sizeof buf );

    /* Error Handling */
        if (n < 0)
        {
            std::cout << "Error reading: " << strerror(errno) << std::endl;
        }

    /* Print what I read... */
       return buf;

    close(USB);
}

int main() {
    /* Open File Descriptor */
    int USB = open( "/dev/tty.usbmodem14201", O_RDONLY | O_NDELAY | O_NONBLOCK);

    /* Error Handling */
    if ( USB < 0 )
    {
        std::cout << "Error " << errno << " opening " << "/dev/ttyUSB0" << ": " << strerror (errno) << std::endl;
    }
    while(true){
        std::string g = testSerialComm(USB);
        std::stringstream stringStream(g);
        std::string segment;
        std::vector<std::string> seglist;

        while(std::getline(stringStream, segment))
        {
            seglist.push_back(segment);
        }
        for(int i = 0; i < seglist.size(); i++){
            std::string s = seglist[i];
            if( g != ""){
                if(s.find("$GNGLL") != std::string::npos){
                    std::cout << g ;
                    if(s.find(",,,,,") != std::string::npos){
                        std::cout << "Keine Position erkannt" << std::endl;
                    }
                    else{
                        std::cout << "s = " << s;
                        std::stringstream stringStream(s);
                        std::string segment2;
                        std::vector<std::string> seglist2;
                        while(std::getline(stringStream, segment))
                        {
                            seglist2.push_back(segment2);
                        }
                        std::cout << "Lat: "<< seglist2[1] << " " << seglist2[2] << std::endl;
                        std::cout << "Lon: "<< seglist2[3] << " " << seglist2[4] << std::endl;
                        std::cout << "UTC Time: " << seglist2[5] << std::endl;
                    }
                }
            }
        }
    }
    return 0;
}

输出看起来像这样:

$GNVTG,,T,,M,1.346,N,2.493,K,A*31
$GNGGA,162555.00,5219.07535,N,01337.93745,E,1,06,2.06,41.2,M,42.1,M,,*71
$GNGSA,A,3,08,21,13,15,27,05,,,,,,,3.73,2.06,3.11*11
$GNGSA,A,3,,,,,,,,,,,,,3.73,2.06,3.11*1C
$GPGSV,3,1,11,04,15,114,15,05,51,227,14,07,34,067,18,08,15,050,24*7F
$GPGSV,3,2,11,09,00,116,,13,57,291,09,15,24,295,19,21,10,325,12*75
$GPGSV,3,3,11,27,07,017,09,28,45,149,,30,68,074,20*4F
$GLGSV,1,1,01,,,,23*65
$GNGLL,5219.07535,N,01337.93745,E,162555.00,A,A*76
$GNRMC,162556.00,A,5219.07530,N,01337.93762,E,0.984,,071119,,,A*$GPGSV,3,1,11,04,15,114,15,05,51,227,14,07,34,067,18,08,15,050,24*7F
$GPGSV,3,2,11,09,00,116,,13,57,291,10,15,24,295,19,21,10,325,11*7E
$GPGSV,3,3,11,27,07,017,09,28,45,149,,30,68,074,20*4F
$GLGSV,1,1,01,,,,22*64
$GNGLL,5219.07530,N,01337.93762,E,162556.00,A,A*75
$GNRMC,162557.00,A,5219.07530,N,01337.93755,E,1.021,,071119,,,A*64
$GNVTG,,T,,M,1.021,N,1.890,K,A*3F
$GNGGA,162557.00,5219.07530,N,01337.93755,E,1,06,2.06,40.8,M,42.1,M,,*7C
$GNGSA,A,3,08,21,13,15,27,05,,,,,,,3.72,2.06,3.10*11
$GNGSA,A,3,,,,,,,,,,,,,3.72,2.06,3.10*1C
$GPGSV,3,1,11,04,15,114,15,05,51,227,14,07,34,067,19,08,15,050,23*79
$GPGSV,3,2,11,09,00,116,,13,57,291,12,15,24,295,19,21,10,325,09*75
$GPGSV,3,3,11,27,07,017,11,28,45,149,,30,68,074,19*4C
$GLGSV,1,1,01,,,,22*64
$GNGLL,5219.07530,N,01337.93755,E,162557.00,A,A*70
$GNRMC,162558.00,A,5219.07513,N,01337.93724,E,0.889,,071119,,,A*67
$GNVTG,,T,,M,0.889,N,1.646,K,A*31
$GNGGA,162558.00,5219.07513,N,01337.93724,E,1,06,2.06,40.8,M,42.1,M,,*74
$GNGSA,A,3,08,21,13,15,27,05,,,,,,,3.72,2.06,3.10*11
$GNGSA,A,3,,,,,,,,,,,,,3.72,2.06,3.10*1C
$GPGSV,3,1,11,04,15,114,13,05,51,227,14,07,34,067,20,08,15,050,22*74
$GPGSV,3,2,11,09,00,116,,13,57,291,10,15,24,295,19,21,10,325,13*7C
$GPGSV,3,3,11,27,07,017,09,28,45,149,,30,68,074,19*45
$GLGSV,1,1,01,,,,23*65
$GNGLL,5219.07513,N,01337.93724,E,162558.00,A,A*78
$GNRMC,162559.00,A,5219.07523,N,01337.93720,E,0.766,,071119,,,A*$GNGSA,A,3,,,,,,,,,,,,,3.72,2.06,3.10*1C
$GPGSV,3,1,11,04,15,114,12,05,51,227,14,07,34,067,19,08,15,050,23*7E
$GPGSV,3,2,11,09,00,116,,13,57,291,10,15,24,295,19,21,10,325,11*7E
$GPGSV,3,3,11,27,07,017,08,28,45,149,,30,68,074,18*45
$GLGSV,1,1,01,,,,23*65
$GNGLL,5219.07523,N,01337.93720,E,162559.00,A,A*7E
Keine Position erkannt
$GNRMC,162600.00,A,5219.07611,N,01337.93712,E,0.764,,071119,,,A*$GPGSV,3,3,11,27,07,017,13,28,45,149,,30,68,074,19*4E
$GLGSV,1,1,01,,,,22*64
$GNGLL,5219.07611,N,01337.93712,E,162600.00,A,A*72
$GNRMC,162601.00,A,5219.07575,N,01337.93735,E,0.483,,071119,,,A*6E
$GNVTG,,T,,M,0.483,N,0.895,K,A*36
$GNGGA,162601.00,5219.07575,N,01337.93735,E,1,06,2.05,40.3,M,42.1,M,,*73
$GNGSA,A,3,08,21,13,15,27,05,,,,,,,3.72,2.05,3.10*12
$GNGSA,A,3,,,,,,,,,,,,,3.72,2.05,3.10*1F
$GPGSV,3,1,11,04,15,114,13,05,51,227,15,07,34,067,19,08,15,050,23*7E
$GPGSV,3,2,11,09,00,116,,13,57,291,10,15,24,295,18,21,10,325,13*7D
$GPGSV,3,3,11,27,07,017,12,28,45,149,,30,68,074,19*4F
$GLGSV,1,1,01,,,,22*64
$GNGLL,5219.07575,N,01337.93735,E,162601.00,A,A*77
Keine Position erkannt
$GNRMC,162602.00,V,,,,,,,071119,,,N*6D
$GNVTG,,,,,,,,,N*2E
$GNGGA,162602.00,,,,,0,05,15.84,,,,,,*74
$GNGSA,A,1,08,21,15,27,05,,,,,,,,36.98,15.84,33.41*28
$GNGSA,A,1,,,,,,,,,,,,,36.98,15.84,33.41*27
$GPGSV,3,1,11,04,15,114,12,05,51,227,16,07,34,067,19,08,15,050,22*7D
$GPGSV,3,2,11,09,00,116,,13,57,291,06,15,24,295,17,21,10,325,17*71
$GPGSV,3,3,11,27,07,017,08,28,45,149,,30,68,074,18*45
$GLGSV,1,1,01,,,,23*65
$GNGLL,,,,,162602.00,V,N*55
Keine Position erkannt
$GNRMC,162603.00,A,5219.07421,N,01337.93894,E,0.811,,071119,,,A*$GNGSA,A,3,,,,,,,,,,,,,3.72,2.05,3.10*1F
$GPGSV,3,1,11,04,15,114,10,05,51,227,15,07,34,067,18,08,15,050,21*7E
$GPGSV,3,2,11,09,00,116,,13,57,291,09,15,24,295,17,21,10,325,10*79
$GPGSV,3,3,11,27,07,017,07,28,45,149,,30,68,074,18*4A
$GLGSV,1,1,01,,,,23*65
$GNGLL,5219.07421,N,01337.93894,E,162603.00,A,A*71
Keine Position erkannt
$GNRMC,162604.00,A,5219.07430,N,01337.93925,E,0.640,,071119,,,A*69
$GNVTG,,T,,M,0.640,N,1.186,K,A*31
$GNGGA,162604.00,5219.07430,N,01337.93925,E,1,06,2.05,40.8,M,42.1,M,,*72
$GNGSA,A,3,08,21,13,15,27,05,,,,,,,3.72,2.05,3.10*12
$GNGSA,A,3,,,,,,,,,,,,,3.72,2.05,3.10*1F
$GPGSV,3,1,11,04,15,114,,05,51,227,14,07,34,067,18,08,15,050,21*7E
$GPGSV,3,2,11,09,00,116,,13,57,291,09,15,24,295,18,21,10,325,18*7E
$GPGSV,3,3,11,27,07,017,08,28,45,149,,30,68,074,18*45
$GLGSV,1,1,01,,,,22*64
$GNGLL,5219.07430,N,01337.93925,E,162604.00,A,A*7D

Process finished with exit code 15

我遇到了几个问题:

首先:每次插拔电源时,usb设备的名称都会更改。唯一改变的是数字。因此它从以下更改:

/dev/tty.usbmodem14201

收件人:

/dev/tty.usbmodem14101

如何找到正确的设备名称?

第二个问题: 我想从GPS传感器获取位置。如果它有位置,则消息看起来像这样:

$GNGLL,,,,,162602.00,V,N*55

获得职位后,它看起来像这样:

$GNGLL,5219.07430,N,01337.93925,E,162604.00,A,A*7D

坐标在第二和第四段中: $ GNGLL, 5219.07430 ,N, 01337.93925 ,E,162604.00,A,A * 7D

我的主要问题是,我想逐行读取设备,但是read( USB, &buf , sizeof buf );方法不适合这种情况。

1 个答案:

答案 0 :(得分:0)

#$GNGLL decoder


import serial

port = "/dev/ttyS0"

def parseGPS(data):
#   print "raw:", data #prints raw data
    if data[0:6] == "$GNGLL":
        sdata = data.split(",")
        if sdata[2] == 'V':
            print "no satellite data available"
            return
        print "---Parsing GNGLL---",
        time = sdata[5][0:2] + ":" + sdata[5][2:4] + ":" + sdata[5][4:6]
        lat = decode(sdata[1]) #latitude
        lon = decode(sdata[3]) #longitute

        print  time+" "+lat+" "+lon


def decode(coord):
    #Converts  DMS to decimal system
       
    if(coord[0:1]=='0'):
      gps = coord[1:3]
    else:
      gps=coord[0:2]
    gps1=float(gps)+round((float(coord)/60)%10,4)
    return str(gps1)


print "Receiving GPS data"
ser = serial.Serial(port, baudrate = 9600, timeout = 0.5)
while True:
    data = ser.readline()
    parseGPS(data)