- I removed the #DEFINE and related conditionals
- I removed his "Main" from the class and placed the "While True" loop code into the "Main" in my Program.cs file.
- I added the public void Print(string line) from Hari's original SerialHelper class so that I could send the output of the Maxbotix sensor the the ASCII terminal program on my PC via the serial to USB FTDI cable.
I was very impressed that the code ran perfectly first time out. For reference the SerialInput class as I used it appears below. That is followed by the relevant section of my "Main." Attached is the screen shot of the output of the Maxbotix captured by the SerialInput class. Everything ran for as long as I let it wtih no exceptions popping up. As you can see from the screen shot I targeted a stationary object 17 inches away. Once in a while you will note that the distance got reported as 16 inches. Again, the serial ouput of the Maxbotix is far more stable than the analog output has proven to be.
SerialInput Class with added Print function
using System; using System.Collections; using System.Threading; using System.IO.Ports; using System.Text; using Microsoft.SPOT; using SecretLabs.NETMF.Hardware.Netduino; using Math = System.Math; namespace PoluluRobot_010 { public class SerialIinput : IDisposable { private readonly SerialPort serialPort; private MyStringBuilder myStringBuilder = new MyStringBuilder(); private readonly object sync = new object(); private readonly Queue lines = new Queue(); private readonly AutoResetEvent autoResetEvent = new AutoResetEvent(false); public SerialIinput(string portName = SerialPorts.COM2, int baudRate = 9600, Parity parity = Parity.None, int dataBits = 8, StopBits stopBits = StopBits.One) { serialPort = new SerialPort(portName, baudRate, parity, dataBits, stopBits); serialPort.DataReceived += (o, e) => ProcessData(); serialPort.Open(); } public void Print(string line) { System.Text.UTF8Encoding encoder = new System.Text.UTF8Encoding(); byte[] bytesToSend = encoder.GetBytes(line); serialPort.Write(bytesToSend, 0, bytesToSend.Length); } public void Dispose() { serialPort.Dispose(); } public string ReadLine() { while (true) { lock (sync) { if (lines.Count > 0) { return (string)lines.Dequeue(); } } autoResetEvent.WaitOne(); } } private void ProcessData() { var buffer = new byte[32]; var bytesToRead = serialPort.BytesToRead; while (bytesToRead > 0) { var bytesReceived = serialPort.Read(buffer, 0, Math.Min(bytesToRead, buffer.Length)); Process(buffer, bytesReceived); bytesToRead -= bytesReceived; } } private void Process(byte[] buffer, int count) { foreach (var ch in Encoding.UTF8.GetChars(TrimToSize(buffer, count))) { var atNewLine = ch == '\r' || ch == '\n'; if (atNewLine) { Flush(); } else { myStringBuilder.Append(ch); } } } private static byte[] TrimToSize(byte[] buffer, int count) { if (buffer.Length == count) { return buffer; } var newBuffer = new byte[count]; Array.Copy(buffer, newBuffer, count); return newBuffer; } private void Flush() { var nextLine = myStringBuilder.ToString(); myStringBuilder = new MyStringBuilder(); lock (sync) { lines.Enqueue(nextLine); } autoResetEvent.Set(); } } public class MyStringBuilder { private const int initialCapacity = 4; private char[] buffer = new char[initialCapacity]; private int currentLength = 0; public void Append(char ch) { if (currentLength == buffer.Length) { //at capacity? var newBuffer = new char[currentLength * 2]; Array.Copy(buffer, newBuffer, currentLength); buffer = newBuffer; } buffer[currentLength++] = ch; } public override string ToString() { return new string(buffer, 0, currentLength); } } }
Below is the loop used to call the class and write the output to the ASCII terminal program
public class Program { static SerialIinput serialInput = new SerialIinput(); static InterruptPort interruptPort = new InterruptPort(Pins.ONBOARD_SW1, false, Port.ResistorMode.PullUp, Port.InterruptMode.InterruptEdgeLow); static DualSerialMotorController motorController = new DualSerialMotorController(); public static void Main() { SetupButton(); using (var s = serialInput) { while (true) { var result = s.ReadLine(); s.Print(result); //Debug.Print(result); if (result == "quit") { break; } } } }