【物联网智能网关-06】GPS定位+星图显示(WinForm库应用实例)

简介:

 在2008上半年就曾经深入研究过GPS,当时还以为已经相对全面的了解GPS呢,现在重新拾起去研究GPS技术,发现还是差了一大截。最初以为GPS是单向通信,GPS模块按照固定的时间间隔发送文本格式的GPS数据。现在才知道GPS不仅可以双向通信,还可以以二进制格式收发数据,并且可以配置需要发送数据的种类和发送间隔,当然必要的时候,还可以用专门的工具,更新GPS模块的固件。

最初了解GPS,是基于WINCE平台,为写一本书而做,详情请参见《实战Windows Embedded CE 6.0—GPS篇》和《我的第一个WINCE驱动》。后来为了便于调试,又把程序移植到Windows Mobile手机上(采用.NET精简框架集的Winform完成,本篇.NET MF界面代码就是基于原先的这套代码,稍作改进而来,而底层接收代码,添加了校验和更全的GPS命令解析),相关博文请参见《GPS NMEA0183协议解析》。 

现在重新研究GPS,是为物联网网关系统封装一个GPS库,最初的时候,购买了几个低价二手的GPS模块,但是却无法定位,在阳台附近无法定位也就算了,但是我直接到空旷的大操场也无法定位,并且没有一个星的信号。所以后来只好又购买一个价钱较高,带有源天线的GPS模块。

这个带外接天线的模块果然不错,信号强度蛮强,但是我在购买的时候犯了一个错误,选型的时候,选择了“4800bps GPRMC数据包输出,不带PPS”,所以就只能输出$GPRMC基本信息了,但是这样星图就无法显示了。

由于技术支持不在线,所以只好先自己想办法解决这个问题了。我想应该有两种思路可以解决这个问题,一是更新固件。但是这种方法显然需要技术支持来提供相应固件,如果自己找相关工具和固件进行烧写,难免会出问题(后来问了技术支持才知道,还得飞一个线,进入烧写模式才行);二是配置信息输出。这种方法最方便,问题是,掉电配置就丢失了,但是这个GPS板子带纽扣电池,所以问题不大。

有了第二种思路,然后网上就进行搜索,果然功夫不负有心人,搜到了如下信息:

    NMEA信息输出控制

$PSRF103,00,01,00,01*25<CR><LF>

格式说明(Set Serial Port Data Format):

Name

Example

Unit

Description

Message ID

$PSRF103

 

PSRF103 protocol header

Msg

00

 

0:GGA

1:GLL

2:GSA

3:GSV

4:RMC

5:VTG

6:MSS (If internal beacon is supported)

7:Not defined

8:ZDA (if 1PPS output is supprttd)

9:Not defined

Mod

01

 

0 = Set Rate

1 = Query one time

2 = ABP On

3 = ABP Off

Rate

00

 

Output Rate:

0 = Off

1–255 = seconds between messages

CksumEnable

01

 

0=Disable Checksum

1=Enable Checksum

Checksum

*25

 

 

<CR><LF>

 

 

End of message termination

示例

关闭GGA:

$PSRF103,00,00,01,01*25

设置GGA为5秒输出一次:

$PSRF103,00,00,05,01*21

 

关闭GSA:

$PSRF103,02,00,00,01*26

设置GSA为5秒输出一次:

$PSRF103,02,00,05,01*23

         但是由于NMEA有校验,所以还需要一个专门的工具来设置才行,所以又找到了SiRFLive软件,这个软件很不错,可以方便的调试GPS模块。也许是供电的问题,我这次在阳台测试我原先的GPS模块,居然可以定位成功了。下图便是该GPS模块使用SiRFLive软件进行测试的效果图。

 

如果需要配置GPS,直接进入命令发送窗口即可,记得选择NMEA协议。 

修改了相关配置,新购买的GPS果然可以输出星图信息了,在物联网智能网关上的运行效果图如下: 

 

GPS库相关内容我这里就不细说了,文档里面有详细的说明。我这里说一下,在.NET Micro Framework平台,如何进行Winform界面开发(WinForm for .NET MF 功能一览)。

本实例程序,GPS相关函数一旦执行,会自动把GPS模块的相关参数赋值到GPS类的相关属性中去。界面绘图我们采用重载Form类的OnPaint方法,为了避免闪烁,我们还采用了在Windows编程中常见的技巧,就是重载OnPaintBackground方法,不去绘制背景。

   

      protected override void OnPaint(PaintEventArgs e)      {          try          {              e.Graphics.Clear(Color.Gray);    //绘制背景              //--------------------------              //绘制信噪比图
             DrawSNR(e.Graphics, new Rectangle(2, 240 - 80, 320 - 4, 80));              //绘制星图
             DrawSatellite(e.Graphics, new Rectangle(10, 60, 100, 100));                 //状态
             e.Graphics.DrawString("状态:" + (GPS.Online ? "已连接 " : "未连接 ") + (GPS.Manage.AnchorState == "A" ? "已定位" : "未定位"), font, sb, 5, 8);                 //坐标
             e.Graphics.DrawString("坐标:" + GPS.Manage.ToString("D"), font, sb, 5, 25);              //pb_Graphics.DrawString("坐标:" + GPS.Manage.Latitude.ToString() + " " + NMEA.GPS.Longitude.ToString(), font, new SolidBrush(Color.White), 5, 25);                 //时间
             e.Graphics.DrawString("时间:" + GPS.Manage.UTCDateTime.ToString(), font, sb, 150, 25);              //-------------------------------              //卫星数
             e.Graphics.DrawString("卫星:" + GPS.Manage.SatelliteNum.ToString() + "", font, sb, 130, 60);              //定位状态 0=未定位,1=GPS单点定位固定解,2=差分定位,3=无效PPS,4=RTK固定解,5=RTK浮点解,6=估计值,7=手工输入模式,8=模拟模式
             e.Graphics.DrawString("状态:" + strState[GPS.Manage.AnchorSStateEx], font, sb, 130, 75);              //获取定位模式(A=自动,M=手动)。
             e.Graphics.DrawString("模式:" + (GPS.Manage.AnchorMode == "A" ? "自动" : "手动"), font, sb, 130, 90);              //定位类型(1=未定位,2=2D定位,3=3D定位)
             e.Graphics.DrawString("类型:" + strType[GPS.Manage.AnchorType], font, sb, 130, 105);              //海拔
             e.Graphics.DrawString("海拔:" + GPS.Manage.Altitude.ToString("F2") + "(" + GPS.Manage.Height.ToString("F2") + ")", font, sb, 130, 120);              //速度
             e.Graphics.DrawString("速度:" + GPS.Manage.KSpeed.ToString("F2"), font, sb, 130, 135);              //方向
             e.Graphics.DrawString("方向:" + GPS.Manage.Track.ToString("F2"), font, sb, 130, 150);              //信息
             Microsoft.SPOT.Debug.Print(GPS.ErrorMessage);          }          catch { }      }

 

具体绘制绘制信噪比图的代码如下:

  

  private void DrawSNR(Graphics e, Rectangle rect)      {          Font font = new Font("Arial", 9, FontStyle.Regular);          int FontHeight = 20;          int SNRHeight = rect.Height - FontHeight;          int SNRWidth = (rect.Width - FontHeight / 2) / 12;             //绘制信噪比图
         e.DrawLine(new Pen(Color.Gray), rect.Left, rect.Top, rect.Right, rect.Top);          e.DrawLine(new Pen(Color.Gray), rect.Left, rect.Top + SNRHeight / 2, rect.Right, rect.Top + SNRHeight / 2);          e.DrawLine(new Pen(Color.Gray), rect.Left, rect.Top + SNRHeight, rect.Right, rect.Top + SNRHeight);             for (int i = 0; i < 12; i++)          {              string strPRN = GPS.Manage.Satellite[i].PRN.ToString();              if (strPRN.Length == 1) strPRN = "0" + strPRN;              int Height = (int)(GPS.Manage.Satellite[i].SNR * SNRHeight / 100);              int font_h, font_w;              font.Value.ComputeExtent(strPRN, out font_w, out font_h);                 //星号
             e.DrawString(strPRN, font, new SolidBrush(Color.White), (int)(rect.Left + FontHeight / 4 + SNRWidth * i), (int)(rect.Top + SNRHeight + 4));                 //信噪比
             e.FillRectangle(new SolidBrush(Color.Blue), new Rectangle(rect.Left + FontHeight / 4 + SNRWidth * i, rect.Top + SNRHeight - Height, font_w, Height));          }      }

