Last active
February 3, 2016 04:05
-
-
Save jen20/8038233 to your computer and use it in GitHub Desktop.
Start of a nice Observable wrapper for serial devices for a WPF app
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.IO; | |
using System.IO.Ports; | |
using System.Reactive.Linq; | |
namespace ObservableSerialPort | |
{ | |
public class ObservableSerialPort : IObservable<string> | |
{ | |
private readonly string _portName; | |
private readonly int _baudRate; | |
private readonly Parity _parity; | |
private readonly int _databits; | |
private readonly StopBits _stopBits; | |
private IObservable<string> _serialPortObservable; | |
public ObservableSerialPort(string portName, int baudRate = 9600, Parity parity = Parity.None, int databits = 8, StopBits stopBits = StopBits.One) | |
{ | |
_portName = portName; | |
_baudRate = baudRate; | |
_parity = parity; | |
_databits = databits; | |
_stopBits = stopBits; | |
CreateObservable(); | |
} | |
private void CreateObservable() | |
{ | |
var port = new SerialPort(_portName, _baudRate, _parity, _databits, _stopBits); | |
_serialPortObservable = Observable.Create<string>(obs => | |
{ | |
var receiveCallback = new SerialDataReceivedEventHandler((sender, e) => | |
{ | |
if (e.EventType == SerialData.Eof) | |
obs.OnCompleted(); | |
else | |
{ | |
var serialPort = (SerialPort)sender; | |
var input = serialPort.ReadLine(); | |
var newLineIndex = input.IndexOf(serialPort.NewLine, StringComparison.Ordinal); | |
var value = (newLineIndex < 0) ? input : input.Remove(newLineIndex, serialPort.NewLine.Length); | |
obs.OnNext(value); | |
} | |
}); | |
port.DataReceived += receiveCallback; | |
var errorCallback = new SerialErrorReceivedEventHandler((sender, e) => obs.OnError(new Exception(e.EventType.ToString()))); | |
port.ErrorReceived += errorCallback; | |
try | |
{ | |
port.Open(); | |
} | |
catch (IOException e) | |
{ | |
obs.OnError(e); | |
} | |
return () => | |
{ | |
port.DataReceived -= receiveCallback; | |
port.ErrorReceived -= errorCallback; | |
port.Close(); | |
port.Dispose(); | |
}; | |
}); | |
} | |
public IDisposable Subscribe(IObserver<string> observer) | |
{ | |
return _serialPortObservable.Subscribe(observer); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment