24 Ekim 2012 Çarşamba

Serial Communications and Arduino



Part 1 – Graphical User Interfaces

Smiley’s Workshop 18: Serial Communications Part 1 – Graphical User Interfaces

Joe Pardue November 9, 2009
clip_image002
Figure 1: A Simple Terminal

Recap

Last month we finished with our introduction to the Arduino Projects Kits (available from  Smiley Micros webshop) and used all the parts to do some interesting things. This month we will start to look a bit deeper into communicating between the Arduino and a PC. We will begin a three part series about serial communications between a PC and a microcontroller. In the first part we will learn a bit about the virtual serial port used in the Arduino and introduce writing programs on the PC using the free Microsoft C# and Visual Basic Express .NET applications and use this to build Graphical User Interfaces. In the second part, next month, we will apply this knowledge to build a Simple Terminal program. And the month after that, in the third part we will build a GUI for an Arduino Volt Meter.

Virtual Serial Port Introduction

Why Imitate a PC Serial Port with USB?

In the olden days the PC serial port had Windows© driver and hardware link based on the RS232 electrical specification and used a DB-9 connector and a UART (Universal Asynchronous Receiver Transmitter). It wasn’t exactly simple for a novice PC user to hook up a serial link since it required the user to select software interrupts and set hardware jumpers – something you and I, as certifiable nerds, like to do – but something that normal people hate and tend to mess up. These and other complications led to the development of the Plug and Play initiative (more commonly and correctly known as Plug and Pray). One part of all this was to replace the serial port with USB to help simplify things, which it did for the user, but made the developer’s life (yours and mine) MUCH more complicated. USB also obsoletes lots of perfectly good serial devices and a couple of decades of knowledge of how to do robust RS232 style serial communications between PCs and external serial devices.
I’ve read the USB specification, and I’m here to testify (brother amen) that the old ComPort/UART/RS232 was a piece of cake compared to USB. I worked with USB when it first came out and my brain is worse for the wear, but fortunately some genius’s thought that they would simplify the life of not just the user but the developer by creating a transitional concept: to have an old fashioned RS232 style serial port that runs over USB. The FTDI folks call this a Virtual Communications Port (VCP). It allows legacy applications to continue to use the old microcontroller code and the windows COM port software with the USB part all tidily bound up in a black box that the developer doesn’t have to open. These transitional devices give us the best of both worlds: the ease of using the serial (COM) port and the ubiquity of using USB. The developer has the option of adding RS232 level converts to completely emulate the old way of doing things, or leaving the level converters off and outputting voltage levels directly compatible with a microcontroller’s UART. The latter is exactly what the Arduino does to allow serial communications with a PC
The FTDI chip (FT232R) used on the Arduino is the same as that used on the BBUSB that was discussed in detail in the article “The Serial Port is Dead, Long Live the Serial Port’ by yours truly in the June 2008 issue of Nuts&Volts. You can also get the book “Virtual Serial Programming Cookbook” (also by yours truly) and an associated projects kit from the Smiley Micros web shop. Much of the information in this article on using C# and VB for serial communications is derived from that book.

Why communicate with a PC?

A microcontroller is usually a small cheap black lump used to control something. The something could be the ignition timing on your car; the water temperature in your washing machine; the obnoxious tune (that you think is cute) on your cell phone; etc. etc. etc… The word ‘ubiquitous’ seems almost invented to describe the current uses of microcontrollers: they really are everywhere.
Most often the microcontroller knows how to do its job and doesn’t need any advice from you. If it does deign to accept suggestions, you usually give them via a button (snooze alarm) or touch pad (microwave oven). But some of us, mostly students, hobbyists, and developers, want to spend a lot of time in conversation with a microcontroller. This may be because we want to learn how it works, or get it to follow complex commands that aren’t easy to give with buttons, or because we are designing a complex system and we need direct access to the micro’s brains while we are trying to figure out why things aren’t working like they are supposed to. If you are one of these folks then you might see the benefit of being able to use the vast resources of a PC (if you are using Windows©, perhaps ‘half-vast’ would be more appropriate?) to carry on a conversation with a microcontroller. We will look at some things to help you to do this.

Why use C# and Visual Basic Express .NET ?

One good reason for selecting either language in Express .NET is because both are free. You like free don’t you? I decided to present the software in both C# and Visual Basic Express.NET because there are lots of folks who program in one language and think the other language is the vile realm of Hell bound heretics. However, the concepts that are being programmed are the same no matter what language is being used (religious wars aside), examples are done in both languages with the C# example shown here, and the Visual Basic example included in Workshop18.zip. Just skip over the language you don’t like.
You will find a treasure trove of free tools and learning materials at:http://www.microsoft.com/express/. You will notice that Microsoft says that both C# and Visual Basic Express are ‘easy to use’, ‘fun’, and ‘easy to learn’. Well… maybe not ‘easy’ by most of our definitions, but, C# and Visual Basic are all three of those things compared to earlier methods of creating a Graphical User Interface (GUI – pronounced gooey) to communicate with external serial devices. However, this is a little like saying a root-canal is ‘easy’ or ‘fun’ compared to thumbscrews. Ouch!
If you are entirely new at programming GUIs on Windows then I’d like to suggest that you consider using C#, since it is similar to C which is likely the language you will choose for the other side of the cable: the microcontroller, which I personally prefer for many religious reasons, including having written a book on the subject. If you are already a microcontroller BASIC fan or have used VB on a PC, then you will probably want to use the Visual Basic Express, BUT do be prepared for a lot of culture shock. The IDE shown in many following illustrations will be for C#, but the Visual Basic IDE is virtually identical, so it shouldn’t be difficult to transpose the concepts.
The Microsoft learning resources are really great and free! I already knew how to program in C# and thought I’d skim some of it as a review. Instead I went through 16 hours of free video and learned a lot (mainly that I didn’t know as much as I thought I did). For our purposes, you don’t need to view all the lessons, just the introductory materials and the parts on forms, and common controls. This is great stuff and let me repeat: it is free (shock!) What’s with all the free stuff from Microsoft; did the Tin Man get a heart? So, to the tune of Wizard of Oz: We’re off to learn C# the wonderful C# of Microsoft… OR We’re off to learn Visual Basic the wonderful Visual Basic of Microsoft… Depending on which you choose. Either way, watch for flying monkeys.
While you are off learning the preliminaries, try to keep in mind the ultimate goal: We are learning to use tools that will allow us to build GUIs on a PC that we can use to communicate with microcontrollers connected to either a real serial port or a USB Virtual Serial Port.
So dog-ear this page and go learn some stuff. See you in a day or so…
Time passes… dear reader learns…
Okay, now that you can build simple forms with textboxes and buttons you are ready to look at the Simple Terminal software source code. Pay careful attention as we go through the steps to create this program. But before we write it, lets play with the finished version to get some insight into where we are going as we later write the code.

