Build An Arduino Voltmeter And Meet The FT232R
This will be the last part of our mini series on serial communications between a PC and the Arduino. We will do two things. First, we will use what we learned in the last two articles about C# .NET programming to build an Arduino voltmeter 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.
|FIGURE 1. Arduino voltmeter.|
Using the Arduino Voltmeter
A word of warning for those who think running with scissors is a good idea. The Arduino voltmeter hooks directly to the Arduino analog input pin 0 which can measure up to five volts. THIS CIRCUIT IS NOT PROTECTED IN ANY WAY. It will not forgive you 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 voltmeter running on the PC (shown in Figure 1) is communicating with the following AVR_Test program running on the Arduino:
// Joe Pardue December 17, 2009
// based on Tom Igoe’s example in the
// Arduino Serial.print(data) documentation
// begin the serial communication
// variable to hold the analog input value
int analogValue = 0;
// read the analog input on pin 0
analogValue = analogRead(0);
// print as an ASCII-encoded decimal
// print a terminal newline character so the AVR Voltmeter
// will know that it has received the full string
// delay 1 second before the next reading:
|FIGURE 2. Select your Arduino.|
The PC Software
The Arduino voltmeter (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 website; www.nutsvolts.com.]
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.
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. Then connect one end of that series to +5V and the other end to the GND as shown in Figure 3 and Figure 4. [This arrangement of resistors is called a voltage divider.] Figures 3 and 4 show the Arduino Analog Input pin 0 attached between the third and fourth resistors closest to the +5V end.
|FIGURE 3. Schematic - resistors in series.||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 five 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.5 mA. So, we have 0.5 mA current running through each of the 10 resistors. 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 seven 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 setup 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 projects in the last two columns, you should be able to build the Arduino voltmeter GUI just by looking at Figure 1 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 you 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.
|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. 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 have realized that the Duemilanove board has two microcontrollers on it. In addition to the general-purpose Atmel AVR ATmega328 that we’ve been spending all our time on, there is a special-purpose FTDI FT232R USB UART IC (www.ftdichip.com/Products/FT232R.htm) that controls our serial communications between the Arduino and the PC (see Figure 5).
|FIGURE 6. FT232R pins on the Arduino.|
I first discussed the FT232R in Nuts & Volts (before there even was a Smiley’s Workshop) in the Jun ‘08 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 my book The Virtual Serial Port Cookbook and an associated hardware projects kit available from Nuts & Volts.
|FIGURE 7. FT2322RL pins.|
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 RS-232 style UART signals; these pins can also be used for GPIO (General-Purpose Input Output) as the eight-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.
|FIGURE 8. FT232RL in Arduino schematic.|
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). Check out Figure 8. 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 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 eight modem pins on the FT232R that are part of the concept of a virtual RS-232 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. 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;), thus providing 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) 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. [FYI, the pinouts for the FT232RL used by the Arduino are different from those shown in the ‘Serial Port’ article which uses the FT232RQ.]
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. However, when used in the bus mode, they can either input or output (but not serial communications). NOTE: YOU CAN’T USE BOTH THE MODEM AND BIT-BANG MODES AT THE SAME TIME.
|FIGURE 9. Circuit to probe input and output.|
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. And by probe, I mean a random piece of wire as shown in Figure 10, where I use the RTS output to light up an LED.
|FIGURE 10. Wire to RTS controls LED.|
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. Use the Settings menu item to open the port as shown last month for the Simple Terminal.
|FIGURE 11. Pin Change Test: Click RTS to turn LED on or off.||FIGURE 12. Bit-bang Test.|
To test the FT232R pins in the bit-bang mode, we will once again go to the ‘Serial Port’ article and use the Bit-bang Test program. The C# source code is included in the Workshop20Source.zip file, 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 previously, but this time each pin is not forced to be an 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 will either light up or dim down, depending on the state it is reading. If you set it for output, then you can click 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.
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 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 Nuts & Volts. NV
You can find the source code and supplements for this article in Workshop19.zip in the downloads section of the Nuts & Volts website and Smiley Micros website.
The Arduino projects kit is a special hardware pack that will help you get hands on experience as you follow along with this series. It provides components for use with Workshops 9, 10, 11, and many future Workshops. Over time, we'll learn simple ways to use these components, and more importantly, use them to drill down into the deeper concepts of C programming, AVR microcontroller architecture, and embedded systems principles.
Smileys Workshop 2010-03 (Workshop20.zip)