• Qt实现GPS协议NMEA0183


    要实现GPS的解析和显示经纬度等信息,在硬件上最方便的就是使用一个GPS模块,比如ublox模块,这个厂家的产品基本上算是市场占有率第一的。然后ublox模块可以通过串口或者usb来和SYSZUX PAD(或者其它的什么显示电路)来通信。

          Ublox模块启动后会先发送一些ublox公司相关信息的文本,然后会按照NMEA0183标准协议来传送GPS定位数据,gemfield的Qt端做的就是解析这些数据。一般情况下,ublox模块一秒钟发送一组定位的相关信息,这些信息是文本格式,大致内容如下:
    $GPVTG,18.89,T,,M,1.422,N,2.634,K,A*03
    $GPGGA,070054.00,3958.45919,N,11619.78649,E,1,04,7.29,0.0,M,-8.7,M,,*4D
    $GPGSA,A,2,24,29,05,10,,,,,,,,,7.36,7.29,1.00*05
    $GPGSV,3,1,09,01,06,260,,02,63,098,,04,22,111,,05,74,323,39*7C
    $GPGSV,3,2,09,07,12,062,25,10,68,028,37,24,35,305,35,25,09,044,29*72
    $GPGSV,3,3,09,29,42,299,35*49
    $GPGLL,3958.45919,N,11619.78649,E,070054.00,A,A*62
    $GPRMC,070055.00,A,3958.45914,N,11619.78689,E,1.858,17.98,130110,,,A*54

          上面的每一行称为一个GPS语句,一个完整的语句以$符开始,以换行符结束。其中*符号之后的是校验值,这个值是前面各字符的异或和。我们要实现简单的定位的话,只需要使用上面的一种就可以了。Gemfield选取的是$GPRMC语句,RMC语句是Recommended Minimum data的缩写,意思是推荐的最小定位信息,短小精悍吧。下面来看看这个语句的格式:
    $GPRMC,hhmmss,status,latitude,N,longitude,E,spd,cog,ddmmyy,mv,mvE,mode*cs<CR><LF>

          这个语句包含了如下信息:
    <1> UTC时间,hhmmss(时分秒)格式
    <2> 定位状态,A=有效定位,V=无效定位
    <3> 纬度ddmm.mmmm(度分)格式(前面的0也将被传输)
    <4> 纬度半球N(北半球)或S(南半球)
    <5> 经度dddmm.mmmm(度分)格式(前面的0也将被传输)
    <6> 经度半球E(东经)或W(西经)
    <7> 地面速率(000.0~999.9节,前面的0也将被传输)
    <8> 地面航向(000.0~359.9度,以真北为参考基准,前面的0也将被传输)
    <9> UTC日期,ddmmyy(日月年)格式
    <10> 磁偏角(000.0~180.0度,前面的0也将被传输)
    <11> 磁偏角方向,E(东)或W(西)
    <12> 模式指示(仅NMEA0183 3.00版本输出,A=自主定位,D=差分,E=估算,N=数据无效)
    其它更详细的语句信息参考http://www.civilnet.cn/bbs/browse.php?topicno=3490

          下面开始gemfield的Qt程序设计之旅:

          首先我们还是要使用SYSZUX OS提供的串口类,你也可以使用其它的,只要原理类似就可以了。

    void gemfieldGps::on_serialport_readyRead()

          int n = serialport->bytesAvailable();//可读的字节个数,一看就是QIODevice的后代
          if(n<=0)
            return; //没有收到信息的话就返回,结束当前的方法体
          gemfield_gps+=serialport->read(n);//gemfield_gps是QbyteArray类型,获得当前串口的完整信息
          if(gemfield_gps.contains("$GPRMC"))//我们选取的是RMC语句,所以我们要筛选出来RMC的帧
        {
            gemfield_gps.remove(0,gemfield_gps.indexOf(gemfield_flag));//去掉$GPRMC之前的暂时不用的信息
            if(gemfield_gps.contains("*"))
               {
                  gemfield_rmc=gemfield_gps.left(gemfield_gps.indexOf("*"));//获得除了校验值之外的完整的RMC语句
                  QList<QByteArray> gemfield_list=gemfield_rmc.split(',');//分割提取每个语句段
                  lcdNumber_2->display(gemfield_list[3].toFloat());//显示纬度信息
                  gemfield_gps.clear();//清空gemfield_gps,为下一秒的读取做准备
               }
        }

          上面gemfield并没有采取校验,原因是?呵呵。

          Qt在处理字符串、字节数组方面还是有很多方法可供使用的。现在gemfield的SYSZUX PAD通过串口获得的GPS数据已经能实时显示gemfield的经纬度和时间信息了,所以也可以这么说,gemfield 的SYSZUX PAD 上显示的时间不是当前系统时间,而是美国的GPS授时

    http://www.civilnet.cn/blog/browse.php?operation=display&authorno=1&entryno=367&type=blog

  • 相关阅读:
    sbt commands
    SBT Assembly
    There is no setter for property named 可能产生的原因!
    JSP页面分页显示数据
    CentOS7配置FTP服务器增强版~(零基础学会FTP配置)
    Windows下将程序打包为安装包(最为简易的方式)
    Linux多线程编程详细解析----条件变量 pthread_cond_t
    在Linux中使用线程
    关于verilog中语句可不可综合
    32位先行进位加法器的实现
  • 原文地址:https://www.cnblogs.com/wangzihao/p/1984671.html
Copyright © 2020-2023  润新知