Netduino home hardware projects downloads community

Jump to content


The Netduino forums have been replaced by new forums at community.wildernesslabs.co. This site has been preserved for archival purposes only and the ability to make new accounts or posts has been turned off.
Photo

Application Of The Serial Input Class Suggested By Corey Kosak


  • Please log in to reply
2 replies to this topic

#1 Paul

Paul

    Member

  • Members
  • PipPip
  • 14 posts

Posted 29 October 2010 - 11:01 PM

Having gotten the serial output of the Maxbotix range finder working my next step was to apply the SerialInput Class suggested by Corey Kosak in his reponse to one of my earlier posts. After looking through the code to get an understanding of how it works I made the following very minor adjustments:

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

Attached Files



#2 Corey Kosak

Corey Kosak

    Advanced Member

  • Members
  • PipPipPip
  • 276 posts
  • LocationHoboken, NJ

Posted 30 October 2010 - 12:32 AM

That is SO awesome :)

#3 hari

hari

    Advanced Member

  • Members
  • PipPipPip
  • 131 posts

Posted 30 October 2010 - 03:45 AM

Very nice... I have to remember to use this the next time I need to use serial port. Great job Paul! =Hari=




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users

home    hardware    projects    downloads    community    where to buy    contact Copyright © 2016 Wilderness Labs Inc.  |  Legal   |   CC BY-SA
This webpage is licensed under a Creative Commons Attribution-ShareAlike License.