 | Level: Introductory Lewin Edwards (sysadm@zws.com), Design Engineer, Freelance
06 Sep 2005 Get an overview of some design decisions involved in configuring a secondary
processor to handle maintenance tasks on your robot submarine, and see some of the
setup code allowing the subordinate processor to interact with the main system.
The last six episodes of this series have focused closely on the Kuro Box
hardware and techniques for programming various functionality within the
PowerPC® Linux™ environment. The next few articles focus on
designing the hardware that talks to the "real stuff" on your submarine (motors,
sensors, and so forth). I'll return to the Kuro Box frequently, but the primary
focus now is on the hardware and the deeply embedded real-time code that runs on
the external microcontroller(s).
Let me forestall an obvious question here: I do not intend to publish PCB
artwork for the hardware parts of this project just yet. The reason for this is
that I'm still iterating and spinning the design -- the hardware you're reading
about here is a third-generation design that differs quite a bit from the previous
generations, and I hope it represents the final fieldable version of this project.
I really don't want to see people wasting money on prerelease board designs.
As always, I encourage you to submit suggestions and questions in the
forum
for this series. Since this is a live, work-in-progress project, your input could
make big changes!
The goals for this article are:
- To introduce the block-level E-2 system architecture.
- To design a control board based around an 8-bit microcontroller, which will
ultimately be capable of driving actuators (solenoids, steppers, and brushless
DC motors) and acquiring data from various sensors.
- As a first step in the firmware, to establish bidirectional communications
between the PowerPC host running Linux and the control board developed for Step
2.
System architecture
Over the remainder of this series, I'm going to use a lot of acronyms specific to
the E-2 project. I'm documenting these on my personal Web site (see
Resources), but the first two acronyms I'd like you to
remember are VCM (Vehicle Control Module) and SCM (Science Control Module). In the
context of this article series, the SCM is the Kuro Box, and the VCM is the small
real-time board you'll start to build in this article. Below you'll see a block
diagram of the system this series is teaching you to build. The VCM is essentially
everything that's (a) not inside the Kuro Box, and (b) not shown in pink.
Figure 1.
Block diagram of the robot submarine
The color coding in this image is as follows: tan = storage, blue = software
component, pink = power system component, yellow = actuator/output component,
green = sensor/input component. All other coloring is cosmetic.
For the purposes of this article series, I'm using a 7Ah battery pack
(specifically, two Powersonic PS-1270 12V/7Ah batteries) and a solar panel with
nominally 36W of output. This is a convenient test setup that I have on my
workbench at home; it's essentially a scale model of the Power
Architecture™ systems on the actual E-2.
 |
