Professional Documents
Culture Documents
1. Overview
2. Assembling the Arduino Board
3. Example 1: Basic command based communication
4. Example 2: Extending functionality using a Timer
Aquí lo único que va se hará es una sencilla comunicación con el Arduino. El Arduino tendrá 2 push, 1 pot,
2 leds (no para on/off y otro para PWM).
La GUI será lo más básica posible sin usar un stream de comandos hacia el Arduino. El PWM se controlará
por medio de pasos: ‘a’ para PWM 25%, ‘b’ PWM 50% y así…
Overview
In this lecture we will communicate the prototype board we assembled in the previous lecture with a
software made in .Net Framework.
We will code a new Windows Forms application that will communicate over the Serial Port with an Arduino
Board which has some components attached to it: Servo motor, potenciometer, push button, LED.
We will basically replace the Serial Monitor with a “custom” program that will send the commands to the
arduino. This way we will create a nice Graphic User Interface (GUI) that an average person will be able
to easily use.
So keep in mind that the commands that the Arduino will receive will be sent over the Serial Port for a
program having a GUI. The GUI will have buttons, checkboxes and text boxes, the common controls any person
so far is used to see in any application.
I’ll use the same code from the last lecture’s example “Example: Controlling multiple input/output’s via
Serial” with little modifications:
/*
* Hazael Fernando Mojica García
* 11/August/2017
* HMI-3-Arduino-.Net-Ex1
*/
int pinServo = 3;
int pinLED = 4;
int pinPush = 5;
int pinPotA = 0;
int pwmVal = 0;
void setup() {
Serial.begin(115200);
pinMode(pinServo, OUTPUT);
pinMode(pinLED, OUTPUT);
pinMode(pinPush, INPUT);
}
void loop() {
if(Serial.available()) {
switch(Serial.read()) {
case 'a'://Turn On LED
digitalWrite(pinLED, HIGH);
break;
void increaseServo() {
pwmVal += 5;
if(pwmVal > 255) {
pwmVal = 255;
}
setPWMVal();
}
void decreaseServo() {
pwmVal -= 5;
if(pwmVal < 0) {
pwmVal = 0;
}
setPWMVal();
}
void setPWMVal() {
analogWrite(pinServo, pwmVal);
}
void readDigitalVal() {
//Writes "HIGH\r\n" if Push is pressed
//writes "LOW\r\n" otherwise
if(digitalRead(pinPush)) {
Serial.println("HIGH");
} else {
Serial.println("LOW");
}
}
void readAnalogVal() {
//Write a String of values representing a number
//between 0 and 1023 and adds \r\n at the end
//Example: "0\r\n", "20\r\n", "341\r\n", "1023\r\n",
//https://www.arduino.cc/en/Serial/Println
Serial.println(analogRead(pinPotA));
}
Create a new Windows Forms project in Visual Studio and add 6 buttons and 2 Labels. If you don’t remember
Windows Forms or Visual Studio read again HMI-1
HMI-1 C# .Net Fundamentals using Windows FormsYou
Forms will end up
with something similar to the next image:
Arrange everything and put text in the buttons so each one of them sends a specific command to the
Arduino. The next image is the final view of or screen.
I renamed the Control variable names so they coincide with the function they do, instead of having the
default names like button1, button2, label1 and so forth, I’ll have button_LEDOn, button_LEDOff,
label_Digital. You can do the same by changing the Property (name) in the Properties panel.
Create the click events for each one of the buttons and declare a SerialPort instance variable for
handling the SerialPort communication, this variable needs to be initialized in the Forms constructor with
the correct Baud Rate (115200 bds) and the COM port name.
You can find the port name in the Arduino IDE or in the Device Manager:
using System;
using System.Windows.Forms;
using System.IO.Ports;
namespace HMI3_Ex1
{
public partial class Form1 : Form
{
private SerialPort serialPort;
public Form1()
{
InitializeComponent();
//Actually creates the Serial Port instance object
//The Arduino is in COM1 and uses a Baud Rate of 115200bds
serialPort = new SerialPort("COM1", 115200);
serialPort.Open();
}
Testing functionality
So we compile and upload the code to the Arduino board, replace the correct Serial Port in the code of the
C# GUI, instead of “COM1” you could have “COM2” or “COM3”, who knows.
Run the GUI and click en the buttons to see how it works. Here is an example image of the GUI working:
Example 2: Extending functionality using a Timer
Now, we don’t actually want to push the button each time we want to read something from the Serial Port,
what about building a program that automatically sends the read command to the arduino in order to get the
analog signal value?
We will also add 2 buttons, one for starting the Timer and one for stopping it.
It’s also worth mentioning that now we are decopling the data transmission from the data reception. With
this I mean that when we send a command via Serial Port we are not expecting an inmediate response and
this is good because it may not be even one, instead of let our program hang until a response is comming
it’s better to make a separated process handle it.
It’s almost the same code as in the previous example but without the call for reading a digital value.
/*
* Hazael Fernando Mojica García
* 11/August/2017
* HMI-3-Arduino-.Net-Ex2
*/
int pinServo = 3;
int pinLED = 4;
int pinPush = 5;
int pinPotA = 0;
int pwmVal = 0;
void setup() {
Serial.begin(115200);
pinMode(pinServo, OUTPUT);
pinMode(pinLED, OUTPUT);
pinMode(pinPush, INPUT);
}
void loop() {
if(Serial.available()) {
switch(Serial.read()) {
case 'a'://Turn On LED
digitalWrite(pinLED, HIGH);
break;
void increaseServo() {
pwmVal += 5;
if(pwmVal > 255) {
pwmVal = 255;
}
setPWMVal();
}
void decreaseServo() {
pwmVal -= 5;
if(pwmVal < 0) {
pwmVal = 0;
}
setPWMVal();
}
void setPWMVal() {
analogWrite(pinServo, pwmVal);
}
void readAnalogVal() {
//Write a String of values representing a number
//between 0 and 1023 and adds \r\n at the end
//Example: "0\r\n", "20\r\n", "341\r\n", "1023\r\n",
//https://www.arduino.cc/en/Serial/Println
Serial.println(analogRead(pinPotA));
}
You need to delete everything related to the digital read routines. Add a SerialPort and a Timer controls
to the Form. Also add a Chart control and change it’s Series to a Spline as shown in the images below:
Configure the Timer for an Interval of 300ms using the Properties panel.
Create a “Tick Event” for the Timer control using the Properties panel - Events section and makind double
click to the “Tick” Behavior.
Configure the SerialPort for using the Serial Port “COMx” your Arduino is connected to and a Baud Rate
of 115200 using the Properties Panel.
Create a “Data Received Event” using the Properties panel - Events section and making double click to the
“DataReceived” Behaviour.
The code would looks like:
using System;
using System.Windows.Forms;
using System.IO.Ports;
using System.Collections.Generic;
namespace HMI3_Ex2 {
public partial class Form1 : Form {
private Queue<int> samples;
public Form1() {
InitializeComponent();
}
Paying close attention the this code you should note some differences compared to the previous example:
1. The SerialPort variable is now handled in the Designer view and is now called serialPort1.
2. A new Event is used for get notified when we are receiving data over the Serial Port, which is the
method serialPort1_DataReceived.
3. A method called timer1_Tick is executed each 300ms and it sends the command “f” over the Serial Port,
it also has some validation in it to stop the application if for some reason the Serial Port is
unavailable.
4. An instance variable private Queue<int> samples; is created for storing up to 50 values retrieved from
the Analog Digital convertion made by the Arduino. If you don’t know this data structure here is some
useful links: Wikipedia
Wikipedia, MSDN
Wikipedia MSDN.
MSDN
5. The method ChartRefresh() iterates over the Queue of samples and paints the Chart again. Note how this
method is called inside the Tick event, this means the Chart is going to have a refresh rate of 300ms.
6. The methods button_Analog_Start_Click and button_Analog_Stop_Click are used only for starting and stoping
the Tick Event execution.
Testing functionality
Compile and upload the code to the Arduino. Run the GUI application, click the Turn LED ON and OFF, the
PWM++ and – buttons to check if they are still working. And now click the Start Reading button to start
populating the SPLine Chart.
Here we have an image showing how the application looks like once you Start Reading the analog input from
the Arduino, the Chart is populated with the ADC data coming over the Serial Port.