forked from nanoframework/nanoFramework.IoT.Device
-
Notifications
You must be signed in to change notification settings - Fork 0
/
GenericSerialGnssDevice.cs
149 lines (132 loc) · 4.54 KB
/
GenericSerialGnssDevice.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System;
using System.IO.Ports;
using System.Text;
using UnitsNet;
namespace Iot.Device.Common.GnssDevice
{
/// <summary>
/// Implementation of a generic serial GNSS device.
/// </summary>
public class GenericSerialGnssDevice : GnssDevice, IDisposable
{
private readonly bool _shouldDispose;
private SerialPort _serialPort;
private bool _isrunning = false;
/// <summary>
/// Initializes a new instance of the <see cref="GenericSerialGnssDevice"/> class.
/// </summary>
/// <param name="serialPort">A valid <see cref="SerialPort"/>. Note that you are responsible to set a watch char `\n` and provide the proper port configurations.</param>
/// <param name="shouldDispose">True to dispose the serial port.</param>
public GenericSerialGnssDevice(SerialPort serialPort, bool shouldDispose = true)
{
_serialPort = serialPort;
_shouldDispose = shouldDispose;
}
/// <summary>
/// Initializes a new instance of the <see cref="GenericSerialGnssDevice"/> class.
/// </summary>
/// <param name="portName">Serial port name.</param>
/// <param name="baudRate">Baud rate, default to 9600.</param>
/// <param name="parity">Parity, default to <see cref="Parity.None"/>.</param>
/// <param name="dataBits">Data bits, default to 8.</param>
/// <param name="stopBits">Stop bits, default to One.</param>
public GenericSerialGnssDevice(string portName, int baudRate = 9600, Parity parity = Parity.None, int dataBits = 8, StopBits stopBits = StopBits.One)
{
_serialPort = new SerialPort(portName, baudRate, parity, dataBits, stopBits);
_serialPort.ReadBufferSize = 2048;
_serialPort.ReadTimeout = 2000;
#if NANOFRAMEWORK_1_0
_serialPort.WatchChar = '\n';
#endif
_shouldDispose = true;
}
/// <inheritdoc/>
public void Dispose()
{
Stop();
if (_shouldDispose)
{
_serialPort?.Dispose();
_serialPort = null;
}
}
/// <inheritdoc/>
public override string GetProductDetails()
{
return "Generic GNSS Serial device";
}
/// <inheritdoc/>
public override bool Start()
{
if (_isrunning)
{
return true;
}
if (_serialPort == null)
{
_isrunning = false;
return false;
}
if (!_serialPort.IsOpen)
{
_serialPort.Open();
_serialPort.DataReceived += SerialPortDataReceived;
}
_isrunning = true;
return true;
}
/// <inheritdoc/>
public override bool Stop()
{
if (!_isrunning)
{
return true;
}
_isrunning = false;
if (_serialPort == null)
{
return false;
}
if (_serialPort.IsOpen)
{
_serialPort.DataReceived -= SerialPortDataReceived;
_serialPort.Close();
}
return true;
}
/// <inheritdoc/>
public override bool IsRunning => _isrunning;
private void SerialPortDataReceived(object sender, SerialDataReceivedEventArgs e)
{
try
{
var serialDevice = (SerialPort)sender;
if (serialDevice.BytesToRead == 0)
{
return;
}
var buffer = new byte[serialDevice.BytesToRead];
var bytesRead = serialDevice.Read(buffer, 0, buffer.Length);
var stringBuffer = Encoding.UTF8.GetString(buffer, 0, bytesRead);
#if NANOFRAMEWORK_1_0
var commands = stringBuffer.Split(serialDevice.WatchChar);
#else
var commands = stringBuffer.Split('\n');
#endif
foreach (var command in commands)
{
if (command.Length > 4)
{
ProcessCommands(command.TrimEnd('\r'));
}
}
}
catch (Exception exception)
{
RaiseParsingError(exception);
}
}
}
}