绘制星图的代码如下:

private void DrawSatellite(Graphics e, Rectangle rect)      {          Font font = new Font("Arial", 9, FontStyle.Regular);             int X = rect.Left + rect.Width / 2;          int Y = rect.Top + rect.Height / 2;          int Size = (rect.Width > rect.Height ? rect.Height : rect.Width);          int R = (Size - 12 * 2) / 6;          int r = 8;             e.DrawLine(new Pen(Color.Red), X - R * 3 - 12, Y, X + R * 3 + 12, Y);          e.DrawLine(new Pen(Color.Red), X, Y - R * 3 - 12, X, Y + R * 3 + 12);             e.DrawEllipse(new Pen(Color.Blue), new Rectangle(X - R, Y - R, R * 2, R * 2));          e.DrawEllipse(new Pen(Color.Blue), new Rectangle(X - R * 2, Y - R * 2, R * 4, R * 4));          e.DrawEllipse(new Pen(Color.Blue), new Rectangle(X - R * 3, Y - R * 3, R * 6, R * 6));          e.DrawString("N", font, new SolidBrush(Color.White), X + 2, Y - R * 3 - 10);          e.DrawString("S", font, new SolidBrush(Color.White), X + 2, Y + R * 3 + 2);          e.DrawString("W", font, new SolidBrush(Color.White), X - R * 3 - 10, Y + 2);          e.DrawString("E", font, new SolidBrush(Color.White), X + R * 3 + 2, Y + 2);             //绘制卫星位置

        int X0 = 0, Y0 = 0, L = 0;          double A1 = 0, A2 = 0;          StringFormat sFormat = new StringFormat();          sFormat.Alignment = StringAlignment.Center;          sFormat.LineAlignment = StringAlignment.Center;             for (int i = 0; i < 12; i++)          {              if (GPS.Manage.Satellite[i].PRN > 0)              {                  A1 = GPS.Manage.Satellite[i].Elevation * Math.PI / 180;                  A2 = GPS.Manage.Satellite[i].Azimuth * Math.PI / 180;                  L = (int)(Math.Cos(A1) * 3 * R);                  X0 = X + (int)(Math.Cos(Math.PI * 5 / 2 - A2) * L);                  Y0 = Y - (int)(Math.Sin(Math.PI * 5 / 2 - A2) * L);                  e.FillEllipse(new SolidBrush(Color.Blue), new Rectangle(X0 - r, Y0 - r, 2 * r, 2 * r));                  e.DrawString(GPS.Manage.Satellite[i].PRN.ToString(), font, new SolidBrush(Color.White), new Rectangle(X0 - r * 2, Y0 - r * 2, 4 * r, 4 * r), sFormat);              }          }      }

从以上代码可以看出,在.NET Micro Framework系统中开发WinForm程序,和上位机没有什么区别,上面的代码也基本上也可以在windows桌面.Net程序中直接可以使用。

  

下载地址:http://www.sky-walker.com.cn/MFRelease/library/V42/YFSoft.Hardware.GPS.rar

MF简介:http://blog.csdn.net/yefanqiu/article/details/5711770

MF资料:http://www.sky-walker.com.cn/News.asp?Id=25

 





本文转自yefanqiu51CTO博客,原文链接:http://blog.51cto.com/yfsoft/939408,如需转载请自行联系原作者

