【模块】北斗+GPS双模定位模块

在相当长的时间里,GNSS(全球卫星导航系统, Global Navigation Satellite System)是以美国的GPS(Global Positioning System, 全球定位系统)一家独大的。随着各国对定位系统的逐渐重视,都陆续推出自己的卫星导航系统,比如我国的北斗、俄罗斯的GLONASS还有欧盟的伽利略。

研究并建成一套拥有完全独立自主技术的卫星导航系统是相当不容易的,我国举全国之力为之奋斗了整整26年。今年的7月31号,北斗三号正式开通标志着中国可以摆脱GPS系统的掣肘,真正地走向全球,对中国来说意义非凡。

本篇文章里小编并不想详细的比较北斗和GPS系统之间的差异和优劣,网络上有很多专业的比较,感兴趣的同学可以自行搜索。我们更感兴趣的当然是作为民用级别的定位应用,怎么白嫖最方便和最精确?

比如说你想在自己DIY的项目中加入定位模块,一搜索你会发现市面上大多是多模(双模或者三模)定位模块,很少会有北斗单模系统。原因有以下几个:

  1.  虽然北斗也有民用频段,但普及程度没有GPS广,比如Arduino的北斗示例和资料都比较少。

  2. 其实北斗、GPS、伽利略和GLONASS的民用射频频段几乎是一样,模块厂家只需要一块射频接收器,后端稍作不同的处理就可以支持不同的系统并不需要增加额外的成本,所以厂家更愿意推广多模的模块,比如北斗/BDS和GPS双模。

  3. 民用级别的双模在精度上被证明的确优于单模。最主要的原因就是多一套系统,可用的卫星数就多了。下面三张图就是网友(知乎@侯燕青)实测的对比图(红色为实际轨迹)。

接下去我们就来实际操作一下,如何用Arduino读取北斗+GPS双模定位模块的数据。

我们使用的是型号为ATGM336H-5N模块,这是一款非常小尺寸的、支持全GNSS系统(北斗、GPS、GLONASS、伽利略、日本的QZSS以及卫星增强系统SBAS),ATGM336H-5N模块基于中科微AT6558单芯片,价格也很美丽。

首先把模块的引脚焊接上,并接好陶瓷天线。模块是通过UART跟Arduino交流的,如果对UART协议不了解,请参阅《Arduino常用的三种通信协议UART, I2C和SPI》。按照下图的对应关系,我们连接好模块和Arduino UNO,PPS可不接。

#include <SoftwareSerial.h> SoftwareSerial sSerial(12, 11); //RX,TXvoid setup(){     Serial.begin(115200);  //Debug Serial   sSerial.begin(9600);  //Gps Serial   }
void loop(){  while (sSerial.available() > 0)  {     byte gpsData = sSerial.read();     Serial.write(gpsData);   }}

这里解释一下,因为我们需要创建一个软串口(SoftwareSerial)用于Arduino和模块之间的通信,而默认的硬串口Serial用于串口监视器查看具体的输出数据。

通上电,打开Arduino串口监视器,如果一切正常,你将会看到类似下面的一堆火星文。

这些火星文就是NMEA-0183协议的报文,大多数常见的GNSS接收机、GNSS数据处理软件、导航软件都遵守或者至少兼容这个协议。

数据里面我们看到三种数据类型 GN、GP、BD 分别代表双模模式、GPS 模式、北斗模式。那比如下面这条报文怎么理解呢?

$GNGGA,064954.000,3040.04684,N,10348.56480,E,1,09,1.7,491.2,M,0.0,M,,*71

根据NMEA-0183协议的规定,$XXGGA报文是关于时间、经纬度位置、解算状态、卫星颗数等相关信息。XX的不同代表模式的不同,比如$GPGGA表示单GPS模式,$BDGGA表示单北斗模式,$GNGGA表示多星联合定位。具体的含义我们对应查表就行了:

还有其他的报文都有对应的含义:

$XXGSA 显示的是当前的卫星信息:

$XXGSV 显示的是可见卫星的信息:

每条GSV语句最多可以显示4个可见卫星的信息,其他的卫星都会在下一条语句中输出显示。每种卫星系统都会单独显示,一般GPS有3条GSV报文,北斗有2条GSV报文。

$XXVTG包含地面速度信息:

$XXGLL包含基本的地理定位信息:

$XXRMC包含位置、速度、时间等最简定位信息:

如果我们不想把NMEA-0183协议的报文一股脑儿地输出,我们可以把之Arduino的代码再写复杂一点,把数据解析也做一下再输出:

#include <SoftwareSerial.h>SoftwareSerial sSerial(12, 11);  //RX,TX
struct{  char GPS_Buffer[80];  bool isGetData;    //是否获取到GPS数据  bool isParseData;  //是否解析完成  char UTCTime[11];    //UTC时间  char latitude[11];    //纬度  char N_S[2];    //N/S  char longitude[12];    //经度  char E_W[2];    //E/W  bool isUsefull;    //定位信息是否有效} Save_Data;
const unsigned int gpsRxBufferLength = 600;char gpsRxBuffer[gpsRxBufferLength];unsigned int ii = 0;

void setup()  //初始化内容{  sSerial.begin(9600);      //定义波特率9600  Serial.begin(115200);    Serial.println("I Love Arduino");  Serial.println("Wating...");
  Save_Data.isGetData = false;  Save_Data.isParseData = false;  Save_Data.isUsefull = false;}