Running the Simple Terminal

The Simple Terminal is available in two forms, first is a publish version that allows you to install and run the program on your PC. The second version is the source code that loads in Visual Studio Express .NET.
Workshop18.zip
..\Simple Terminal Application
..\Arduino Command_Demo.txt
..\SimpleTermGUI_C#_Source
..\SimpleTermGUI_VB_Source
Workshop18.zip can be downloaded from the Nuts&Volts or Smiley Micros website. Unzip Workshop18.zip and open the Simple Terminal Application directory, then click on the setup application. You will see the warning shown in Figure 2 – Yet another bogus warning. Click install if you are using Vista, cuss it out if asks you if you are sure. It should open and look like Figure 1: A Simple Terminal except that the text boxes should be empty.
clip_image004
Figure 2: Yet another bogus warning.
Click on the ‘Settings’ menu item and in the settings dialog click the COM port connected to the Arduino shown in Figure 3: Settings. In my case the only port available is COM5 – but your Arduino will probably be on a different port so click on that one. Make sure the serial port you selected shows up in the Serial Port label (‘Serial Port = COM5” – if you don’t click it then the port defaults to COM1). The Arduino Command_Demo that we will be using has a Baudrate set to 19200, which is the default for the Simple Terminal so you should now click ‘Okay’.
clip_image006
Figure 3: Settings
Next open the Arduino Command_Demo directory on your PC and then upload the Command_Demo program into the Arduino as discussed in earlier workshops (copy/paste/run). Press the reset button on the Arduino and you should see ‘Command_Demo rev. 0.02’ in the Receive text box. Finally, enter ‘cmd0!’ in the Send text box and you should see the response in the Receive box as shown in Figure 1: A Simple Terminal.
Cool… Now lets follow a recipe and cook up a Serial Terminal GUI for ourselves, shall we?

Build a PC Graphical User Interface

The Main Form

· Open C# or Visual Basic 2008 Express, they are nearly identical so all the following introduction to the IDE, though in C# Express, works equally well for either.
· From the ‘File’ menu select ‘New Project’ (Figure 4: New Project)
clip_image008
Figure 4: New Project
· In the ‘New Project’ form, highlight Windows Application and change the name to Simple Terminal and click the ‘OK’ button (Figure 5: Select Windows Application)
clip_image010
Figure 5: Select Windows Application
· The IDE should look like Figure 6: AVRStudio IDE.
clip_image012
Figure 6: AVRStudio IDE
· Take note of the various panels. We will call the central panel the ‘Editor Window’, the left panel the ‘Toolbox’, the upper right panel the ‘Solutions Explorer’, the lower right panel the ‘Properties Window’.
· In the Properties Window change the size from 300,300 to 600,380. (Figure 7: Properties)
clip_image014
Figure 7: Properties
· In the Toolbox click and hold the MenuStrip then drag and drop it on Form1.
clip_image016
Figure 8: Add MenuStrip
· Note that the specific instance menuStrip1 of the class MenuStrip appears below Form1 in the Edit Window. (Figure 9: menuStrip1)
clip_image018
Figure 9: menuStrip1
· In the Toolbox click and hold the RichTextBox then drag and drop it on Form1. (Figure 10: Add RichTestBox)
clip_image020
Figure 10: Add RichTestBox
· In the Properties Window change the richTextBox size from 100,96 to 590,136.
· In the Properties Window change the richTextBox location to 0,44.
· You may be wondering where I’m getting these funky dimensions. Well, I just used the cursor to size the items until they looked right, which you can also do, but if you want to get your Simple Terminal to look exactly like mine you’ll need to hand-input the dimensions.
· Add another richTextBox (same size), richTextBox2, below the first. Change the location to 0,209.
· From the ToolBox select ‘Label’ and drag and drop it between the MenuStrip and richTextBox1.
· In the Properties Window change ‘Text’ from label1 to Send:
· Select a second label and drop it between richTextBox1 and richTextBox2. Change the Text from label2 to Receive:
clip_image022
Figure 11: RichTextBoxes
  • BORING! Plain old gray just won’t cut it. Let’s tart this up a bit. (Figure 11: RichTextBoxes)
  • Select Form1 and in the Properties Window select BackColor and click the down arrow to show the color menu:
clip_image024
Figure 12: BackColor
  • Select Bisque.
  • In the Edit Window select the menuStrip1 and in the Properties Window select ‘BackColor’ and choose the Web color NavahoWhite. (Figure 12: BackColor)
  • Select label1 and in the Properties Window choose Font. Change Font Style to Bold and Size to 12. (Figure 13:Font)
clip_image026
Figure 13: Font
  • In the Properties Window for label1 select ForeColor and change to Web DarkGoldenrod.
  • Select Form1 and in the Properties Window change text to ‘Smiley Micros – Simple Terminal’ or some other less commercial name if you prefer.
  • Still in the Form1 Properties Window select Icon and then select ‘Smiley.ico’ (located in the \Software\Graphics\ directory).
clip_image028
Figure 14: GUI with makeup
  • Now you’ve just got to admit that a little makeup helps. (Figure 14: GUI with makeup)
  • Select the MenuStrip and highlight the ‘Type Here’ box. (Figure 15: Add menu item)
clip_image030
Figure 15: Add menu item
  • Type Settings.
  • Move your cursor to the next menu position to the right, type Open Port.
  • And in the next right type Clear. (Figure 16: Menu items)
clip_image032
Figure 16: Menu items
  • NOW SAVE YOUR WORK! (aka Save Your Butt) – Do this every time you have done enough work that you’d feel bad if you lost it. If you didn’t already know this, you will learn it the hard way like the rest of us.
  • In the Express IDE menus, select Debug and click Start Debugging. (Figure 17: Start debugging)
