Skip to content

Instantly share code, notes, and snippets.

@ddpruitt
Forked from jen20/ObservableSerialPort.cs
Created February 3, 2016 04:05
Show Gist options
  • Save ddpruitt/12a017862a57757b88d5 to your computer and use it in GitHub Desktop.
Save ddpruitt/12a017862a57757b88d5 to your computer and use it in GitHub Desktop.
Start of a nice Observable wrapper for serial devices for a WPF app
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