Sorcerer or Apprentice?
For those who are really interested, here are some more details on how this
technology is applied in my submarine project. Although the hardware you see
here is very similar to the control system in the sub, there's an important
architectural difference. In the sub, the heavy processing iron (currently an
Advantech PCM-5820 single-board x86 computer based on the AMD Geode processor)
doesn't do the navigation tasks; it is powered down almost all of the time in
order to conserve energy.
In fact, for the daylight hours, the submarine is configured in a minimum-power
mode with practically everything switched off, so that the batteries can reach
the maximum possible charge level. The actual mission is carried out at night --
the rationale for this being that underwater you'll need lights to see anything
interesting regardless of what time it is, so you may as well spend the daytime
just collecting energy.
As a result, the block diagram of the E-2 is slightly different from
what
you see in this article; it has all the same
blocks, but the GPS receiver goes directly into the ATmega32. Through a little
software and hardware cunning, a single UART on the ATmega32 services both the
GPS and the SCM. From a conceptual standpoint, the other main differences are
that all the software feedback loops (depth control, for instance) are closed
within the ATmega32, and the engineering data log (EDL) is connected directly to
that micro as well. The EDL is implemented on a standard SD or MMC card in SPI
mode.
This architectural decision, by the way, is why I don't need to worry very much
about security on the Linux side of the equation: during normal operation, the
outside world simply cannot communicate with the Linux box. The only field
communications interface during mission time is with the VCM, which is as secure
as it needs to be.
Note that there are also a couple of additional function blocks in the E-2,
designed to communicate with the device and help with recovering it if lost,
which this article series doesn't get into. These modules will eventually be
described in detail in the E-2 public information area on larwe.com; one of them
is an emergency recovery beacon similar to an aircraft flight data recorder's
"pinger," and the other is an off-the-shelf satellite transceiver.
|
|
Note: If you were planning to use these articles to build an actual
vehicle, then at this point please read the
Sorcerer or Apprentice sidebar, because it talks about
important differences between this hardware design and the actual design used in
E-2.
Design requirements
Now to get acquainted with a few of the design requirements for the board: Many
of the actuators (solenoid valves, motors, and so on) needed are most readily
available in 24V flavors, so the board should be designed to operate off a 24V
battery supply. This raises the first interesting question of how to regulate the
bus voltage down to a micro-friendly 5V.
Being a lazy sort, I'd usually take the easy way out and dump a simple linear
regulator into an application like this, but dropping 24V down to 5V is just too
big a step, as it would mean throwing away about 5W in that regulator for a
relatively modest 250mA load. Use of a switcher is therefore mandatory, and if you
refer to the schematic you'll see that I've used the dirt-cheap MC34063A in a
direct crib of its step-down application note. There is nothing at all special
about this circuit, and if you're trying to throw together a quick hack to
experiment with the code I'm talking about here, feel free to use a 7805, or just
power your board off a lab power supply. Substantial heatsinking and a TO-3
package on the regulator will be necessary if you use a 7805 with a 24V input
voltage.
Fulfilling Step 3 in the goals mentioned above requires choosing a sensible
hardware interface, and overlying software protocol, between the VCM and SCM.
There are many ways to achieve this, but the method I've chosen is an asynchronous
serial interface with RS232-compatible levels. Please note that this probably
wouldn't be the ideal choice for a real integrated application that you were
building from scratch. If you were using a bare MPC8241 part, for instance, the
right thing to do would be simply to put some 3.3V-5V level shifting in place and
connect directly to one of the MPC8241's serial ports. Unfortunately, we're
fighting the Kuro design a bit; one serial port is reserved for debug output, and
the other is connected to the supervisor/watchdog chip.
Getting a serial port
The great thing about async serial connections, however, is that they can be
plugged into almost any hardware platform on the planet. In the case of the Kuro
Box, you can either go in through the debugging serial port, or you can put a
standard level-shifter on the micro and attach it to the Kuro Box through a
USB-to-serial converter.
This discussion follows the latter route, partly because the debug port is
constantly in use by the kernel, but mostly because this way you can use the same
VCM hardware to talk to a Microsoft® Windows® machine running Cygwin,
or a regular PC running Linux, or indeed almost anything else with a standard
serial port.
I'm using a Keyspan USA-19W USB-to-serial adapter in this project, because I
happen to have it lying around; there are numerous other such adapters supported
by Linux. If you followed my instructions in
the third article
of this series,
you have a complete set of modules installed on your Kuro Box already; this
includes support for Keyspan and Belkin adapters, among others, as well as FTDI
USB-serial solutions. The only thing you need to do is to create the necessary
/dev/ttyUSB* nodes; if you unpack the sourcecode tarball for this article series,
you'll find a nested tarball called ttyusb.tar.gz. Move this into the root
directory of your Kuro and extract it; this will create all the necessary ttyUSB*
nodes for you.
Your friend, the
microcontroller
Now, I've chosen to use an Atmel Atmega32 microcontroller as the core of the VCM.
This happens to be an ideal choice for me, because I'm very comfortable with
programming this micro, it's 5V-compatible (and hence easily interfaced to all the
power electronics; it can be a bit irksome using 3.3V micros in projects like
this), and it operates over a wide temperature range. It's also supported very
well by free or low-cost hardware and software tools, and most of those tools work
within Linux. Most of the same things, except for the voltage comment, are also
true for the MSP430 series -- if you're more familiar with that microcontroller,
then you can probably port 75% of the circuit and code across without much
difficulty.
Here's a schematic of the circuit we're working with in this article. It's little
more than the microcontroller and serial interface. Also click to see
a larger version
of this schematic.
Figure 2. The
Vehicle Control Module
To flash this chip, you will need an in-system programmer such as the Atmel
AVR-ISP cable, the STK500 development board, or a third-party tool. The software
tools you'll need are gcc, binutils and the AVR runtime library, avrlibc. All of
these tools (at least the versions specified in the
Download table below) build and run perfectly under Linux,
MacOS or Cygwin. In fact, if you so desire, you can even build and run the AVR
development tools on the Kuro Box itself.
Building the AVR tools
Windows users can avoid having to compile the various components by downloading
the complete WinAVR package, also mentioned in Resources.
However, the build process is very simple:
First, build binutils. Unpack the tarball, cd into the source directory, then
execute the following commands:
Listing 1. Building binutils
./configure --target=avr --program-prefix="avr-"
make
make install
|
Now build gcc. Again, unpack the tarball, cd into the source directory, then
execute the following commands:
Listing 2. Building gcc
./configure --target=avr --program-prefix="avr-" --enable-languages=c
make
make install
|
Finally, build the avrlibc library. Unpack the tarball, cd into the source
directory, then execute the following commands:
Listing 3. Building avrlibc
./doconf
./domake
./domake install
|
You might also want to install a command-line programming utility (my makefile
uses uisp, available from the links in
Resources). However, take warning! From time to time,
Atmel changes the communication protocol used by its serial programming tools.
When you download and run a new version of AVR Studio for Windows, it will often
prompt you to update your STK500's firmware without warning you of the
consequences. One of these "flag days" occurred very recently, and it has
completely broken third-party support for the STK500. The only open-source program
I'm aware of that's currently capable of using this new STK500 protocol is the
latest beta of avrdude; older programs such as
uisp are effectively useless. If you have a working
system based on third-party tools, I advise that you never run AVR Studio
when your STK500 (or AVRISP cable) is connected.
Please also be aware that these articles won't provide you with a complete
from-the-ground-up introduction to programming the AVR; what I'm trying to
describe here is the set of specific technical challenges in my application and
how I solved them. However, I do hope that as I introduce the hardware and
firmware in bite-size chunks month by month, you'll be able to study the changes
alongside the library and chip documentation, and hence get a better understanding
of what's going on.
Building the AVR firmware
To build the firmware for the AVR side, assuming you already have avrgcc properly
installed, simply extract the source tarball for this article and run make in the
vcm_399 directory. Take a moment to examine the structure of the program. In
particular, note how the interrupt syntax works. The avrlibc library by default
vectors all the AVR interrupts to a do-nothing handler. To revector an interrupt,
rather than writing a normal function name, you use the
SIGNAL macro with an argument naming the interrupt to
be vectored -- followed immediately by the code block to be inserted. For
instance, in serial.c you'll see the serial receive interrupt declared as:
Listing 4. A signal handler
SIGNAL(SIG_USART_RECV)
{
// code goes here
}
|
WARNING: The signal name definitions are not 100% identical between different AVR
variants, and sometimes their meanings can be a little confusing. Therefore, C
code that uses interrupts is not guaranteed to be portable, even if both AVRs in
question share the interrupt-generating hardware feature you're interested in. If
your interrupts are inexplicably not firing, look at the appropriate header file
in /usr/local/avr/include/avr (assuming you used the default install location for
everything) and verify that you used the correct interrupt name for the particular
chip you're using.
Because of this potential for confusion, when you're bringing up a new design, I
strongly advise using a spare I/O as an interrupt flag. Before you start puzzling
out obscure interrupt priority questions, just do a quick sanity check -- force
your interrupts to fire, and verify on the scope that you're reaching the correct
code point.
Another interesting feature you might want to look at is the EEPROM handling code
in eeconf.c. Although nothing is stored in there yet, in the final product the
EEPROM is used for some important calibration constants (accelerometer zero
roll/pitch values, for instance). The code in eeconf.c implements a simple
checksummed redundant configuration scheme. The avrlibc library provides a
convenient framework for polled EEPROM read/write code. If you have higher
performance requirements and want to use interrupt-driven writes, you have to roll
your own.
A handy hint: To get a quick look at ROM and RAM utilization in your
avrgcc program, use
avr-objdump to look at the section headers -- in this
case, avr-objdump -h 399.elf will show you what you
need to know (look at the Size column, and ignore .stab and .stabstr, which are
symbol tables that don't get uploaded to the chip).
Efficiency, or the lack thereof
Speaking of memory, you should be aware that avrlibc isn't very efficient
size-wise. For instance, if you use printf, you'll pull
in a huge amount of code (this is a common problem in embedded systems). There are
various stripped-down printf functions you can use, or
you can simply implement by hand the bare functionality you need. Since my
application doesn't need to transmogrify much output into human-readable formats,
I chose the latter route; look at utils.c for examples of that code. (These
functions are not used in the code for this article; I just include them by way of
completeness).
If you refer to main.c and serial.c, you'll see that the device uses a very
simple packet format to communicate with its host; packets begin with
! and end with #. The VCM
transmits a version ID packet at startup, and thereafter once every three seconds
it sends a "ping" packet to show the contents of a RAM variable. The SCM can send
a packet to change the contents of that RAM variable; once it does so, the VCM
announces !VALCHANGE# and subsequent ping packets show
the updated variable.
Obviously we will add further layers of complexity to protect the integrity of
data in transit; this is just a first step at bringing up bidirectional comms
between the two devices.
In the AVR code, there is also a timer running at approximately 30Hz; this times
the periodic output packets sent by the VCM. Note the general-purpose software
timer architecture; the E-2 module needs a large number of timers for various
periodic tasks.
Talking to the microcontroller
Now take a look in the scmd directory (it stands for SCM Daemon, by the way) in
the source tarball. This is the Kuro Box side of the application. This simple
applet sets /dev/ttyUSB0 to 19200bps, 8N1, then loops infinitely. In the loop, it
waits for a valid packet to be received and displays it onscreen. After every
fourth incoming packet, the SCM sends an incremented value-update packet back to
the VCM. I'm going to ask you to take the Kuro-side serial code on faith a bit --
working with serial ports in Linux is a little irritating because you're
simultaneously dealing with the port driver and terminal interface code on top of
it.
Here's sample output from scmd talking to the VCM code
in the tarball for this article:
Listing 5. Talking to the VCM
root@KURO-BOX:~/article7/scmd# ./scmd
IBM developerWorks Kuro Box to AVR Demo Applet
Waiting for AVR to start sending...
Rx packet: "VCM V0.04"
Rx packet: "VAL=0"
Rx packet: "VAL=0"
Rx packet: "VAL=0"
Tx packet: "!A#"
Rx packet: "VALCHANGE"
Rx packet: "VAL=A"
Rx packet: "VAL=A"
Rx packet: "VAL=A"
Tx packet: "!B#"
Rx packet: "VALCHANGE"
Rx packet: "VAL=B"
Rx packet: "VAL=B"
|
With the two system modules talking to each other, world domination is only a
short step away. In the next article, you'll see how to add I/O expansion and
actuators to the VCM, and the Kuro Box will finally be able to move and wiggle
things in the real world.
Downloads
The downloads for this article are being updated. Please try to download later.
Resources Learn
Get products and technologies
- Download the sourcecode
referenced in this article from the Download table above.
The usual warning applies to Internet Explorer users -- make sure to save the file
as something.tar.gz.
- In addition the the two
AVR tools in the download table above, also
download avrlibc from
http://www.nongnu.org/avr-libc/.
- If you're using Windows
for your AVR development, download the
precompiled WinAVR from
SourceForge.
- If you'd prefer a simple
USB interface over old-style serial communications, look at
FTDI's range of
products -- as well as
selling bare interface chips, they also have ready-assemble modules that fit into
a standard DIP socket.
- Another vendor of
USB-to-serial modules
for embedded projects is Pololu. By the way, you can also use these sorts of
products to connect the Kuro Box's debugging serial port to your PC.
- The entry-level
development platform for Atmel's AVR microcontrollers is the
STK500.
The board is readily available from retailers such as Digi-Key.
-
Olimex sells inexpensive programmers and
evaluation boards for numerous micros including the AVR series (and the MSP430,
among others). Note that the circuit design I'm implementing here uses the JTAG
pins for other functions, so do not buy the AVR-JTAG or AVR-USB-JTAG devices to
work with this circuit!
- Download
datasheets for the AVR range of microcontrollers
from Atmel's Web site.
- The batteries I'm using
in this project are PowerSonic PS-1270 12V, 7Ah sealed lead-acid (or equivalents).
You can download
some basic specs
for
them. Note that the 1270 form factor is standardized; Numerous other parties offer
almost identical batteries of exactly the same dimensions.
- The solar cells we'll be
using are nominally 0.54V Voc, 6000mA Isc. An equivalent model is type 04-1192
from
Silicon Solar Inc's catalog.
Discuss
About the author  | |  | Lewin A.R.W. Edwards works for a Fortune 50 company as a wireless security/fire safety device design engineer. Prior to that, he spent five years
developing x86, ARM and PA-RISC-based networked multimedia appliances at
Digi-Frame Inc. He has extensive experience in encryption and security
software and is the author of two books on embedded systems development. |
Rate this page
|  |