clip_image034
Figure 17: Start debugging
  • Whoa, look at that! You didn’t write a word of software and yet you just created a GUI for a serial terminal! Move your mouse over the menu items and notice how they change colors. This is not just pretty, but pretty useless as is. So let’s make it useful.
  • Click the debug form’s close button (the little X in the upper right).

Making the Simple Terminal GUI do something

Add functionality to the menu items

  • This is what we see in the C# Edit Window:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace WindowsApplication2
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
    }
}
  • In the IDE double click on the menuStrip1 Settings button.
  • In the Edit Window click the ‘Form1.cs [Design] tab to view the Design Editor panel. Now click the ‘Open Port’ menu item.
  • Repeat for the ‘Clear’ menu item.
  • In the Form1.cs code window you’ll see that the IDE has created three functions that will be run when you click the menu item.
  • In C# add the following text to each:
private void settingsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            MessageBox.Show("Menu item 'Settings'");
        }

        private void openPortToolStripMenuItem_Click(object sender, EventArgs e)
        {
            MessageBox.Show("Menu item 'Open Port'");
        }

        private void clearToolStripMenuItem_Click(object sender, EventArgs e)
        {
            MessageBox.Show("Menu item 'Clear'");
        }
  • Run the program in debug mode again (Debug/Start Debugging)
  • Click the ‘Settings’ menu item.
clip_image036
Figure 18: Click the Settings menu item
  • Likewise test the ‘Open Port’ and ‘Clear’ menu items.
  • Close the debug form.
  • Select Form1.cs and change the Clear menu function to:
  • In C# add:
        private void clearToolStripMenuItem_Click(object sender, EventArgs e)
        {
            richTextBox1.Text = "";
            richTextBox2.Text = "";
        }
  • This will cause the text in the rich text boxes to be cleared.
  • Run the program in Debug mode and type some text in each richTextBox then click the Clear menu item to see it work.
  • The source code is in the \Software\Chapter 4 – Simple Terminal GUI \ directory
If you are anxious to get a jump start on next month’s article, you can get the details for building the Simple Terminal in the free first six chapters of ‘Virtual Serial Port Cookbook’from www.smileymicros.com, or if you find yourself interested in the FTDI FT232R chip used in the Arduino for serial communications then you can purchase the book and a projects kit from Nuts&Volt or Smiley Micros. I will start a thread on www.avrfreaks.net titled ‘Smiley’s Simple Terminal ‘and I’ll try to check by several times a week to see if there are any questions.
In this workshop we went thru the Microsoft tutorials and learned just enough to be dangerous. We built the GUI for a Simple Terminal. In the next workshop we will build a dialog form (Settings) to get data from the user for selecting a serial port and setting up the UART. We will then learn to use the Serial Port Class, and finally we will build an Arduino Volt Meter that displays output on a PC.

The Arduino Projects Kit:

Smiley Micros and Nuts&Volts are selling a special kit: The Arduino Projects Kit. Beginning with Workshops 9 we started learning simple ways to use these components, and in later Workshops we will use them to drill down into the deeper concepts of C programming, AVR microcontroller architecture, and embedded systems principles.
With the components in this kit you can:
· Blink 8 LEDs (Cylon Eyes)
· Read a pushbutton and 8-bit DIP switch
· Sense Voltage, Light, and Temperature
· Make Music on a piezo element
· Sense edges and gray levels
· Optically isolate voltages
· Fade LED with PWM
· Control Motor Speed
· And more…
NOTE: The source code is in the file: Workshop 18

Part 2 – A Simple Terminal

Smiley’s Workshop 19: Serial Communications Part 2 – A Simple Terminal

Joe Pardue December 7, 2009
NOTE: the code is improperly formatted in this blog so I suggest you skim over it and look at the code in the file: Workshop 19

Recap

Last month we introduced to serial communications between a PC and an Arduino using C# or Visual Basic Express .NET (both free from http://www.microsoft.com/express/. (The article shows the C# examples, and the Visual Basic examples are in Workshop19.zip) This month we will look at selecting a serial port, getting user input, and then we will expand on all this to build a simple terminal.

Getting User Input

In this section we will create a dialog form to allow the user to select an available serial port and set the UART parameters needed for the communication link (Baudrate, Data Bits, Parity, Stop Bits, and Handshaking). To create and test the Settings dialog we will use a test form, PortSetTest, to call it. Later we will access this form by clicking the settings menu item from the Simple Terminal (and next month we will use it for a Arduino Volt Meter program).
· Open either C# Express and create a new project named PortSetTest
· Create a form to look like Figure 1: PortSet Test
clip_image002
Figure 1: PortSet Test
· The text list is made from 6 labels using the text shown.
· In the Solutions Explorer right click ‘PortSetTest’ and from the drop down menus select Add/NewItem as shown in Figure 2: Add New Item.
clip_image004
Figure 2: Add New Item
  • In the Add New Item form shown in Figure 3, highlight ‘Windows Form’, change the name to ‘PortSettings.cs’ if C# and click Add.
clip_image006
Figure 3: Add New Item Form
  • The blank form will open.
  • In the Properties Window select ‘FormBorderStyle’ and select ‘FixedDialog’. This type of form can post a DialogResult message that the calling form, in this case the Simple Terminal form, can process (don’t panic, this is all done for you and is simpler than is sounds). We will use the DialogResult to learn if the user clicked the Settings form Okay or Cancel button.
  • Now you should be able to do some stuff without a lot of hand-holding:
    • Change the form name to ‘Setting’.
    • Add the Smiley.ico icon.
    • Change the form color to Bisque.
  • Add the controls shown below:
    • The upper white box with listBoxPorts, is a listBox, which you will name listBoxPorts.
    • The control with the label ‘Baudrate’ is a ComboBox, change its name to comboBoxBaud.
  • Your Settings form should look like Figure 4: Settings Form.
