Interface & Application Programming
Week 13 - Interface & Application Programming
Here you will find my work description during this tirdsteenth week
General info
Class notes
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.
Then I compare than value. Depending of it I process some action, like turn forward or backward.
Loop and setup methods: init serial and motor pins
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
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.
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)
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
Stay in touch
Hi, I'm
Joris Navarro, from Perpignan (France), a proud dad, a fab director/manager, a teacher, a ceo, a FabAcademy student, but not only. Click here to know more about me.
Check my work for FabAcademy on FabCloud GitLab
@joris.navarro.
Want to say Hi ? Please send me a message.