void loop()    //主循环{  gpsRead();  //获取GPS数据  parseGpsBuffer();//解析GPS数据  printGpsBuffer();//输出解析后的数据}
void errorLog(int num){  Serial.print("ERROR");  Serial.println(num);  while (1)  {    digitalWrite(13, HIGH);    delay(300);    digitalWrite(13, LOW);    delay(300);  }}
void printGpsBuffer(){  if (Save_Data.isParseData)  {    Save_Data.isParseData = false;        Serial.print("Save_Data.UTCTime = ");    Serial.println(Save_Data.UTCTime);
    if(Save_Data.isUsefull)    {      Save_Data.isUsefull = false;      Serial.print("Save_Data.latitude = ");      Serial.println(Save_Data.latitude);      Serial.print("Save_Data.N_S = ");      Serial.println(Save_Data.N_S);      Serial.print("Save_Data.longitude = ");      Serial.println(Save_Data.longitude);      Serial.print("Save_Data.E_W = ");      Serial.println(Save_Data.E_W);    }    else    {      Serial.println("GPS DATA is not usefull!");    }      }}
void parseGpsBuffer(){  char *subString;  char *subStringNext;  if (Save_Data.isGetData)  {    Save_Data.isGetData = false;    Serial.println("**************");    Serial.println(Save_Data.GPS_Buffer);
        for (int i = 0 ; i <= 6 ; i++)    {      if (i == 0)      {        if ((subString = strstr(Save_Data.GPS_Buffer, ",")) == NULL)          errorLog(1);  //解析错误      }      else      {        subString++;        if ((subStringNext = strstr(subString, ",")) != NULL)        {          char usefullBuffer[2];           switch(i)          {            case 1:memcpy(Save_Data.UTCTime, subString, subStringNext - subString);break;  //获取UTC时间            case 2:memcpy(usefullBuffer, subString, subStringNext - subString);break;  //获取UTC时间            case 3:memcpy(Save_Data.latitude, subString, subStringNext - subString);break;  //获取纬度信息            case 4:memcpy(Save_Data.N_S, subString, subStringNext - subString);break;  //获取N/S            case 5:memcpy(Save_Data.longitude, subString, subStringNext - subString);break;  //获取纬度信息            case 6:memcpy(Save_Data.E_W, subString, subStringNext - subString);break;  //获取E/W
            default:break;          }
          subString = subStringNext;          Save_Data.isParseData = true;          if(usefullBuffer[0] == 'A')            Save_Data.isUsefull = true;          else if(usefullBuffer[0] == 'V')            Save_Data.isUsefull = false;
        }        else        {          errorLog(2);  //解析错误        }      }    }  }}

void gpsRead() {  while (sSerial.available())  {    gpsRxBuffer[ii++] = sSerial.read();    if (ii == gpsRxBufferLength)clrGpsRxBuffer();  }
  char* GPS_BufferHead;  char* GPS_BufferTail;  if ((GPS_BufferHead = strstr(gpsRxBuffer, "$GPRMC,")) != NULL || (GPS_BufferHead = strstr(gpsRxBuffer, "$GNRMC,")) != NULL )  {    if (((GPS_BufferTail = strstr(GPS_BufferHead, "\r\n")) != NULL) && (GPS_BufferTail > GPS_BufferHead))    {      memcpy(Save_Data.GPS_Buffer, GPS_BufferHead, GPS_BufferTail - GPS_BufferHead);      Save_Data.isGetData = true;
      clrGpsRxBuffer();    }  }}
void clrGpsRxBuffer(void){  memset(gpsRxBuffer, 0, gpsRxBufferLength);      //清空  ii = 0;}

这样编译上传后,我们就可以看见解析后的地理信息。是不是更加直观了?

这样我们就可以用双模定位模块获取更加精确定位数据,然后我们可以把这些数据再喂给一些GIS(地理信息系统)软件,或者可以利用python的一些库自己可视化数据。

在硬件方面,我们也可以增加电池和SD模块,让它长时间的保存定位信息,还可以添加GSM模块把数据通过移动网络传回服务器,这里我们就不深入了。

  • 38
    点赞
  • 346
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
北斗GPS双模定位ATGM336H是一款集成了北斗GPS定位功能的定位模块,其用户手册为用户提供了详细的使用指南和技术参数。以下是针对该用户手册的回答: 北斗GPS双模定位ATGM336H用户手册是一本专门针对该模块的使用者而编写的指南。手册首先介绍了该模块的基本特点和技术参数,包括工作频率、定位精度、灵敏度等详细信息,帮助用户更好地了解该模块的性能和功能。 手册还提供了该模块的外部接口和引脚定义,以及电气特性和通信协议等方面的介绍。用户可以通过这些内容,了解该模块如何与其他设备或系统进行连接和通信,以便在实际应用中更好地结合该模块。 用户手册还包含了该模块的使用说明,详细介绍了如何进行模块的电源接入、信号接收等基本操作,以及提供了一些常见问题的解答和故障排除指南,帮助用户在使用中遇到问题时能够及时解决。 此外,用户手册还给出了该模块的典型应用场景和案例,帮助用户更好地理解和把握该模块的优势和适用性。手册中还提供了一些开发环境和软件工具的介绍,帮助用户在使用该模块进行应用开发时能够更加高效和便捷。 总之,北斗GPS双模定位ATGM336H用户手册是一本详细的使用指南,为用户提供了全面的技术资料和操作指导,帮助用户更好地理解和使用该模块,实现定位功能的应用。用户通过仔细阅读和按照手册的指导操作,能够更好地发挥该模块的性能和功能,满足自己的需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值