clip_image008
Figure 4: Settings Form
· Add the DevInfo file to the project:
· Copy the DevInfo.cs if C# to the directory containing the PortSettings project files. You will find the DevInfo file in Workshop19.zip.
· Refer to the Add/New Item image as shown in Figure 2: Add New Item.
· Open the same menus in the Solution Explorer, but instead of selecting Add/New Item, select Add/Existing Item and select DevInfo.cs.
· Note that we are intentionally not using the SerialPort GetPortNames function for since it doesn’t work correctly. (Microsoft released a buggy funcion – hard to believe isn’t it?) We will not look at this file in detail since it contains some advanced concepts, but we will use it to get the names of the available ports. The source code is in Workshop19.zip and if you want to learn the gory details, they are contained in The Virtual Serial Port Cookbookavailable from Nuts&Volts and Smiley Micros.
· In C# add to the ‘using’ list at the top of the program:
using DevInfo;
· In C# add to the constructor:
public PortSettings()
{
InitializeComponent();
// Get a list of the Serial port names
string[] ports = GetPorts();
int i = 0;
foreach (string s in ports)
{
if (s != “”)
{
listBoxPorts.Items.Insert(i++, s);
}
}
// Set first Serial port as default
GetCOM(0);
// Initialize baudrates in combobox;
comboBoxBaud.Items.AddRange(new object[]wrap
{“75″,”110″,”134″,”150″,”300″,”600″,wrap
“1200″,”1800″,”2400″,”4800″,”7200″,”9600″,wrap
“14400″,”19200″,”38400″,”57600″,”115200″,”128000″});
// Set Handshaking selection
// We will only use these handshaking types
comboBoxHandshaking.Items.Add(“None”);
comboBoxHandshaking.Items.Add(“RTS/CTS”);
comboBoxHandshaking.Items.Add(“Xon/Xoff”);
// Set Parity types
foreach (string s in Enum.GetNames(typeof(Parity)))
{
comboBoxParity.Items.Add(s);
}
// Set Databits
// FT232R UART interface supports only 7 or 8 data bits
//comboBoxDataBits.Items.Add(“5″); // not supported
//comboBoxDataBits.Items.Add(“6″); // not supported
comboBoxDataBits.Items.Add(“7″);
comboBoxDataBits.Items.Add(“8″);
// Set Stopbits
// FT232R UART interface supports only 1 or 2 stop bits
//comboBoxStopBits.Items.Add(“None”); // not supported
comboBoxStopBits.Items.Add(“1″);
//comboBoxStopBits.Items.Add(“1.5″); // not supported
comboBoxStopBits.Items.Add(“2″);
comboBoxBaud.Text = “19200″;
comboBoxParity.Text = “None”;
comboBoxDataBits.Text = “8″;
comboBoxStopBits.Text = “1″;
comboBoxHandshaking.Text = “None”;
}
· Note the word wrap. This means that the prior line of code was too long to display so it was wrapped to the next line for the book only and not wrapped for the actual source code. We will use this as a convention throughout this book. If you enter wrap’ in your code, you’ll get an error. If you think I’m over-explaining this, you haven’t seen my email inbox.
· From the Settings Designer form click the Okay button and the Cancel buttons and then in the Settings text editor window add the following DialogResults to the functions:
· In C# add:
private void buttonOkay_Click(object sender, EventArgs e)
{
DialogResult = DialogResult.OK;
}
private void buttonCancel_Click(object sender, EventArgs e)
{
DialogResult = DialogResult.Cancel;
}
· These functions close the form and post the DialogResult message for the PortSettingsTest form, which called the Settings form.
· You may have noticed that in the source code in Workshop19.zip you will see #region and #endregion. The IDE uses #region and #endregion to show or hide code sections. When you click on the + or – to the left #region the code section collapses or expands. We use these to simplify the code visually making it easier to follow the overall code logic. Collapsing the regions looks like Figure 5: Regions.
clip_image010
Figure 5: Regions
· Create data assessors and indexChanged functions by clicking the ‘SelectedIndexChanged’ event in the events section (lightning bolt) of the Properties window.
· In C# add:
#region Data Assessors
// Data assessors and index changed functions
// FT232R UART interface supporta
// 7 or 8 data bits
// 1 or 2 stop bits
// odd / even / mark / space / no parity.
// So these will be the only options available
#region Port Name
// Assessor for the selected port name
private string SelectedPort = “”;
public string selectedPort
{
get
{
return SelectedPort;
}
set
{
SelectedPort = value;
labelPort.Text = “Selected Port = ” + SelectedPort;
}
}
#endregion
#region Baudrate
private int SelectedBaudrate;
public int selectedBaudrate
{
get
{
return SelectedBaudrate;
}
set
{
SelectedBaudrate = value;
comboBoxBaud.Text = value.ToString();
}
}
private void comboBoxBaud_SelectedIndexChanged(object sender, EventArgs e)
{
selectedBaudrate = wrap
Convert.ToInt32(comboBoxBaud.Items[comboBoxBaud.SelectedIndex]);
}
#endregion
#region Parity
private Parity SelectedParity;// = Parity.None;
public Parity selectedParity
{
get
{
return SelectedParity;
}
set
{
SelectedParity = value;
comboBoxParity.Text = value.ToString();
}
}
private void comboBoxParity_SelectedIndexChanged(object sender, EventArgs e)
{
string temp = comboBoxParity.Items[comboBoxParity.SelectedIndex].ToString();
switch (temp)
{
case “Even”:
selectedParity = Parity.Even;
break;
case “Mark”:
selectedParity = Parity.Mark;
break;
case “None”:
selectedParity = Parity.None;
break;
case “Odd”:
selectedParity = Parity.Odd;
break;
case “Space”:
selectedParity = Parity.Space;
break;
default:
selectedParity = Parity.None;
break;
}
}
#endregion
#region StopBits
private StopBits SelectedStopBits = StopBits.One;
public StopBits selectedStopBits
{
get
{
return SelectedStopBits;
}
set
{
SelectedStopBits = value;
comboBoxStopBits.Text = value.ToString();
}
}
private void comboBoxStopBits_SelectedIndexChanged(object sender, EventArgs e)
{
string temp = wrap
comboBoxStopBits.Items[comboBoxStopBits.SelectedIndex].ToString();
switch (temp)
{
case “None”:
selectedStopBits = StopBits.None;
break;
case “1″:
selectedStopBits = StopBits.One;
break;
//case “1.5″: // not supported by FT232R
//SelectedStopBits = StopBits.OnePointFive;
//break;
case “2″:
selectedStopBits = StopBits.Two;
break;
default:
selectedStopBits = StopBits.One;
break;
}
}
#endregion
#region DataBits
private int SelectedDataBits = 8;
public int selectedDataBits
{
get
{
return SelectedDataBits;
}
set
{
SelectedDataBits = value;
comboBoxDataBits.Text = value.ToString();
}
}
private void comboBoxDataBits_SelectedIndexChanged(object sender, EventArgs e)
{
if (comboBoxDataBits.SelectedIndex == 0) selectedDataBits = 7;
else selectedDataBits = 8;
}
#endregion
#region Handshaking
// We will only use None, Xon/Xoff, or Hardware (which is RTS/CTS)
private Handshake SelectedHandshaking = Handshake.None;
public Handshake selectedHandshaking
{
get
{
return SelectedHandshaking;
}
set
{
SelectedHandshaking = value;
comboBoxHandshaking.Text = value.ToString();
}
}
private void comboBoxHandshaking_SelectedIndexChanged(object sender, EventArgs e)
{
if (comboBoxHandshaking.SelectedIndex == 0) selectedHandshaking = wrap
Handshake.None;
else if (comboBoxHandshaking.SelectedIndex == 1) selectedHandshaking = wrap
Handshake.RequestToSend;
else if (comboBoxHandshaking.SelectedIndex == 2) wrap
selectedHandshaking = Handshake.XOnXOff;
else selectedHandshaking = Handshake.None;
}
#endregion
· We will test the Settings dialog by displaying the data in the PortSetTest form.
· Open Form1 (PortSettingsTest) and add the following code.
· In C# add:
public partial class Form1 : Form
{
private string portname = “Not Initialized”;
private string baudrate = “Not Initialized”;
private string parity = “Not Initialized”;
private string stopbits = “Not Initialized”;
private string databits = “Not Initialized”;
private string handshaking = “Not Initialized”;
// Instantiate the PortSettings class
PortSettings p = new PortSettings();
public Form1()
{
InitializeComponent();
}
private void clearSettings()
{
portname = “”;
baudrate = “”;
databits = “”;
stopbits = “”;
parity = “”;
handshaking = “”;
}
private void buttonTest_Click(object sender, EventArgs e)
{
if (p.ShowDialog() == DialogResult.Cancel)
{
// clear out settings
clearLabels();
}
else
{
// set labels to Settings values
setLabels();
}
}
private void clearLabels()
{
labelPortName.Text = “PortName”;
labelBaudRate.Text = “BaudRate”;
labelParity.Text = “Parity”;
labelDataBits.Text = “DataBits”;
labelStopBits.Text = “StopBits”;
labelHandShaking.Text = “HandShaking”;
}
private void setLabels()
{
labelPortName.Text = “PortName: ” + p.selectedPort;
labelBaudRate.Text = “BaudRate: ” + p.selectedBaudrate.ToString();
labelParity.Text = “Parity: ” + p.selectedParity.ToString();
labelDataBits.Text = “DataBits: ” + p.selectedDataBits.ToString();
labelStopBits.Text = “StopBits: ” + p.selectedStopBits.ToString();
labelHandShaking.Text = “HandShaking: ” + wrap
p.selectedHandshaking.ToString();
}
}
· In the IDE click the Debug menu and select the ‘start debugging’ item. You should see the blank PortSettingsTest form shown in Figure 1: PortSet Test.
· Click the Test button and you should see the Settings form as shown in Figure 6: Settings Test.
clip_image012
Figure 6: Settings Test
· The actual port names will of course (barring a stunning coincidence) be different from those shown. By highlighting and selecting the items as shown and clicking Okay, the settings will propagate back to the PortSettingTest form as shown in Figure 7: Settings Test Result.
clip_image014
Figure 7: Settings Test Result
We have covered a lot so far. In the last workshop we created a GUI for our Simple Terminal. Then in this workshop we created and tested a Settings form. You may be a bit tired of PC GUIs by now, and I have some good news. We will be able to use the Settings object in future projects by simply copying the source code to the new projects directory and using the Add/Existing Item technique shown above to get this object into our code. So the good news is: we never have to code this again! Now you see one of the values of object oriented programming. You can build and test a useful software object, then forget all about how it works and just use it like a black box.

