Interface and application programming

1. Week assignment

write an application that interfaces with an input &/or output device that you made, comparing as many tool options as possible

2. Development Environment

This week I used Visual Studio 2015 CE and Arduino IDE.

3. The sketch

          
            #include <SoftwareSerial.h>

            const int rx=0; // rx pin for serial
            const int tx=2; // tx pin for serial
            SoftwareSerial mySerial(rx,tx); // serial initialize

            int led = 4; // pin where the led is soldered to
            int sensor = 3; // pint where the photoresistor is soldered to
            int value; // int for reading value


            void setup() {
              // defining pin as input/output
              pinMode(rx, INPUT);
              pinMode(tx, OUTPUT);
              pinMode(led, OUTPUT);
              pinMode(sensor,INPUT);
              mySerial.begin(9600); // serial starting
              // debug
              digitalWrite(led,HIGH);
              delay(500);
              digitalWrite(led,LOW);
              delay(500);
            }

            void loop() {
              // reading sensor data and putting the value on the serial
              if (mySerial.available()) {
                value=analogRead(sensor);
                mySerial.println(value);
              }
              delay(100);
            }
          
        

I decided to use the board I made for input device week.

This sketch running on the board write the value read from the ADC which is connected to the photoresistor on the emulated software serial.

4. The interface

For the interface implementation I used Visual C# in visual studio.

This is the code for the main (and only) window.

          

            using System;
            using System.Linq;
            using System.Windows;
            using System.Windows.Controls;
            using System.Management;
            using System.IO.Ports;
            using System.Threading.Tasks;

            namespace Interface {
              /// <summary>
              /// Interaction logic for MainWindow.xaml
              /// </summary>
              public partial class MainWindow : Window {
                SerialPort mySerialPort;
                string indata;
                public MainWindow() {
                  InitializeComponent(); //initialize window
                  comboBox.IsEnabled = true; //initialize selection for COMs
                  // Add COM ports to selection box
                  string[] ports = SerialPort.GetPortNames();
                  comboBox.Items.Clear();
                  for (int i = 0; i < ports.Length; i++) {
                    comboBox.Items.Add(ports[i]);
                  }
                  // declare max and min for bar: 0 is the minimun adc value and 1023 is the maximum
                  sensor.Maximum = 1023;
                  sensor.Minimum = 0;
                }

                //try to initialize serial
                private void comboBox_SelectionChanged(object sender, SelectionChangedEventArgs e) {
                  try {
                    serialInizialize(comboBox.SelectedValue.ToString(), 9600);
                  } catch {
                    MessageBox.Show("No data found on this serial port.");
                  }
                }

                // update value read from sensor
                public void update(string value) {
                  string input=indata;
                  indata = indata.Substring(indata.Length - 2); //remove carriage from string
                  //this dispatcher is needed because serial is working on a different thread and
                  //can't update main window component
                  try { // catch the exception when the program is closed and serial keeps going on
                    this.Dispatcher.Invoke(() =>{
                      try {
                        sensor.Value = Convert.ToDouble(input); //casting from string to double
                      } catch (Exception e) {
                      }
                      labelValue.Content= Convert.ToDouble(input); //casting from string to double
                    });
                  } catch (TaskCanceledException tc) {
                    Console.WriteLine(tc);
                  }
                }

                //define the method for initializing the serial
                public void serialInizialize(string port, int baud) {
                  mySerialPort = new SerialPort(port);
                  mySerialPort.BaudRate = baud;
                  mySerialPort.Parity = Parity.None;
                  mySerialPort.StopBits = StopBits.One;
                  mySerialPort.DataBits = 8;
                  mySerialPort.Handshake = Handshake.None;
                  // define the handler called when a new data is read on the serial
                  mySerialPort.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
                  mySerialPort.Open();
                }

                //serial data handler
                public void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e) {
                  SerialPort sp = (SerialPort)sender;
                  indata = sp.ReadLine(); //read a line and wait until all the line is read
                  Console.WriteLine(indata); //debug code, write sensor data on the console
                  if(indata!="\r"&&indata!="") //check for blank strings
                  update(indata);
                }
              }
            }
          
        

The interface is this:



There is a selection box which list all the COM ports in the PC, and as soon as you click the COM you want the application connects to the one selected.

When the connection is started, the data is read from the serial, and the bar and the value is updated accordingly.

Note: if you also want output on console, you need to define your application output type as “Console Application”.

Interesting bits of code:
- public void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
    This method is the handler of the serial, the code inside is run every time a data is written on the serial. This is a standalone thread, running independently from the main one
- public void update(string value)
    This method updates the bar and the text label value. It uses a dispatcher because in VS you cannot let a thread different from main window update visual elements.

The try-catch blocks works in this way: in the try you try (indeed) to run the code; if an exception (an unexpected behaviour) you can handle it in the catch block. In this case I have try-catch blocks for null strings (converting to int an empty string throws and exception), when I close the application, because sometimes the console in the background throws an error, and if for some reason the serial can’t be opened (because unavailable or maybe busy from other processes, like Arduino IDE serial monitor).

Interface from Nicola Giannelli on Vimeo.

5. Files

Source codes - .zip