相关实践学习
钉钉群中如何接收IoT温控器数据告警通知
本实验主要介绍如何将温控器设备以MQTT协议接入IoT物联网平台,通过云产品流转到函数计算FC,调用钉钉群机器人API,实时推送温湿度消息到钉钉群。
阿里云AIoT物联网开发实战
本课程将由物联网专家带你熟悉阿里云AIoT物联网领域全套云产品,7天轻松搭建基于Arduino的端到端物联网场景应用。 开始学习前,请先开通下方两个云产品,让学习更流畅: IoT物联网平台:https://iot.console.aliyun.com/ LinkWAN物联网络管理平台:https://linkwan.console.aliyun.com/service-open
相关文章
|
1月前
|
网络协议
【开源视频联动物联网平台】J2mod库对指令码的定义
【开源视频联动物联网平台】J2mod库对指令码的定义
32 1
|
1月前
|
Java Maven
【开源视频联动物联网平台】J2mod库写一个Modbus RTU 服务器
【开源视频联动物联网平台】J2mod库写一个Modbus RTU 服务器
61 0
|
1月前
|
存储 监控 安全
Java基于物联网技术的智慧工地云管理平台源码 依托丰富的设备接口标准库,快速接入工地现场各类型设备
围绕施工安全、质量管理主线,通过物联感知设备全周期、全覆盖实时监测,将管理动作前置,实现从事后被动补救到事前主动预防的转变。例如塔吊运行监测,超重预警,升降机、高支模等机械设备危险监控等,通过安全关键指标设定,全面掌握现场安全情况,防患于未然。
147 5
|
1月前
|
Java API Maven
【开源视频联动物联网平台】JAIN-SIP库写一个SIP服务器
【开源视频联动物联网平台】JAIN-SIP库写一个SIP服务器
66 0
|
7月前
|
传感器 安全 物联网
一个非常优秀的跨平台物联网开发常用的网络请求库libcurl
一个非常优秀的跨平台物联网开发常用的网络请求库libcurl
175 1
|
人工智能 JavaScript 前端开发
面向 JavaScript 开发人员的 5 大物联网库
最近元宇宙的概念火遍互联网,自 Facebook 改名 Meta 以来,国内外越来越多的企业纷纷加入到布局元宇宙的行列。元宇宙之所以强势进入人们视野,与其底层技术的进步有着莫大的关系,包括AR/VR、云计算、物联网、5G、人工智能、数字孪生等等。其中,5G作为重要的连接基础,是元宇宙场景得以实现的关键。元宇宙将汇集游戏引擎、AR可穿戴设备、VR、现实世界数据集和不断发展的物联网。
198 0
|
C# 图形学 芯片
【物联网智能网关-04】WinForm for .NET MF 功能一览
 .Net Micro Framework界面开发官方标准功能仅支持WPF方式,并且所谓的WPF开发和Windows平台上的WPF有很大的区别,即不支持可视化界面设计,也不支持XML方式界面格式定义,另外提供的控件也很少,又不含事件处理,所以使用上相对繁琐,需要自己写很多额外代码。
844 0
|
定位技术 Windows
【物联网智能网关-06】GPS定位+星图显示(WinForm库应用实例)
GPS不仅可以双向通信,还可以以二进制格式收发数据,并且可以配置需要发送数据的种类和发送间隔,当然必要的时候,还可以用专门的工具,更新GPS模块的固件。
1084 0
【物联网智能网关-15】WAV播放器(WinForm+WavPlay库实例)
由于.NET Micro Framework已经支持了DA输出功能,而STM32芯片时钟中断功能也比较强大,所以就尝试做WAV解码。没有想到实际做出的效果竟然非常好,特别是用外接音箱播放的时候,几乎可以媲美一些播放器的音质。
809 0
|
27天前
|
存储 安全 物联网
未来技术纵横谈:区块链、物联网和虚拟现实的革新之路
在科技不断进步的今天,新兴技术正以前所未有的速度改变着我们的生活和工作方式。本文将深入探讨区块链、物联网(IoT)以及虚拟现实(VR)这三项技术的发展趋势与潜在应用场景,揭示它们如何塑造一个更加智能、互联和沉浸式的未来世界。通过对这些技术的综合分析,我们旨在提供一个全面的视角,以理解它们在未来社会结构中的重要性及影响。
24 7

相关产品

  • 物联网平台