The Serial Port Class

You may have looked at some of the uses of the Serial Port Class in the source code for the Simple Terminal from Workshop 18. You may even have had one of those ‘what the…’ moments with some of the delegate stuff. Put simply, the code that is communicating with the serial port isn’t actually running with the code for the GUIs. This concerns ‘threads’ or bits of software that are running separately in Windows (each gets a part of each second to run so that all the threads seem like they are running at the same time to the user). When you want one thread to put stuff in another thread you set a delegate that the first thread can call from the second thread. So we have to create a delegate in our GUI that allows the serial port thread to set the text in our richTextBox. Yeah, its complex, but we don’t really have to go too deep at this point just to use the serial port. This is one of those cases where cookbook coding really comes in handy and you can safely just use the source code and move on till you have time to burn out a few more brain cells and learn the details. If you get to that point you might consider the book: Virtual Serial Port Cookbook available on both Nuts&Volts and Smiley Micros.
Now that we have built and tested the portSettings class, lets add it to the GUI that we built last month and get our simple terminal communicating between the PC and the Arduino.

Bringing it all together

In Workshop 18 we built the Simple Terminal GUI, now we want to add the portSettings stuff we just built so that we can make the GUI communicate using the serial port.
· Create a new Simple Terminal directory for your work and add these files:
  • In C# from the PortSetTest C# directory copy:
    • Port Settings.cs
    • Port Settings.Designer.cs
    • Port Settings.resz
    • DevInfo.cs
  • Then paste the files into your new directory.
  • Following the Add/Existing Items instructions given earlier, add Port Settings and DevInfo to the project.
