Interface & Application Programming

Week 13 - Interface & Application Programming

Here you will find my work description during this tirdsteenth week

General info

Class notes

Link to my notes during class

Assignments

  • individual assignment: write an application that interfaces with an input &/or output device that you made
  • group assignment: compare as many tool options as possible

ATmaga328p Datasheet RN48711 Datasheet

Arduino

With the board I realized last week (output assignement), based on Neil’s Bipolar stepper motor. I wrtite some code to add seral communication. So like a state machine I write a “trivial” serial protocol. if you read:

  • char ‘a’ means stop rotating
  • char ‘b’ means rotate clockwise (1 turn)
  • char ‘c’ means rotate counterclock wise (1 turn)

after command, send to total amount of turn realised.

How it is developped ?

During the Embedded programming week I develop serial communication methods. To summarize I read the raw data from the serial and convert it to an ASCII value.

image not loaded

Then I compare than value. Depending of it I process some action, like turn forward or backward.

image not loaded

Loop and setup methods: init serial and motor pins

image not loaded

Xamarin

What is Xamarin Plateform ?

Why Xamarin ?

Cross plateform solution to develop mobile applications. Can build native applications Use C# and Visual Studio

Getting started with Xamarin

Get Xamarin

I spent few hours trying to install Xamarin because I had some troubles because of Beta version already installed on my computer.

I created a new Project and started discovering the plateform reding tutorials and documentations.

When I realized I can not release something for the assignement I decided to write a quick desktop app to dialog with the output board I made last week.

w13

Desktop application

This application is a quick and dirty desktop app developped in WPF (XAML) and C#. It uses the SerialPort object to open a connection with the board (9600 bauds). Than I added 2 buttons (Clockwise and Counter Clock wise) to send data to serial:

  • char ‘a’ means stop rotating
  • char ‘b’ means rotate clockwise (1 turn)
  • char ‘c’ means rotate counterclock wise (1 turn)

w13

click on the next thumbnail to see a result video

The code behind the 2 buttons window is quite simple.

The Window object creates and open a serial connection. When data is received it display in a label. The difficulty here is to display on the UI thread an information read in another thread, for that I used the grlobal Dispatcher.

Like a state-machine, when we hold a button (CCW_Button_Clicked) I memorize the state in global var. Depending on the state we enable/disable a timer that will send the command through the serial port to the device.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.IO.Ports;
using System.Net;
using System.Threading;
using System.Xml;
using Timer = System.Timers.Timer;

namespace W13WpfApp
{
    /// <summary>
    /// Logique d'interaction pour MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private string comPortToUse = "COM5";
        private int baudRate = 9600;

        private bool portFound;
        private SerialPort sport;

        private bool holdCW;
        private bool holdCCW;

        private Timer holdTimer;

        public MainWindow()
        {
            InitializeComponent();

            holdTimer = new Timer(1000);
            holdTimer.Elapsed += (sender, a) => Turn();

            try
            {
                if (sport == null || !sport.IsOpen)
                {
                    while (!GetSerialPorts())
                    {
                        Thread.Sleep(5000);
                    }
                }
                else
                {
                    Thread.Sleep(3000);
                }
            }
            finally
            {
            }
        }

        private void Turn()
        {
            string direction = "a";
            if (holdCW)
            {
                direction = "b";
            }

            if (holdCCW)
            {
                direction = "c";
            }

            if (holdCW || holdCCW)
            {
                try
                {
                    byte[] hexstring = Encoding.ASCII.GetBytes(direction);
                    foreach (byte hexval in hexstring)
                    {
                        byte[] _hexval = new byte[] { hexval }; // need to convert byte to byte[] to write
                        sport.Write(_hexval, 0, 1);
                        Thread.Sleep(1);
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine("Failed to SEND \n" + ex + "\n");

                }
            }            
        }

        private bool GetSerialPorts()
        {
            foreach (var portName in SerialPort.GetPortNames())
            {
                Console.WriteLine("FOUND " + portName);
            }

            portFound = SerialPort.GetPortNames().Contains(comPortToUse);

            if (!portFound)
            {
                Console.WriteLine(comPortToUse + " port not found !");
                return false;
            }

            serialport_connect(comPortToUse, baudRate);

            return true;
        }

        public void serialport_connect(String port, int baudrate)
        {
            sport = new SerialPort(port, baudrate);
            sport.PortName = port;
            sport.BaudRate = Convert.ToInt32(baudrate);
            sport.Handshake = System.IO.Ports.Handshake.None;
            sport.Parity = Parity.None;
            sport.DataBits = 8;
            sport.StopBits = StopBits.Two;
            sport.ReadTimeout = 200;
            sport.WriteTimeout = 50;

            try
            {
                sport.Open();
                sport.DataReceived += SportDataReceived;
                Console.WriteLine("COM port open");
                CwButton.IsEnabled = true;
                CcwButton.IsEnabled = true;
            }
            catch (Exception ex)
            {
                Console.WriteLine("EXCEPTION : " + ex, "Error");
            }

            holdTimer.Start();
        }

        string readValue;

        private void SportDataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            DateTime dt = DateTime.Now;
            String dtn = dt.ToShortTimeString();
            readValue = sport.ReadExisting();

            Dispatcher.BeginInvoke(new Action(delegate ()
            {
                rx.Text = readValue;
            }));
           

            Console.WriteLine("[" + dtn + "] " + "Received: " + readValue + "\n");
        }

        public void ClosePort()
        {
            try
            {
                holdTimer.Stop();
                if (sport.IsOpen)
                {
                    sport.Close();
                    Console.WriteLine("COM port closed");
                }
            }
            catch (Exception)
            {
                Console.WriteLine();
            }
        }


        public static string TextToBase64(string sAscii)
        {
            byte[] bytes = Encoding.ASCII.GetBytes(sAscii);
            return System.Convert.ToBase64String(bytes, 0, bytes.Length);
        }


        private void CCW_Button_Clicked(object sender, RoutedEventArgs e)
        {
            if (sport.IsOpen)
            {

            }
        }

        private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            ClosePort();
        }

        private void CWButton_MouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            if (sport.IsOpen)
            {
                holdCW = true;
                Console.WriteLine("holding");
            }
        }

        private void CWButton_MouseUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            if (sport.IsOpen)
            {
                holdCW = false;
                Console.WriteLine("releasing");
            }
        }

        private void CCWButton_MouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            if (sport.IsOpen)
            {
                holdCCW = true;
                Console.WriteLine("holding");
            }
        }

        private void CCWButton_MouseUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            if (sport.IsOpen)
            {
                holdCCW = false;
                Console.WriteLine("releasing");
            }
        }


    }
}

Files to download

Click here to download WPF project

Click here to download the arduino project




Share this story