//------------------------------------------------------------------------------ // 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; } }