· In C# in the ‘using’ list add:
using PortSet;
Now that you have added the PortSettings and DevInfo Classes to your Simple Terminal project you are ready to use the .NET System.IO.Ports library that contains the SerialPort Class.
· Open the Form1 designer and from the Toolbox drag and drop serialPort1.
· We will set the serial port properties according to the data we enter in the Port Settings class.
· In C# add:
private void settingsToolStripMenuItem_Click(object sender, EventArgs e)
{
// Make sure the port isn’t already open
if (serialPort1.IsOpen)
{
MessageBox.Show(“The port must be closed before changing the settings.”);
return;
}
else
{
// creat an instance of the settings form
PortSettings settings = new PortSettings();
if (settings.ShowDialog() == DialogResult.OK)
{
if (settings.selectedPort != “”)
{
// set the serial port to the new settings
serialPort1.PortName = settings.selectedPort;
serialPort1.BaudRate = settings.selectedBaudrate;
serialPort1.DataBits = settings.selectedDataBits;
serialPort1.Parity = settings.selectedParity;
serialPort1.StopBits = settings.selectedStopBits;
// show the new settings in the form text line
showSettings();
}
else
{
MessageBox.Show(“Error: Settings form returned with wrap
no Serial port selected.”);
return; // bail out
}
}
else
{
MessageBox.Show(“Error: buttonSetup_Click – Settings wrap
dialog box did not return Okay.”);
return; // bail out
}
// open the port
try
{
serialPort1.Close();
serialPort1.Open();
menuStrip1.Items[1].Text = “Close Port”;
showSettings();
}
catch (System.Exception ex)
{
MessageBox.Show(“Error – setupToolStripMenuItem_Click wrap
Exception: ” + ex);
}
}
}
// show the settings in the form text line
private void showSettings()
{
this.Text = “Smiley Micros – ” +
serialPort1.PortName + ” ” +
serialPort1.BaudRate.ToString() + “,” +
serialPort1.Parity + “,” +
serialPort1.DataBits.ToString() + “,” +
serialPort1.StopBits;
if (serialPort1.IsOpen)
{
this.Text += ” – Port is open”;
}
else
{
this.Text += ” – Port is closed”;
}
}
· In the form designer click on the ‘Open Port’ menu item.
· In C# add:
private void openPortToolStripMenuItem_Click(object sender, EventArgs e)
{
try
{
if (serialPort1.IsOpen)
{
serialPort1.Close();
openPortToolStripMenuItem.Text = "Open Port";
}
else
{
serialPort1.Open();
openPortToolStripMenuItem.Text = "Close Port";
}
showSettings();
}
catch (System.Exception ex)
{
MessageBox.Show("Error - openPortToolStripMenuItem_Click Exception: wrap
" + ex);
}
}
· In the form designer select the richTextBoxSend component.
· In the properties window click the ‘KeyPress’ event and to the event handler created in C# add:
private void richTextBox1_KeyPress(object sender, KeyPressEventArgs e)
{
sendChar(e.KeyChar);
}
private void sendChar(char c)
{
char[] data = new Char[1];
data[0] = c;
try
{
serialPort1.Write(data, 0, 1);
}
catch
{
MessageBox.Show("Error: sendByte - failed to send.\nIs the port open?");
}
}
· Our receive functions use a delegate to allow the serial port read thread to write to our receive text box. This is a bit complex, so for the time being just use it as-is.
· In C# add:
#region receive functions
// We want to have the serial port thread report back data received, but to
// display that data we must create a delegate function to show the data in the
// richTextBox
// define the delegate
public delegate void SetText();
// define an instance of the delegate
SetText setText;
// create a string that will be loaded with the data received from the port
public string str = “”;
// note that this function runs in a separate thread and thus we must use a
// delegate in order to display the results in the richTextBox.
private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
// instantiate the delegate to be invoked by this thread
setText = new SetText(mySetText);
// load the data into the string
try
{
str = serialPort1.ReadExisting();
}
catch (System.Exception ex)
{
MessageBox.Show(“Error – port_DataReceived Exception: “ + ex);
}
// invoke the delegate in the MainForm thread
this.Invoke(setText);
}
// create the instance of the delegate to be used to write the received data to
// the richTextBox
public void mySetText()
{
// show the text
richTextBox2.Text += str.ToString();
moveCaretToEnd();
}
// This rigaramole is needed to keep the last received item displayed
private void richTextBoxReceive_TextChanged(object sender, System.EventArgs e)
{
moveCaretToEnd();
}
private void moveCaretToEnd()
{
richTextBox1.SelectionStart = richTextBox1.Text.Length;
richTextBox1.SelectionLength = 0;
richTextBox1.ScrollToCaret();
}



#endregion
And that will give you a working terminal program. For more details you might want to look at the free first six chapters of the Virtual Serial Port Cookbook. You can get that book and hardware projects kit from both Nuts&Volts and Smiley Micros. Next month we will use this code to create an Arduino Volt Meter that shows ADC data on the PC monitor.

The Arduino Projects Kit:

Smiley Micros and Nuts&Volts are selling a special kit: The Arduino Projects Kit. Beginning with Workshops 9 we started learning simple ways to use these components, and in later Workshops we will use them to drill down into the deeper concepts of C programming, AVR microcontroller architecture, and embedded systems principles.
With the components in this kit you can:
· Blink 8 LEDs (Cylon Eyes)
· Read a pushbutton and 8-bit DIP switch
· Sense Voltage, Light, and Temperature
· Make Music on a piezo element
· Sense edges and gray levels
· Optically isolate voltages
· Fade LED with PWM
· Control Motor Speed
· And more…
NOTE: the code is improperly formatted in this blog so I suggest you skim over it and look at the code in the file: Workshop 19

Part 3 – Arduino Volt Meter And FT232R

Smiley’s Workshop 20: Serial Communications Part 3

Joe Pardue January 18, 2010

clip_image002[4]
Figure 1: Arduino Volt Meter

Recap

This is the third and last part of our mini-series on serial communications between a PC and the Arduino. We will do two things this month. First we will use what we learned in the last two articles about C# .NET programming to build an Arduino Volt Meter that displays ADC data on the PC. Second we will introduce the FT232R device that the Arduino board uses to mediate serial communications. For this device we will learn how to use some of the extra FT232R pins, and we’ll look at how the Arduino uses this device to automatically reset the board.

Arduino Volt Meter

Using the Arduino Volt Meter

A word of warning for those who think running with scissors is a good idea. The Arduino Volt Meter hooks directly to the Arduino analog input pin0, which can measure up to 5 volts. THIS CIRCUIT IS NOT PROTECTED IN ANY WAY. It will not forgive your doing something stupid like trying to measure the voltage in the wall socket. If you survive such a Darwinian experiment, your hardware won’t and that could include the PC you’ve got your Arduino hooked up to (most USB ports are protected, but you can never be absolutely certain).

