使用SerialPort 读取外置GPS信息和使用GeoCoordinateWatcher获取内置gps的信息
- 简介
最近工作中需要读取gps设备的信息,平板本身有内置的gps设备,但是精度不够,就又添加了一个外置的gps。
对于外置的gps,我们主要通过SerialPort类来获得串口的信息,然后对接收到的内容进行解析处理,
对于内置的gps,我们可以通过GeoCoordinateWatcher类来方便的获取gps数据。 - 使用 SerialPort 设置串口属性
进行串口通讯时,需要设置一些相关参数,可以通过设置SerialPort 类的属性来进行。串口属性主要包括
.PortName 串口名称,COM1, COM2等。
.BaudRate 波特率,也就是串口通讯的速度,进行串口通讯的双方其波特率需要相同,如果用PC连接其他非PC系统,一般地,波特率由非PC系统决定。
.ReadTimeout超时时间。
.Parity 奇偶校验。可以选取枚举Parity中的值
.DataBits 数据位
.StopBits 停止位,可以选取枚举StopBits中的值
.Handshake 握手方式,也就是数据流控制方式,可以选取枚举Handshake中的值 - 事件DataReceived
SerialPort 提供了DataReceived事件。当有数据进入时,该事件被触发。该事件的触发由操作系统决定,当有数据到达时,该事件在辅助线程中被触发。辅助线程的优先级比较低,因此并不能确保每个字节的数据到达时,该事件都被触发。
在使用该事件接收数据时,最好对定义通讯协议格式,添加桢头和桢尾。在DataReceived事件中接收数据时,把数据放在数组中或字符串中缓冲起来,当接收的包含桢头和桢尾的完整数据时,再进行处理。 - 解析Gps信息
public class UsbNmeaGpsHelper : IGpsHelper { private SerialPort serialPort = null; private Object lockOjb2 = new object(); private string currentPortName = ""; private int currentReadTimeout = 2000; private int currentBaudRate = 4800; private double latitude = 0; /// <summary> /// 最新纬度 /// </summary> public double Latitude { get { return latitude; } } private double longitude = 0; /// <summary> /// 最新经度 /// </summary> public double Longitude { get { return longitude; } } private GeoPositionDeviceStatus lastGeoPositionStatus = GeoPositionDeviceStatus.NoData; /// <summary> /// gps最新状态 /// </summary> public GeoPositionDeviceStatus LastGeoPositionStatus { get { return lastGeoPositionStatus; } } private DateTime lastTimestamp = DateTime.Now; /// <summary> /// 数据时间 /// </summary> public DateTime LastTimestamp { get { return lastTimestamp; } } public UsbNmeaGpsHelper(string portName, int baudRate, int readTimeout) { currentPortName = portName; currentBaudRate = baudRate; currentReadTimeout = readTimeout; } public UsbNmeaGpsHelper(string portName) : this(portName, 4800, 2000) { } /// <summary> /// 打开端口,开始监测 /// </summary> public void Start() { if (serialPort == null) { lock (lockOjb2) { serialPort = new SerialPort(); /// 名称不能错 serialPort.PortName = currentPortName; /// 需要设置超时,要不会阻塞 serialPort.ReadTimeout = currentReadTimeout; /// 波特率不能错,要不读不到数据 serialPort.BaudRate = currentBaudRate; /// 获取数据 serialPort.DataReceived += serialPort_DataReceived; /// 打开端口 serialPort.Open(); } } else { if (serialPort.IsOpen) { serialPort.Close(); } serialPort.Open(); } } void serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e) { try { String txt = serialPort.ReadLine(); HandleMsg(txt); } catch (Exception exp) { System.Diagnostics.Trace.WriteLine(exp.Message); } } /// <summary> /// gps数据解析,只获取需要的数据 /// 当前设备的频率为1秒一次 /// </summary> /// <param name="msg"></param> private void HandleMsg(string msg) { /// 根据GPGGA取出全部信息 if (msg.StartsWith("$GPRMC") && msg[msg.Length - 4] == '*') { String[] infos = msg.Split(','); if (infos.Length == 13 || infos.Length == 12) { ///ddmmyy(日月年)hhmmss.sss(时分秒.毫秒) string timeText = infos[9] + infos[1]; DateTime utcDt = DateTime.UtcNow; try { DateTime? parseDt = DateTimeHelper.ParseDateTime(timeText, "ddMMyyHHmmss.fff"); if (parseDt.HasValue) { utcDt = parseDt.Value; } } catch (Exception ex) { System.Diagnostics.Trace.WriteLine(msg + Environment.CommandLine + ex.ToString()); } utcDt = utcDt.ToLocalTime(); lastTimestamp = utcDt; string GPSStateText = infos[2]; if (GPSStateText == "A") { lastGeoPositionStatus = GeoPositionDeviceStatus.Ready; } else { lastGeoPositionStatus = GeoPositionDeviceStatus.NoData; } string latText = infos[3]; latitude = ConvertToJWD(latText, 2); string latNSText = infos[4]; string lonText = infos[5]; longitude = ConvertToJWD(lonText, 3); string lonEWText = infos[6]; string velocityText = infos[7]; string northAngleText = infos[8]; } } } /// <summary> /// 经纬度转化 /// </summary> /// <param name="value"></param> /// <param name="index"></param> /// <returns></returns> private double ConvertToJWD(String value, Int32 index) { try { Int32 du = DbObjectConverter.ToInt(value.Substring(0, index)); Double fen = Math.Round(DbObjectConverter.ToDouble(value.Substring(index)) / 60, 8); return du + fen; } catch { return 0; } } /// <summary> /// 关闭端口 /// </summary> public void Stop() { if (serialPort != null) { serialPort.Close(); } } }
public class GpsBuildinWatcherHelper : IGpsHelper { private GeoCoordinateWatcher geoCoordinateWatcher; private Object lockOjb2 = new object(); private double latitude = 0; public double Latitude { get { return latitude; } } private double longitude = 0; public double Longitude { get { return longitude; } } private GeoPositionDeviceStatus lastGeoPositionStatus = GeoPositionDeviceStatus.NoData; public GeoPositionDeviceStatus LastGeoPositionStatus { get { return lastGeoPositionStatus; } } private DateTime lastTimestamp = DateTime.Now; public DateTime LastTimestamp { get { return lastTimestamp; } } //检测到位置更改时 //当定位服务已准备就绪并接收数据时,它将开始引发 PositionChanged 事件 public void watcher_PositionChanged(object sender, GeoPositionChangedEventArgs<GeoCoordinate> e) { latitude = e.Position.Location.Latitude; longitude = e.Position.Location.Longitude; lastTimestamp = e.Position.Timestamp.LocalDateTime; } //当位置服务状态发生变化时 //在 GeoPositionStatusChangedEventArgs 对象中传递的 GeoPositionStatus 枚举获取该服务的当前状态。 //可以使用它在应用程序中启用基于位置的功能,以及将服务的当前状态通知给用户。 public void watcher_StatusChanged(object sender, GeoPositionStatusChangedEventArgs e) { switch (e.Status) { //如果服务的状态为 Disabled,则可以检查 Permission 属性,看用户是否禁用了应用程序的定位服务功能。 case GeoPositionStatus.Disabled: if (geoCoordinateWatcher.Permission == GeoPositionPermission.Denied) { lastGeoPositionStatus = GeoPositionDeviceStatus.Denied; } else { lastGeoPositionStatus = GeoPositionDeviceStatus.Disabled; } break; case GeoPositionStatus.Initializing: // 位置服务正在尝试获取数据 lastGeoPositionStatus = GeoPositionDeviceStatus.Initializing; break; case GeoPositionStatus.NoData: lastGeoPositionStatus = GeoPositionDeviceStatus.NoData; break; case GeoPositionStatus.Ready: lastGeoPositionStatus = GeoPositionDeviceStatus.Ready; break; } } public GpsBuildinWatcherHelper(GeoPositionAccuracy desiredAccuracy, double movementThreshold) { currentDesiredAccuracy = desiredAccuracy; currentMovementThreshold = movementThreshold; } public GpsBuildinWatcherHelper() : this(GeoPositionAccuracy.High, 5) { } private GeoPositionAccuracy currentDesiredAccuracy = GeoPositionAccuracy.Default; private double currentMovementThreshold = 0; public void Start() { if (geoCoordinateWatcher == null) { lock (lockOjb2) { geoCoordinateWatcher = new GeoCoordinateWatcher(currentDesiredAccuracy); // 采用高精度 geoCoordinateWatcher.MovementThreshold = currentMovementThreshold; // PositionChanged事件之间传送的最小距离 geoCoordinateWatcher.StatusChanged += new EventHandler<GeoPositionStatusChangedEventArgs>(watcher_StatusChanged); geoCoordinateWatcher.PositionChanged += new EventHandler<GeoPositionChangedEventArgs<GeoCoordinate>>(watcher_PositionChanged); geoCoordinateWatcher.Start();//开始使用位置服务 } } else//方便测试,实际使用需要注意 { geoCoordinateWatcher.Start();//开始使用位置服务 } } public void Stop() { if (geoCoordinateWatcher != null) { lock (lockOjb2) { geoCoordinateWatcher.PositionChanged -= new EventHandler<GeoPositionChangedEventArgs<GeoCoordinate>>(watcher_PositionChanged); geoCoordinateWatcher.Stop(); geoCoordinateWatcher.StatusChanged -= new EventHandler<GeoPositionStatusChangedEventArgs>(watcher_StatusChanged); geoCoordinateWatcher.Dispose(); geoCoordinateWatcher = null; } } } }
使用SerialPort 读取外置GPS信息和使用GeoCoordinateWatcher获取内置gps的信息的更多相关文章
- Android获取内置sdcard跟外置sdcard路径
Android获取内置sdcard跟外置sdcard路径.(测试过两个手机,亲测可用) 1.先得到外置sdcard路径,这个接口是系统提供的标准接口. 2.得到上一级文件夹目录 3.得到该目录的所有文 ...
- android获取内置和外置SD卡路径 - z
本文将介绍Android真机环境下如何获取内置和外置SD卡路径. 测试环境:三星Note3,其他手机待测试... 所需权限(AndroidManifest.xml文件里) <uses-permi ...
- linux 获取shell内置命令帮助信息 help xx
shell,命令解释器 shell内置命令有cd/umask/pwd等 help shell内置命令适用于所有用户获取shell内置命令的帮助信息help umaskhelp if
- Inxi:获取Linux系统和硬件信息的神器
导读 在这篇文章里,我们将看到如何使用inxi来获取这些详情信息.在论坛技术支持中,它可以作为调试工具,迅速确定用户的系统配置和硬件信息. Inxi是一个可以获取完整的系统和硬件详情信息的命令行工具, ...
- Android开发获取多个存储空间的路径(内置SD卡以及外置SD卡)
Android开发中经常会遇到多存储空间的问题,包括内置存储路径以及外置SD卡,而且有的时候会有多张外置SD卡,此时就需要获取不同的SD卡路径,然后根据需要来写入或者读出文件. 此处给出常用的SD卡工 ...
- 如何通过SerialPort读取和写入设备COM端口数据
SerialPort类用于控制串行端口文件资源.提供同步 I/O 和事件驱动的 I/O.对管脚和中断状态的访问以及对串行驱动程序属性的访问.另外,SerialPort的功能可以包装在内部 Stream ...
- 实战项目——获取图片中的GPS位置信息和拍摄时间
今天突然看到有人写过获取图片中位置信息的程序.我觉得很有趣,也就自己实践了一下,研究了一下 话不多说,先上代码 #!/usr/bin/env python3 # -*- coding: utf-8 - ...
- MTK Android 读取SIM卡参数,获取sim卡运营商信息
android 获取sim卡运营商信息(转) TelephonyManager tm = (TelephonyManager)Context.getSystemService(Context.TE ...
- Win CE 6.0 获取手持机GPS定位2----示例代码 (C#)
一.须知 1.手持机(PDA)必须有GPS模块,才能通过代码使用串口通信获取GPS相关信息 2.要清楚自己手持机(PDA)固定的GPS通信串口号,如我们公司的手持机获取GPS信息的串口为COM4 3. ...
随机推荐
- 使用nvm安装node
安装nvm curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.32.1/install.sh | bash 安装node nvm ...
- npm镜像
npm config set registry https://registry.npm.taobao.org // 配置后可通过下面方式来验证是否成功 npm config get registry ...
- [系统集成] 部署 mesos-exporter 和 prometheus 监控 mesos task
前几天我在mesos平台上基于 cadvisor部署了 influxdb 和 grafana,用于监控 mesos 以及 docker app 运行信息,发现这套监控系统不太适合 mesos + do ...
- 消息摘要算法-MAC算法系列
一.简述 mac(Message Authentication Code,消息认证码算法)是含有密钥散列函数算法,兼容了MD和SHA算法的特性,并在此基础上加上了密钥.因此MAC算法也经常被称作HMA ...
- cf Canada cup A题
A. Jumping Ball time limit per test 2 seconds memory limit per test 256 megabytes input standard inp ...
- POJ 3468 A Simple Problem with Integers(线段树 成段增减+区间求和)
A Simple Problem with Integers [题目链接]A Simple Problem with Integers [题目类型]线段树 成段增减+区间求和 &题解: 线段树 ...
- MVC 访问IFrame页面Session过期后跳转到登录页面
Web端开发时,用户登录后往往会通过Session来保存用户信息,Session存放在服务器,当用户长时间不操作的时候,我们会希望服务器保存的Session过期,这个时候,因为Session中的用户信 ...
- IIS发布问题汇总
1.未能加载文件或程序集“System.Data.SQLite” 在IIS界面选择应用程序池->选择所使用的.net 版本->高级设置->将"使用32位应用程序" ...
- mac 设置 git 和github 告别命令行
针对和我一样的新手,大虾们请轻拍. 很多小伙伴都想用git管理自己的代码,或者想在github上上传自己的项目.在网上找了几篇这方面的文章,都是用命令行设置的. 用命令行管理和安装太坑爹,这里有一个简 ...
- day9-协程
生产者和消费者模型: #!/usr/bin/env python #coding:utf8 import threading,Queue import time import random def p ...