Skip to content

Instantly share code, notes, and snippets.

@tsuckow
Created September 9, 2016 05:24
Show Gist options
  • Save tsuckow/a139f9b6ca1eb09c83b500ecbbf97a69 to your computer and use it in GitHub Desktop.
Save tsuckow/a139f9b6ca1eb09c83b500ecbbf97a69 to your computer and use it in GitHub Desktop.
ComPort workaround
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO.Ports;
using System.IO;
namespace IPS.COM
{
public class ComPort : IDisposable
{
private SerialPort port = null;
private bool disposed = false;
const int READ_TIMEOUT = 500;
const int WRITE_TIMEOUT = 500;
const bool PARITY = false;
public const string NewLine = "\r";
public ComPort( string portname )
{
port = new SerialPort(portname);
GC.SuppressFinalize(port); //!! HACK !!// More workaround for BUG IN .NET
port.NewLine = NewLine;
bool ok = true;
try
{
port.BaudRate = 115200;
port.Open();
}
catch
{
ok = false;
}
finally
{
if (!ok)
{
GC.ReRegisterForFinalize(port); //!! HACK !!// BUG IN .NET
}
}
GC.SuppressFinalize(port.BaseStream); //!! HACK !!// BUG IN .NET
}
~ComPort()
{
Dispose(false);
}
private void CheckOpen()
{
if (!port.IsOpen)
{
throw new ComPortException();
}
}
private byte GenParity(string str)
{
byte b = 0;
foreach (char ch in str)
{
b = (byte)(b ^ (byte)ch);
}
return b;
}
public void Write( string str )
{
Write( str, WRITE_TIMEOUT );
}
/**
** \brief Writes str to the com port.
**
** The string is automaticly appended with ; and a parity byte.
*/
public void Write(string str, int timeout)
{
CheckOpen();
port.WriteTimeout = timeout;
#pragma warning disable 0162
if (PARITY)
{
byte parity = GenParity(str);
str += parity;
}
#pragma warning restore 0162
port.WriteLine(str);
}
public string Read()
{
return Read(READ_TIMEOUT);
}
public string Read(int timeout)
{
CheckOpen();
port.ReadTimeout = timeout;
string str = "";
try
{
str = port.ReadLine();
}
catch
{
str = port.ReadExisting();
}
#pragma warning disable 0162
if (PARITY)
{
byte parity = (byte)str[str.Length - 1];
str = str.Substring(0, str.Length - 1);
if (parity != GenParity(str))
{
throw new ParityException();
}
}
#pragma warning restore 0162
return str;
}
public static string[] listDevices()
{
string[] ports = System.IO.Ports.SerialPort.GetPortNames();
HashSet<string> set = new HashSet<string>();
foreach (string portname in ports)
{
string temp = portname;
while (temp.Length > 0)
{
set.Add(temp);
temp = temp.Remove(temp.Length - 1);
}
}
return set.ToArray();
}
#region IDisposable Members
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected void Dispose(bool disposing)
{
if( !this.disposed )
{
Stream sbase = null;
if (port != null && port.IsOpen)
{
sbase = port.BaseStream;
port.Close();
}
/*
** because of the issue with the FTDI USB serial device,
** the call to the stream's finalize is suppressed
**
** an attempt to un-suppress the stream's finalize is made
** here, but if it fails, the exception is caught and
** ignored
*/
if (sbase != null)
{
GC.ReRegisterForFinalize(sbase);
}
if (port != null)
{
GC.ReRegisterForFinalize(port);
if (disposing)
{
port.Dispose();
}
}
this.disposed = true;
}
}
#endregion
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace IPS.COM
{
public class ComPortException : ApplicationException
{
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace IPS.COM
{
public class ParityException : ApplicationException
{
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment