Small C# App To Learn Serial

I had some free time today and decided to try to implement a 'handshake' between the program and my Arduino.

Its by no means complete, and it doesnt do much of anything, but I figure having the code up could help someone whos stuck doing serial, as I did run into a funny problem - the first try it would always time out, and the second time it would work fine. I added a line of code and commented it about this issue.


Main screen. Call button is disabled until a port is selected (WIP!)


Notification that its found a port (multiple port stuff is untested and unimplemented as of this edit)


Information after the 'call' is complete (takes about 500mS)


Project Link (Includes binary and source)


Arduino

void setup() 
{
  Serial.begin(9600);
}

void loop() 
{
  if (Serial.available() > 0)
  {
    if (Serial.read() == 0x69)
    {
      // Model|Version|Serial
      Serial.print("Arduino|v1.00|1337\n");
    }
     Serial.flush();
  }
}

C#

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows.Forms;

namespace Serial_Call
{
    public partial class SerialApp : Form
    {
        bool multiplePorts = false;

        public SerialApp()
        {
            InitializeComponent();
            status.Text = "";
            serialLabel.Text = "";
            versionLabel.Text = "";
            modelLabel.Text = "";
            callButton.Enabled = false;
        }

        private void callButton_Click(object sender, EventArgs e)
        {
            serial.DtrEnable = true;
            //serial.PortName = "COM3";

            serial.ReadTimeout = 250;
            serial.WriteTimeout = 250;

            serial.Open();

            if (!multiplePorts)
            {
                while (true)
                {
                    try
                    {
                        serial.Write(new byte[] { 0x69 }, 0, 1);
                        string message = serial.ReadLine();
                        populateInfo(message);
                        break; // shouldnt get here unless read is successful
                    }
                    catch (TimeoutException) { } // dirty trick to get around the silly timeout exception on the first try
                    catch (Exception ex)
                    {
                        MessageBox.Show("Exception! Text: \n" + ex);
                        status.Text = "Failure!";
                    }
                }
                serial.Close();
            }
        }

        private void populateInfo(string message)
        {
            string[] delimiter = new string[] { "|" };

            string[] result = message.Split(delimiter, StringSplitOptions.None);

            modelLabel.Text = result[0];
            versionLabel.Text = result[1];
            serialLabel.Text = result[2];

            status.Text = "Success!";
        }

        private void searchButton_Click(object sender, EventArgs e)
        {
            string[] ports = SerialPort.GetPortNames();
            if (ports.Length > 0)
            {
                foreach (string port in ports)
                {
                    string devicesString = ports.Length + " device";

                    if (ports.Length == 0)
                    {
                        devicesString = devicesString + "s found!";
                    }
                    else if (ports.Length == 1)
                    {
                        devicesString = devicesString + " found!";
                        serial.PortName = port;
                    }
                    else if (ports.Length > 1)
                    {
                        devicesString = devicesString + "s found!";
                        multiplePorts = true;
                    }

                    MessageBox.Show(devicesString);
                }
                callButton.Enabled = true;
            }
            else
            {
                MessageBox.Show("No serial ports found!");
            }
        }
    }
}
            if (ports.Length > 0)
            {
                foreach (string port in ports)
                {
                    string devicesString = ports.Length + " device";

                    if (ports.Length == 0)
                    {
                        [glow]devicesString = devicesString + "s found!";[/glow]

How does the highlighted code ever get executed?

What is the whole searchButton_Click call back doing? The ports array is populated with the available COM port names. You iterate through that list, caring, on each pass, only about the length of the list. What is the purpose of iterating through the list?

You can also just do

devicesString += "s found!";

saves a bit of coding :)

bld, I usually do the full version of everything on the first go, and then go back through and optimize for a v1.1 with things like you suggested. It just makes it easier for me to debug the code and make sure its not my logic thats wrong :)

PaulS, like I said, its not perfect ;) Ill take a look at it when I get home, but that looks to be remnants of something I started and didnt finish (but the program worked without it implemented).

I do things the easy way the first time, so I don't forget to get back and update it, plus I am too lazy to do it more difficult and twice, if I can do it the first time. ;D

Fair enough!

I have slightly revised the code, still a WIP!

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows.Forms;

namespace Serial_Call
{
    public partial class SerialApp : Form
    {
        bool multiplePorts = false;

        public SerialApp()
        {
            InitializeComponent();
            status.Text = "";
            serialLabel.Text = "";
            versionLabel.Text = "";
            modelLabel.Text = "";
            callButton.Enabled = false;
        }

        private void callButton_Click(object sender, EventArgs e)
        {
            serial.DtrEnable = true;
            //serial.PortName = "COM3";

            serial.ReadTimeout = 250;
            serial.WriteTimeout = 250;

            serial.Open();

            if (!multiplePorts)
            {
                int times = 0;

                while (true && times < 5)
                {
                    try
                    {
                        times++;
                        serial.Write(new byte[] { 0x69 }, 0, 1);
                        string message = serial.ReadLine();
                        populateInfo(message);
                        break; // shouldnt get here unless read is successful
                    }
                    catch (TimeoutException) { } // dirty trick to get around the silly timeout exception on the first try
                    catch (Exception ex)
                    {
                        MessageBox.Show("Exception! Text: \n" + ex);
                        status.Text = "Failure!";
                    }
                }
                serial.Close();
            }
        }

        private void populateInfo(string message)
        {
            string[] delimiter = new string[] { "|" };

            string[] result = message.Split(delimiter, StringSplitOptions.None);

            modelLabel.Text = result[0];
            versionLabel.Text = result[1];
            serialLabel.Text = result[2];

            status.Text = "Success!";
        }

        private void searchButton_Click(object sender, EventArgs e)
        {
            string[] ports = SerialPort.GetPortNames();
            if (ports.Length > 0)
            {
                foreach (string port in ports)
                {
                    string devicesString = ports.Length + " device";

                    if (ports.Length == 1)
                    {
                        devicesString += " found!";
                        serial.PortName = port;
                    }
                    else if (ports.Length > 1)
                    {
                        devicesString += "s found!";
                        multiplePorts = true;
                    }

                    MessageBox.Show(devicesString);
                }
                callButton.Enabled = true;
            }
            else
            {
                MessageBox.Show("No serial ports found!");
            }
        }
    }
}

Its so much simpler in visual basic. Of course its about as amateur as it gets, but that the reason.