The Arduino Software

The Arduino Volt Meter running on the PC (shown in Figure 1) is communicating with the following AVR_Test program running on the Arduino:

// AVM_Test
// Joe Pardue December 17, 2009
// based on Tom Igoe's example in the
// Arduino Serial.print(data) documentation

void setup()
{
  // begin the serial communication
  Serial.begin(19200);
}

// variable to hold the analog input value
int analogValue = 0; 

void loop()
{
  // read the analog input on pin 0
  analogValue = analogRead(0);   

  // print as an ASCII-encoded decimal
  Serial.print(analogValue, DEC);

  // print a terminal newline character so the AVR Voltmeter
  // will know that it has received the full string
  Serial.print('\n');

  // delay 1 second before the next reading:
  delay(1000);
}

The PC Software

The Arduino Volt Meter (AVM) source code in C# is provided in Workshop20Source.zip and requires Visual Studio Express .NET to open and run it. [This can be downloaded from the Nuts&Volts or Smiley Micros website.]
The program is built from many of the components used for the Simple Terminal discussed last month. You access the Arduino by clicking the ‘Select Device’ menu item, which then opens the Settings dialog as shown in Figure 2.
clip_image004[4]
Figure 2: Select your Arduino
The AVM uses the .NET Serial Port control Readline() function that returns a string, which is defined as a sequence of characters terminated by the ‘\n’ character. The Arduino sends the ADC value and then a ‘\n’ character as shown in the source code so that the AVM will interpret the input as a string. The AVM will then display the ADC value in the lower text window and convert that value into a voltage that it displays as a big fake red LED display in the upper window. The voltage is calculated from the ADC value using:

// Calculate volts
myVolts = ((Double)myADC * VoltsPerADC);

Based on the constants:

static Double maxVoltage = 5.0;
static Double maxADC = 1023.0;
Double VoltsPerADC = maxVoltage / maxADC;

Voltage across resistance

Let’s use this with a circuit and play with Ohm’s Law. We put 10 of the 1K ? from the Arduino Projects Kit on the breadboard so that they are each connected in series and then connect one end of that series to +5V and the other end to the GND as shown in Figure 3: Schematic – resistors in series, and Figure 4: Layout – resistors in series. [This arrangement of resistors is called a voltage divider.] The Figures 3 and 4 show the Arduino Analog Input pin 0 attached between the third and fourth resistors closest to the +5V end.
clip_image006[4]
Figure 3: Schematic – resistors in series
clip_image008[4]
Figure 4: Layout- resistors in series
We know that Ohm’s law is Voltage (V) is equal to Current (I) times Resistance (R):
V = IR
(And if ‘we’ don’t know this already, then take my word for it.) We also know that we have 5 volts and a total of 10k ? resistance in our circuit, so we can use a little beginning algebra to calculate the unknown variable, current (I):
I = V/R
I = 5/10000 = 0.0005 Amps
0.0005 Amps is the same as 0.5 milliAmps which we will usually show as 0.5mA. So we have 0.5mA current running through each of the 10 resistors and since each resistor is 1k ? and we can solve Ohm’s Law for the voltage across each resistor:
V = IR
V = 0.0005 * 1000 = 0.5 Volts
So, theoretically, we should be able to measure the voltage between the seventh and eighth resistor above 0V and it should conform to Ohm’s Law where the total resistance of the 7 resistors is 7k ?:
V = IR
V = 0.0005 * 7000 = 3.5 Volts
I ran the Arduino Voltmeter as shown in Figure 1 and got 3.47 volts.
Okay, 3.47 isn’t equal to 3.5, but it is about as close as we can expect with a set up like this. Our resistors only claim 5% accuracy so each one can be plus or minus 50 ? and, again using Ohm’s Law we see:
R = V/I
R = 3.47/0.0005 = 6940 ?
And 6940 is actually pretty darn close since 5% of 7000 ? is 350 ?, our theoretical error, but we are only 60 ? off. Your results will vary a bit but should be within a similar range.

Building the Arduino Voltmeter in C# Express .NET

By this point in your PC-serial-GUI-development-using-C# career, and assuming you built the last two months projects, you should be able to build the Arduino Volt Meter GUI just by looking at Figure 1: Arduino Volt Meter and winging it. You may not have seen such things as how to make the textbox text white and the background black, but you should be familiar enough with our chosen tool that can figure this out for yourself, especially since you have the original source code to look at. And if you think I just threw you into the deep end, well… okay I did, so start swimming, because in the next section we are going to go off the high board.

Introducing the FT232R

