go - 无法通过串口解析 GPS 信息

原文 标签 go serial-port gps

我使用了以下软件包:

  • 从串行端口读取 ( go get go.bug.st/serial )
  • 解析来自串行端口的传入消息 ( go get adrianmo/go-nmea )

  • 主机 : Windows 10
    转到版本: go 版本 go1.14.4 windows/amd64
    根据文档,我编写了一个简单的代码,打开专用串行端口( COM4 )并从端口读取 NMEA 数据并尝试根据 go-nmea 解析数据。包裹
    数据
    来自 GPS 传感器的传入数据:
    $GPRMC,135533.000,A,5306.6644,N,00851.3177,E,0.11,214.59,300620,,,A*6E
    
    $GPRMC,135534.000,A,5306.6643,N,00851.3177,E,0.06,187.72,300620,,,A*68
    
    $GPRMC,135535.000,A,5306.6643,N,00851.3177,E,0.22,341.68,300620,,,A*6C
    
    $GPRMC,135536.000,A,5306.6644,N,00851.3176,E,0.20,324.35,300620,,,A*60
    
    $GPRMC,135537.000,A,5306.6645,N,00851.3176,E,0.12,348.37,300620,,,A*69
    
    代码片段
    package main
    
    import (
        "fmt"
        "log"
    
        "github.com/adrianmo/go-nmea"
        "go.bug.st/serial"
    )
    
    func main() {
    
        mode := &serial.Mode{
            BaudRate: 9600,
            Parity:   serial.NoParity,
            DataBits: 8,
            StopBits: serial.OneStopBit,
        }
        serPort, err := serial.Open("COM4", mode)
        if err != nil {
            log.Fatal(err)
        }
    
        defer serPort.Close()
    
        buff := make([]byte, 1024)
    
        for {
            n, err := serPort.Read(buff)
            if err != nil {
                log.Fatal(err)
                break
            }
            if n == 0 {
                fmt.Println("\nEOF")
                break
            }
            rawSentence := string(buff[:n])
            fmt.Print(rawSentence)
            s, err := nmea.Parse(rawSentence)
            if err != nil {
                log.Fatal(err)
            }
            if s.DataType() == nmea.TypeRMC {
                m := s.(nmea.RMC)
                fmt.Printf("Raw sentence: %v\n", m)
                fmt.Printf("Time: %s\n", m.Time)
                fmt.Printf("Validity: %s\n", m.Validity)
                fmt.Printf("Latitude GPS: %s\n", nmea.FormatGPS(m.Latitude))
                fmt.Printf("Latitude DMS: %s\n", nmea.FormatDMS(m.Latitude))
                fmt.Printf("Longitude GPS: %s\n", nmea.FormatGPS(m.Longitude))
                fmt.Printf("Longitude DMS: %s\n", nmea.FormatDMS(m.Longitude))
                fmt.Printf("Speed: %f\n", m.Speed)
                fmt.Printf("Course: %f\n", m.Course)
                fmt.Printf("Date: %s\n", m.Date)
                fmt.Printf("Variation: %f\n", m.Variation)
            }
        }
    }
    
    
    问题
    如果我运行代码,我会收到以下错误:
    2020/06/30 16:02:16 nmea: sentence does not start with a '$' or '!'
    exit status 1
    
    这很奇怪,因为如果我注释掉代码解析代码:
            // s, err := nmea.Parse(rawSentence)
            // if err != nil {
            //  log.Fatal(err)
            // }
            // if s.DataType() == nmea.TypeRMC {
            //  m := s.(nmea.RMC)
            //  fmt.Printf("Raw sentence: %v\n", m)
            //  fmt.Printf("Time: %s\n", m.Time)
            //  fmt.Printf("Validity: %s\n", m.Validity)
            //  fmt.Printf("Latitude GPS: %s\n", nmea.FormatGPS(m.Latitude))
            //  fmt.Printf("Latitude DMS: %s\n", nmea.FormatDMS(m.Latitude))
            //  fmt.Printf("Longitude GPS: %s\n", nmea.FormatGPS(m.Longitude))
            //  fmt.Printf("Longitude DMS: %s\n", nmea.FormatDMS(m.Longitude))
            //  fmt.Printf("Speed: %f\n", m.Speed)
            //  fmt.Printf("Course: %f\n", m.Course)
            //  fmt.Printf("Date: %s\n", m.Date)
            //  fmt.Printf("Variation: %f\n", m.Variation)
            // }
    
    如上所述,串行端口打印 GPS 坐标。
    我哪里出错了?我尝试通过在代码中执行以下操作来删除换行符和回车符:
            rawSentence := string(buff[:n])
            rawSentence = string.ReplaceAll(rawSentence, "\r\n", "")
            fmt.Print(rawSentence)
    
    但我仍然得到同样的错误。

    最佳答案

    我能够找出问题所在。我首先检查我的字节是如何从以下代码中读取的:

         n, err := serPort.Read(buff)
         fmt.Printf("%d", n)
    
    它依次给出值 173 , 74 .假设 1是设备本身发送的换行符,我发现这可能是代码无法捕获$GPRMC的原因.
    因此我修改了我的代码以检查读取的字节数是否总是大于 1 个字节
        for {
            n, err := serPort.Read(buff)
            fmt.Printf("%v\n", n)
            if err != nil {
                log.Fatal(err)
                break
            }
            // do not try to parse a single read byte
            // instead parse the actual incoming string.
            if n > 1 {
                rawSentence := string(buff[:n])
                fmt.Print(rawSentence)
                s, err := nmea.Parse(rawSentence)
                if err != nil {
                    log.Fatal(err)
                }
                if s.DataType() == nmea.TypeRMC {
                    m := s.(nmea.RMC)
                    fmt.Printf("Raw sentence: %v\n", m)
                    fmt.Printf("Time: %s\n", m.Time)
                    fmt.Printf("Validity: %s\n", m.Validity)
                    fmt.Printf("Latitude GPS: %s\n", nmea.FormatGPS(m.Latitude))
                    fmt.Printf("Latitude DMS: %s\n", nmea.FormatDMS(m.Latitude))
                    fmt.Printf("Longitude GPS: %s\n", nmea.FormatGPS(m.Longitude))
                    fmt.Printf("Longitude DMS: %s\n", nmea.FormatDMS(m.Longitude))
                    fmt.Printf("Speed: %f\n", m.Speed)
                    fmt.Printf("Course: %f\n", m.Course)
                    fmt.Printf("Date: %s\n", m.Date)
                    fmt.Printf("Variation: %f\n", m.Variation)
                }
            }
        }
    
    果然,代码现在可以工作了,导出的输出正是我所期望的:
    $GPRMC,142312.000,A,5306.6774,N,00851.3114,E,0.04,14.48,300620,,,A*5A
    Raw sentence: $GPRMC,142312.000,A,5306.6774,N,00851.3114,E,0.04,14.48,300620,,,A*5A
    Time: 14:23:12.0000
    Validity: A
    Latitude GPS: 5306.6774
    Latitude DMS: 53° 6' 40.644000"
    Longitude GPS: 851.3114
    Longitude DMS: 8° 51' 18.684000"
    Speed: 0.040000
    Course: 14.480000
    Date: 30/06/20
    Variation: 0.000000
    

    关于go - 无法通过串口解析 GPS 信息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62659313/

    相关文章:

    c - UART ISR Tx Rx 架构

    c# - 串行端口重定向或拆分

    android - 如何使用 sencha touch 仅获取 gps 位置?

    c++ - 与 GPS 的串行通信 - 连续数据传输

    go - 如何将文件上传到 S3 Bucket/目录

    go - 如何在同一包中的另一个类中使用一个类?

    performance - Go中的异步TCP服务器的正确结构是什么?

    php - 从邮政编码php获取gps坐标

    react-native - 在没有 GPS 的情况下,使用 navigator.geolocation 在 react-native 上无法获取当前位置

    go - go中的快捷方式分配,不包括空/空值