 | Level: Introductory Lewin Edwards (sysadm@zws.com), Design Engineer, Freelance
14 Mar 2006 From schematics to code, get a leg up on building your own robot submarine.
Building on previous successes, Lewin Edwards shows how to add more sensors to your
submarine, looking at the design requirements of different sensors and ways of
sanity checking the results they provide.
The
preceding episode of this saga
shows you how to add some I/O expansion and two stepper motors to the vehicle
control module. In this article, learn how to connect some sensors up to the
board; after all, you can't have much of a robot until your electronics have some
way of learning about the real world outside it. Below is a thumbnail version of
the schematic for the circuit we're using in this episode. Click to see a
larger version of the schematic,
or download the .zip file containing a .sch file from the
download table below. To view the .sch file, you will need the free version of
Cadsoft's EAGLE PCB/schematic CAD software (see
Resources).
Figure 1. Thumbnail schematic for
the circuit
The simplest sensor
We will start with the humblest of sensors: a simple switch. You might need a
couple of these to delimit the travel of your rudder, or if you're making
something other than a robot, maybe you want some front-panel buttons (though if
that's all you want, you can attach these to the PowerPC® in better ways).
Switches are so simple that in fact the only reason I'm bringing them into the
discussion here is so I can gently lead into a slightly more complex I2C
configuration than the circuit you met last time. I'm going to assume that these
switches will need to be read relatively infrequently (say, in the neighborhood of
50-60Hz). In keeping with the I/O usage philosophy I espoused in the last episode,
this slow rate can safely be marooned on the other side of an I2C I/O expander.
However, you might remember using up all the bits on your expander in the last
episode. How can you add another block of I/O?
A side note about I2C addressing
Fortunately, all you need to do is wire another MCP23008 onto the I2C bus. The
chip has a seven-bit I2C address; four bits of this address are fixed, and the
remaining three can be configured in your external circuit by means of external
strapping resistors on the A0, A1, and A2 lines. This allows you to connect up to
eight MCP23008s to a single I2C bus without any ugly complexities. (This is a very
common sort of arrangement on I2C peripherals, by the way -- for cost reasons,
manufacturers will very rarely bring out more than a few address pins). The
expander that drives the stepper motors is at address 0 (its full binary address
is 01000000, where the bottom bit is actually the read/write flag). We'll add a
second expander at address 1 (again, the full binary address byte for this second
chip is 01000010). The code in i2c.c handles the translation from logical address
(0-7) to physical address byte for you.
In the interest of full disclosure, if you look at the way I scan these switches,
you'll see a rather large cheat in my debouncing algorithm. I simply scan at
periodic intervals, and check for a change in input state. If there is a change,
the new data remains pending until the next scan interval. At that time, if the
change in state is still the same, the new data is latched into a status buffer.
This is not a very advanced debouncing method, but it performs adequately in lab
conditions (at least, with reasonably well-behaved switches). In
Resources, you can read a very detailed article on
debouncing techniques, accompanied by reams of actual real-world data. If you want
to implement a more advanced debouncing method, I've wired the interrupt request
line from the MCP23008 into one of the GPIOs on the microcontroller. Since this
line can be configured as an open-drain output, you can add more I/O expanders and
simply connect all their interrupt lines to the same point for a wired-AND
configuration. An external pullup is not necessary, as the ATmega32 has on-chip
pullups.
Promoting isolationist policies
One further subtlety I've added to this circuit is optical isolation of the input
lines, accomplished very easily with a standard six-pin optocoupler and a couple
of resistors. This additional circuitry serves two purposes: first, it protects
the microcontroller from outrageous external events such as miswired connectors or
electrostatic discharge, and it also provides a kind of level-shifting capability;
you can interface practically anything to the input side of the optoisolators.
You'll be very grateful of this isolation circuitry if you ever accidentally tap
an unregulated battery line onto one of the inputs; it's much easier and cheaper
to desolder an optocoupler than to replace the micro! Please note that if you want
to get the full amenity of the ESD isolation, you will need to ensure that
whatever you have outside the VCM box has a separate (or at least, isolated) power
supply from the VCM. Otherwise an ESD event on your external hardware will
propagate into the VCM through the common power rail, largely negating the benefit
of the optocouplers. Note also that the series resistor I selected for the
optocoupler LEDs is correct for a +12V external supply; you will need to tweak
this if you run the common anode line to a different voltage.
You're getting warmer
Next, you want to monitor some temperature points in the vehicle. In the real E-2
submarine, I'm interested in several temperatures -- the two drive motors have a
temperature sensor apiece, as does each battery. Another temperature sensor is
thermally connected to the external environment so I can have an idea of what the
water temperature is like. For the purposes of this article, I'll only implement
two of these sensors. I'm using the Microchip MPC9801 12-bit I2C temperature
sensor for this application; adding more measuring points is simply a matter of
mounting the sensors where you need them, and wiring them onto the I2C bus. As
with the MPC23008, there are three bits of user-configurable address; the overall
device address byte is 1001xxxR, where xxx are address pins A2 through A0, and R
is the R/W bit. Observe that there is no possibility of address collision with the
MCP23008s, no matter what A2/A0 combinations you select for either. As a matter of
interest, if you refer to the datasheet for the MCP9800 series, you'll see that
the part is also offered in a couple of flavors that are packaged in a five-pin
SOT23 (surface mount transistor) form factor. This tiny package doesn't have space
for external address select pins, so Microchip offers one flavor that's hardwired
at address 000 and another at address 101. Again, this practice is quite common
with I2C sensors.
The MCP9801 also features a thermostat mode (this option is frequently provided
on digital temperature sensor devices). This feature consists of a single
open-drain output that goes active if the sensed temperature falls outside
programmable limits, and it operates completely independently of the I2C logic, so
you can use it as a hardware fail-safe even if the microcontroller crashes.
Perhaps more importantly, you can even shut the micro down completely to save
power, and leave the temperature sensor IC running to shut things down and wake
the micro back up if unreasonable temperature excursions occur.
In the real E-2, I use the MCP9801's thermostat feature to kill charge current if
the batteries get too warm, to stop the drive and compressor motors if any of them
exceeds a nominal temperature threshold, to pause the compressor while filling the
high-pressure air bottle, and to turn off some high-intensity halogen lamps if the
temperature of the hull area surrounding the lamp's reflector rises too high (this
might indicate heavily sedimented water, but the situation I'm most concerned with
is turning on a lamp facing straight down into mud -- those lamps generate an
incredible amount of heat). Note, however, that although this feature is usually
described as a "thermostat" in other vendors' datasheets, and I use the word
freely in this text, this part is not really suited to drive a thermal load
without external intelligent assistance. The temperature alert feature, as
Microchip terms it, is designed to provide a cutoff or warning signal, rather than
an unsupervised process control input.
Coping with pressure
Next, you need to be able to sense a couple of pressures. The part I've selected
for this is a Freescale MPXH6400AC6T1, which can measure from three to 58 PSIA and
has an integrated hose barb. It is intended for automotive applications, but works
well in the moderate pressure ranges encountered in the E-2 project. Again, in the
real submarine quite a few spots need to be sampled; I'm interested in ambient
pressure as a way to gauge the vessel's depth, as well as various pressures in the
air lines leading from the high-pressure air bottle to the ballast tanks, as well
as a couple of pneumatic linear actuators. The circuit you see here only
implements two sensors, but again this can easily be extended to any number your
application might require.
Note that the MPXH6400A series is only characterized for dry air use. You can,
however, use it to measure external water pressure by using an air bubble behind a
flexible diaphragm. That phrasing sounds really scientific and technical, so I'll
freely admit that the "flexible diaphragm" in question is actually a plastic soda
bottle. I drilled a hole in the bottom and epoxied a tube into the hole. I also
glued the cap on tightly with more epoxy, after first removing the rubber seal.
This arrangement has been tested at pressures up to two atmospheres, and it would
probably withstand quite a bit more.
These pressure sensors provide analog outputs. We read them at a fairly low
sample rate using the analog-to-digital channels of the ATMega32L. Some basic
software filtering removes noise; we don't expect the values here to change very
rapidly. You can find the relevant code in main.c.
Do you have any idea
how fast you're going?
The last and most complex sensor we'll use is an Analog Devices ADXL322 MEMS
(Micro Electromechanical Systems) accelerometer. MEMS is an exciting technology
that straddles the border between "really, really small machines" and
nanotechnology. The most common MEMS devices you'll encounter in robotics work are
accelerometers and gyroscopes; various vendors including Analog Devices,
Freescale, ST, and Kionix (among others) offer these sorts of parts. (By the way,
the pressure sensor we're using above is also a MEMS device). If you browse the
Resources in depth, you'll see quite a few other very
interesting MEMS devices on the market, both sensors and actuators. I'm
particularly intrigued by the possibility of building an electric motor the
diameter of a human hair, though I can't yet think of a use for this device in any
project I'm working on.
The ADXL322 is a two-axis +/-2G accelerometer. This means that it can measure
acceleration in two dimensions, and these two dimensions are at right angles to
each other. The sensor output saturates at +/-2G. Other typical ratings for
accelerometers are +/-5G and +/-10G. Parts with higher acceleration ratings are
used in applications such as car airbags, which need to be able to discern between
high-speed and low-speed collisions.
The 2G accelerometer I'm discussing in this article is typically used for
measuring roll and pitch of a vehicle or perhaps a video game controller. For
example, you might use it in an auto-leveling circuit for a model aircraft. The
accelerometer would be mounted with one axis -- the X axis, without loss of
generality -- parallel to the stern-to-bow line of the craft, and the other axis
(Y, in this case) running from port to starboard.
Figure 2. An accelerometer
The ADXL322 provides you with two analog voltage outputs corresponding to the X
and Y acceleration vectors. When the device is parallel to the Earth's surface,
both analog outputs are mid-scale. As you tilt the device towards the X+
direction, the X output gets closer to rail voltage; tilt it back towards the X-
direction and the output heads towards 0V; similarly for the Y axis. In general,
the roll and pitch (when the sensor is mounted as described above) are given by
the relations:
Listing 1. Calculating pitch and
roll
pitch = arcsin (X)
roll = arcsin (Y)
|
where X and Y are numbers scaled from the voltage ranges provided by the chip to
a -1.0 to +1.0 scale. Due to motion or noise, X or Y can exceed 1.0; you need to
allow for this possibility.
An important point that might not immediately be obvious: A two-axis
accelerometer can only tell you your vehicle's acute angle off vertical in the X
and Y directions. It cannot completely resolve this information into a
unique vehicle orientation. Consider the following two situations, where I roll a
vehicle through 15 degrees and then through a further 150 degrees (note that these
diagrams represent a stern view of the vehicle):
Figure 3. Indistinguishable but
very different vectors
As you can see, the roll axis output is the same for both situations. The z-axis,
if I had a way to measure it, would have changed sign, but the two-axis device
simply cannot differentiate between the two possibilities.
Another point that sometimes seems very difficult to communicate is the
following: An accelerometer only measures a single acceleration vector (in this
case, I have the vector decomposed into two components; a three-axis accelerometer
would give a third component, but the net result is still a single vector).
Gravity is one component of this acceleration. Your hand pushing the device across
the table might be another. A rocket motor launching you, the table, and the
device into space would just be another component of the acceleration. You cannot
separate out these components just by looking at the output of the accelerometer.
In other words, if you have the accelerometer mounted as I describe above, the
best you can do -- even with a three-axis accelerometer -- is to obtain a single
vector that summarizes all linear acceleration forces acting on the vehicle.
Due to this fact, and also the lack of a z-dimension and the low-maximum-G sensor
being used, the circuit I'm discussing here is totally unsuitable for inertial
navigation. Building so-called "dead reckoning" inertial guidance circuits and
developing the software for them is very challenging. To establish the motion
vector of an object from a historical record of its acceleration vector, you need
to sample rapidly and (numerically) integrate over time. To calculate the net
displacement (position) of the object, you need to integrate the motion vector
again. Errors in these processes are cumulative.
The consumer application where you are most likely to encounter such circuits is
in very high-end GPS receivers. These devices try to keep track of their position
using the GPS signals as far as possible. When the satellites are temporarily
occluded (for example, when you drive into a tunnel!), the device keeps your
position up to date, with reduced accuracy, using inertial navigation.
The MEMS device is read through the Analog/Digital Converter (ADC) channels, just
like the pressure sensor. A slight nuance here is that due to impedance matching
issues, you need to use an op-amp configured as a simple voltage follower between
the sensor and the micro. You'll observe a few calibration constants in this code;
you need to calibrate the zero reference (flat on the table) and the +/-1.0G
voltages for both outputs. These constants will vary from unit to unit, due to
differences in wafer orientation of the MEMS sensor inside its packaging,
different mounting angles of the package on the PCB, and other random factors. The
usual way of calibrating these devices is with a reference platform. (A piece of
plywood with adjustable-height feet -- or, large bolts -- in each corner and a
spirit bubble on it, is an adequate reference platform). You calibrate the zero
position with the vehicle on the table; you then roll the vehicle through +/-90
degrees and pitch it through +/- 90 degrees to calibrate the range limits. You can
store the constants thus measured in EEPROM; they will be valid unless the device
is serviced and the orientation of the accelerometer with respect to the vehicle
exterior is altered.
Tune in next time
This article has covered a lot of ground with respect to data acquisition. The
next article returns primarily to the Kuro Box side of the equation to show you
how to get that data back into the PowerPC, and some of the cool things you can do
with the data thus gathered. Remember, you have a massively powerful 32-bit
processor just chomping at the bit, waiting to do something interesting.
Downloads
The downloads for this article are being updated. Please try to download later.
Resources Learn
Get products and technologies
-
Download the source code 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!
- To read the schematic
file, you will need the free version of
Cadsoft's EAGLE PCB/schematic CAD
software.
- Working by hand with
the leadless package types used for most MEMS sensors is most irksome.
Dimension
Engineering,
among others, sells accelerometers prepackaged onto handy prototyping boards.
- Download a free trial
version of
WebSphere
Application Server Version 6.0.
- Build your next
development project with
IBM
trial software,
available for download directly from developerWorks.
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
|  |