//------------------------------------------------------------------------------
// SerialPortEx.cs
//
// Extension of SerialPort class for .NET Micro Framework
//
// http://bansky.net/blog
//
// This code was written by Pavel Bansky. It is released under the terms of
// the Creative Commons "Attribution 3.0 Unported" license.
// http://creativecommons.org/licenses/by/3.0/
//
//------------------------------------------------------------------------------
using System;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
namespace Bansky.Net
{
///
/// Extension of SerialPort class
///
public class SerialPortEx : IDisposable
{
private SerialPort port;
///
/// Initializes a new instance of the SerialPort class.
///
/// Serial port configuartion
public SerialPortEx(SerialPort.Configuration configuration)
{
this.port = new SerialPort(configuration);
this.Encoding = new System.Text.UTF8Encoding();
this.ReadTimeout = Timeout.Infinite;
this.NewLine = "\n";
}
///
/// Initializes a new instance of the SerialPort class.
///
/// The port to use (for example, COM1).
/// The baud rate
/// Enable flow control
public SerialPortEx(SerialPort.Serial comPort, SerialPort.BaudRate speed, bool flowControl)
: this(new SerialPort.Configuration(comPort, speed, flowControl))
{
}
///
/// Writes a specified number of bytes to an output buffer at the specified offset.
///
/// The byte array to write the output to.
/// The offset in the buffer array to begin writing.
/// The number of bytes to write.
public void Write(byte[] buffer, int offset, int count)
{
this.port.Write(buffer, offset, count);
}
///
/// Writes the parameter string to the output.
///
/// The string to write to the output buffer.
public void Write(string text)
{
if (text == null)
throw new ArgumentNullException();
if (text.Length > 0)
{
byte[] data = this.Encoding.GetBytes(text);
Write(data, 0, data.Length);
}
}
///
/// Writes the specified string and the NewLine value to the output buffer.
///
/// The string to write to the output buffer.
public void WriteLine(string text)
{
Write(text + this.NewLine);
}
///
/// Reads a number of bytes from the SerialPort input buffer and writes those bytes into a byte array at the specified offset.
///
/// The byte array to write the input to.
/// The offset in the buffer array to begin writing.
/// The number of bytes to read.
/// The timeout for read operation
/// The number of bytes to read.
public int Read(byte[] buffer, int offset, int count, int timeout)
{
return this.port.Read(buffer, offset, count, timeout);
}
///
/// Reads a number of bytes from the SerialPort input buffer and writes those bytes into a byte array at the specified offset.
///
/// The byte array to write the output to.
/// The offset in the buffer array to begin writing.
/// The number of bytes to write.
/// The number of bytes read.
public int Read(byte[] buffer, int offset, int count)
{
return this.port.Read(buffer, offset, count, this.ReadTimeout);
}
///
/// Reads up to the NewLine value in the input buffer
///
/// The contents of the input buffer up to the first occurrence of a NewLine value.
public string ReadLine()
{
return ReadTo(this.NewLine);
}
///
/// Reads a string up to the specified value in the input buffer.
///
/// A value that indicates where the read operation stops.
/// The contents of the input buffer up to the specified value.
public string ReadTo(string value)
{
string textArrived = string.Empty;
// Arguments check
if (value == null)
throw new ArgumentNullException();
if (value.Length == 0)
throw new ArgumentException();
// This is for speed performance (in loops below)
byte[] byteValue = Encoding.GetBytes(value);
int byteValueLen = byteValue.Length;
bool flag = false;
// +1 because of two byte characters
byte[] buffer = new byte[byteValueLen+1];
// Read until pattern or timeout
do
{
int bytesRead;
int bufferIndex = 0;
Array.Clear(buffer, 0, buffer.Length);
// Read data until the buffer size is less then pattern.Length
// or last char in pattern is received
do
{
bytesRead = port.Read(buffer, bufferIndex, 1, this.ReadTimeout);
bufferIndex += bytesRead;
// if nothing was read (timeout), we will return null
if (bytesRead <= 0)
{
return null;
}
}
while ((bufferIndex < byteValueLen+1)
&& (buffer[bufferIndex - 1] != byteValue[byteValueLen - 1]));
// Decode received bytes into chars and then into string
char[] charData = Encoding.GetChars(buffer);
for (int i = 0; i < charData.Length; i++)
textArrived += charData[i];
flag = true;
// This is very important!! Bytes received can be zero-length string.
// For example 0x00, 0x65, 0x66, 0x67, 0x0A will be decoded as empty string.
/// So this condition is not a burden!
if (textArrived.Length > 0)
{
// check whether the end pattern is at the end
for (int i = 1; i <= value.Length; i++)
{
if (value[value.Length - i] != textArrived[textArrived.Length - i])
{
flag = false;
break;
}
}
}
} while (!flag);
// chop end pattern
if (textArrived.Length >= value.Length)
textArrived = textArrived.Substring(0, textArrived.Length - value.Length);
return textArrived;
}
///
/// Clears all buffers and causes any buffered data to be written to the SerialPort
///
public void Flush()
{
this.port.Flush();
}
#region IDisposable Members
public void Dispose()
{
port.Dispose();
port = null;
}
#endregion
///
/// Gets or sets the byte encoding for pre- and post-transmission conversion of text.
///
public System.Text.Encoding Encoding;
///
/// Gets or sets the value used to interpret the end of a call to the ReadLine and WriteLine methods.
///
public string NewLine;
///
/// Gets or sets the number of milliseconds before a time-out occurs when a read operation does not finish.
///
public int ReadTimeout;
}
}