使用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. ...
随机推荐
- webpack-vue搭建,部署到后端
1.安装npm(安装node自带npm),npm安装成功测试 2.安装cnpm,也可以装nvm-windows 步骤1,打开user/admin/.npmrc,输入,也可以用命令 步骤2,输入npm ...
- 循环语句--for
1.guess_age优化版v1.py #coding=utf-8 age = 22 for i in range(10): if i < 3: guess_num = int(input('i ...
- NLog学习
一.什么是NLog? NLog((http://www.nlog-project.org)是一个基于.NET平台编写的类库,我们可以使用NLog在应用程序中添加极为完善的跟踪调试代码. NLog允许我 ...
- MVC中关于Membership类跟数据库的问题
Membership它们用的是ASPNETDB这个数据库,但我们可以使用我们自定义的数据库,然而除非我们自定义的数据库有着跟这个ASPNETDB一样的模式,否则ASP.NET提供的默认的SqlMemb ...
- Microsoft JScript 运行时错误: '$' 未定义
在运行MVC Music Store时Visual Studio 捕捉到此错误: Microsoft JScript 运行时错误: '$' 未定义 可能是引用的Scripts 引用出错,检查当前文件中 ...
- git服务器新增仓库
在已有的git库中搭建新的库,并将本地的git仓库,上传到服务器的git库中,从而开始一个新的项目. 首先是在本地操作: 在本地新建文件夹spider,进入到spider中:如下
- 从高处理解android与服务器交互(看懂了做开发就会非常的容易)
今天帮一个朋友改一个bug 他可以算是初学者吧 .我给他看了看代码,从代码和跟他聊天能明显的发现他对客户端与服务器交互 基本 不是很了解.所以我花了更多时间去给他讲客户端与服务器的关系.我觉得从这个高 ...
- windows下CMake使用图文手册 Part 1
维基百科介绍“CMake是个开源的跨平台自动化建构系统,它用配置文件控制建构过程(build process)的方式和Unix的Make相似,只是CMake的配置文件取名为CMakeLists.txt ...
- CuteSTL——跟着感觉造轮子
置顶推荐: CuteSTL:https://github.com/jxd134/algorithm/tree/master/CuteSTL TinySTL:https://github.com/zou ...
- Strint类成员
String& String::operator=(const string& other){ if(this == &other) { return *this; } de ...