clip_image010[4]
Figure 5: FT232R on the Arduino Duemilanove
As we’ve seen, the Arduino is not a single thing but a toolset that consists of, among other things: a hardware board, a PC IDE (Integrated Development Environment), and a communications link between them. Now let’s take a look at the communications hardware that intermediates between the USB on the PC and the USART on the Arduino: the FTDI FT232R.
After all this time playing with the Arduino hardware, you might not realize that the Duemilanove board has two microcontrollers on it. In addition to the general-purpose Atmel AVR ATmega328 that we’ve spending all our time on, there is a special-purpose FTDI FT232R USB UART IC (http://www.ftdichip.com/Products/FT232R.htm) that controls our serial communications between the Arduino and the PC, see Figure 5: FT232R on the Arduino Duemilanove.
I first discussed the FT232R in Nuts and Volts (before there even was a Smiley’s Workshop) in the article: ‘The Serial Port is Dead: Long Live the Serial Port’. That article discussed the concept of a Virtual Serial Port over USB, using the FTDI chip FT232R on a breadboardable PCB, the BBUSB. This powerful little device is also the basis for the book:The Virtual Serial Port Cookbook and an associated hardware projects kit available from the Smiley Micros web shop. The pins on the FT232R have at least two possible uses for each pin. Eight of the pins can be used as modem lines for converting USB to RS232 style UART signals; these pins can also be used for GPIO (General Purpose Input Output) as the 8-pin DBus. Four other pins can be used as the CBus or for special functions such as to blink LEDs when you have UART traffic as is done on the Arduino to blink the Tx and Rx LEDs. We will look at using some of the more accessible FT232R pins in both the modem and GPIO modes.
Let me repeat some praise about the Arduino: it is a really good thing for beginners that you can use it without knowing anything about the FT232R (or bootloaders, or WinAVR, or AVRDude for that matter). We however are well beyond that beginner phase and are going deeper so that we can make our system even more useful. In addition to the USB pins, there are five other pins of the FT232R that the Arduino uses when communicating with the PC, they are pin 1 TXD (transmit), pin 5 RXD (receive), pin 22 and 23 to blink the Tx and Rx LEDs, and pin 2 DTR (Data Terminal Ready). (See Figure 8: FT232RL in Arduino Schematic.) That last one may be a bit of a surprise, but it is used off-label to reset the Arduino so that you can automatically upload code from the Arduino IDE to the AVR. The DTR pin resets the AVR so that the bootloader becomes active at the same time that the Arduino IDE activates the program AVRDude to upload the code.
Okay, so why is it called DTR and not ‘reset’? Well, that is because it is actually one of 8 modem pins on the FT232R that are part of the concept of a virtual ‘RS232’ serial port from a USB. Many serial ports on microcontrollers ignore all but two of these (RxD and TxD) and a few use a couple of other pins, but it is rare to find any system that uses them all – so you’ll usually have extra pins to play with. If you read ‘The Serial Port is Dead…’ article this will all make more sense, for now, let’s just say that DTR has a long and interesting history but for our purposes it is a pin that we can use in the modem mode to toggle from the PC using old fashioned serial port commands (in our C# example we set this pin to 1 with serialPort1.DtrEnable = true; and to 0 with serialPort1.DtrEnable = false;)and thus provide a signal to the AVR reset pin that will force the AVR to jump to the bootloader so that we can upload a program.
There are also other modem pins (see Figure 6: FT232R pins on the Arduino) available on the FT232R that, with a little effort, you can get at on the Arduino board. Four of these are easy to use since they are brought out on the X3 connector shown in Figure 5. A table of these pins is shown in Figure 6: FT232R pins on the Arduino. [And FYI the pinouts for the FT232RL used by the Arduino are different from those shown in the article ‘The Serial Port is Dead…’ which uses the FT232RQ.]
clip_image012[4]
Figure 6: FT232R pins on the Arduino
clip_image014[4]
Figure 7: FT232RL pins
clip_image016
Figure 8: FT232RL in Arduino Schematic
In case this isn’t entirely clear, let me repeat: we can use some of the FT232R pins in the modem mode for off-label uses such as using DTR for resetting the Arduino, or we can use the pins for general purpose I/O. When we use them in the modem mode to communicate between the PC and the Arduino they can only be used for input or output as shown in the table, but when used in the bus mode they can be used as either input or output (but not serial communications). NOTE: YOU CAN’T USE BOTH THE MODEM AND BIT-BANG MODES AT THE SAME TIME.

Accessing the FT232R pins

Before proceeding with these experiments, I strongly suggest you remove the ATmega328 from its socket to protect it from possible damage (use a small flathead screw driver and gently pry it up a little on each end until it pops out). All of the FT232R pins can be accessed the hard way by directly attaching wires to the FT232R pins (tiny wire, microscope, fine-tipped soldering iron, patience of Job (not Steve, but the Old Testament guy)). Since we aren’t either Job, I suggest we forgo the temptation and limit ourselves to probing the pins individually as we test them. We can probe the FT232R pins using the schematic shown in Figure 9: Circuit to probe input and output. And by probe, I mean a random piece of wire as shown in Figure 10, where I use the RTS output to light up and LED.
clip_image018
Figure 9: Circuit to probe input and output
clip_image020
Figure 10: Wire to RTS controls LED

Modem Mode

Using the Pin Change Tester Application

In order to light up that LED, you’ll need some PC-side software that lets you set and clear the RTS line. I wrote a little program in C# as shown in Figure 11 that lets you toggle the output on RTS and DTR while also reading the input on the CTS, DSR, DCD, and RI lines. You will find the Pin Change Tester C# source code in the Workshop20Source.zip file. I didn’t generate this as a separate application so you will have to run it in Microsoft Visual C# Express Edition which is okay since you want to see the code anyway don’t you? Plug your Arduino into the PC USB port, then run the Pin Change Tester program. Using the Settings menu item to open the port as shown last month for the Simple Terminal.
clip_image022
Figure 11: Pin Change Test: click RTS to turn LED on or off

Bit-bang Mode

To test the FT232R pins in the bit-bang mode we will use a program that was shown in ‘The Serial Port is Dead…’ article, the Bit-bang Test. The C# source code is include in Workshop20Source.zip file, again not as an application but as a project that you can open in Visual Studio .NET Express. You can repeat the probe tests you did above, but this time each pin is not forced to be either input or output but can be used as either depending on how you set the pin in the D Bus block on the program. Click the button as shown in Figure 12 to set each pin as either input or output. If you select input then the associated LED at the bottom will become active and either light up or dim down depending on the state it is reading. If you set it for output then you can click on the on/off buttons in the middle row to turn the associated pin on or off allowing you to use your probe as shown in Figure 10 to light up an external LED. Also notice that the D0 and D1 pins are the same as the TX and RX and are brought out on the Arduino female header pins 0 and 1, so these are the easiest to access.
clip_image024
Figure 12: Bit-bang Test
COOL! I just got my first Vista BSOD (Blue Screen Of Death). I was running the Bit-Bang test code and then tried to open the same device in Developer Terminal JUST TO SEE WHAT WOULD HAPPEN. Now I know that my laptop with dozens of programs open can burn all the way down to the foundations and with a simple restart – it can survive. However, >I< almost didn’t, when my system crashed I’m sure my blood pressure went off the charts while I was waiting to see how much work I’d lost. End of story: I’d saved everything right before I did the tests with my C# programs because I had a slight fear that maybe the idiot who wrote the code (>me<) might try something dangerously stupid. Moral: before using any of >my< code make sure >you< have backed everything up, saved your recent work, have your heart medications handy, and have the time to wait for Windows to figure out how to come back from the dead.
Okay, having a BSOD is a terrible way to end a workshop, but sometimes you have to face the fact that this stuff can get weird quickly. If, however, you have come to embrace the weirdness and want to look deeper then you might want to get the Arduino Projects Kit and The Virtual Serial Port Cookbook and associated projects kit available from the Smiley Micros webshop.
Source Code: Workshop 20

Hiç yorum yok: