Microcontroller Based Projects
In the dim and distant past I had an interest in electronics. But I hated
all of the messing around having to build things several times to get them to
work. My day job is as a software engineer. This means that I can have several
goes at solving a problem without all the messing around with PCBs and
soldering irons. With the advent of the cheap microcontroller I found a way to
let me do most of the real work in software (which I understand) and minimize
the hardware (which I don't!). So most of my projects have a minimum of
hardware and lots of software.
To date all of the projects have been based
upon the Microchip PIC range of microcontrollers. In particular the
16C71 is a favorite of mine (enough memory, A/D converters and
reasonably cheap!). I've mainly used these devices to support my
other hobby of radio controlled model submarines. The 16C71 is ideal
for both accepting radio control inputs, combining them with other
sensor inputs and generating new radio control outputs. Below are
details of two of my current projects the first (Neptune II) is a control module for a model
submarine dive system. The second (SPD
1) is a PWM speed
controller.
Neptune II Submarine Dive Control System

Neptune II provides control over the dive system for a model submarine. The system
I use is one based upon compressed air. A small electrically driven compressor
is used to suck the air out of the ballast tank and compress it into a storage
vessel. As the air is pumped out of the tank water enters which causes the
submarine to submerge. To surface a solenoid air valve is used to bypass the compressor
and allow the compressed air to flow back into the tank forcing out the water.
So two of the basic items to be controlled are the compressor and the valve.
Both of these operate from 12V DC and are simply turned on and off using a
power MOSFET.
One of the more difficult things to do with a model submarine is to hold
it level. This is mainly to do with a lack of visibility and the fact that when
using manual control (via the Radio control set) the tendency is to
over-compensate when the Submarines attitude changes. Most model submarines
make use of some form of automatic level or attitude control. This normally
takes the form of some sort of attitude sensor linked into automatic control of
the rear vanes. Many models use manual control of the front vanes with
automatic level control acting on the rear vanes. I like to minimize the
complexity of the model by only having moving rear vanes. This means that I
need manual control input into the rear vanes as well as automatic attitude
input.
Now we have a submarine that we can make dive and have stabilized its
attitude it seems obvious that some form of depth control would be nice to
have. In particular some help in maintaining a fixed depth (say periscope) plus
the ability to command any other depth with a simple slider would be nice.
Just to finish things off a few safety features would be nice. I've
included water sensors (for leaks), loss of signal failsafe and low battery
monitoring.
This gives the basic feature list of the controller. Below are some of
the more interesting aspects of the hardware/software design
Radio Control Inputs
The controller has three radio control inputs: Manual plane control,
Target Depth, Tank control. These three inputs are standard 1-2mS radio control
pulses. The software makes use of the 16C71 interrupt on change and the TMR0
module to measure the lengths of these pulses. The process is simplified by
measuring each in turn. The standard repeat rate for the pulses is every 20mS
thus it normally takes 60mS to sense all three. This rate is easily adequate
for this application. The length of the pulse is checked for validity and
scaled into a range of -64..+64. This range is a good trade off between
precision and easy manipulation with an 8 bit microcontroller. The controller also
detects complete loss of signal over a short period and provides failsafe
mechanisms.
Depth Sensor and Depth Control
The depth sensor is a SenSym SPX200AN 0-200kPa pressure sensor. This
sensor is now rather old and has been superceded by the SX range. However all
work in basicly the same way producing a small voltage output that is
proportional to the absolute pressure applied to the devices port. To get the
output of the device into a usable range a differential amplifier has been used
with a gain of approximately 1000. A full range device LMC6484IN (input and
output rail to rail swing) has been used which gives an output of 0-5V for a
pressure range of approximately 40" of water. The differential amplifier
has a null preset which allows the base pressure to be set for the surface. The
16C71 A/D converter is used to read this input and an average of four readings
are taken to eliminate noise. This value is scaled into the range -64..+64,
which is the same numeric range used to represent the radio control channel
values.
The controller makes use of two of the radio control inputs. One provides
the target depth and is simply subtracted from the depth value to provide and
error term (the two extremes of this input are used in special ways one
disables automatic depth control the other commands a built in periscope
depth). The channel used for tank control provides a 2nd useful input. When set
to the surface position it disables automatic depth keeping. Also if left in
the surface position for more than 20 seconds the unit assumes that the
submarine is on the surface. It then samples the depth sensor to provide a
reading of the pressure at the surface. This allows the system to compensate
for atmospheric pressure variations.
The actual depth control mechanism runs as a PI (Proportional + Integral)
control loop based upon the error term mentioned above. The integral term is
provided by periodically (every 3 seconds) pulsing the rear planes with a large
control movement if we are not yet at the desired depth. This has the effect of
nudging the submarine up or down towards the target depth while still allowing
the automatic level system to function and avoids problems with integral
wind-up. The proportional term provides small corrections once the target depth
has been reached.
Attitude Sensor and Level Control
The attitude sensor is a liquid based tilt sensor. It is actually a
two-axis device but only one axis is used in this application. Because the
device is liquid based it is not possible to use direct current with it.
Instead a pulse is used to excite the sensor (fed via a blocking capacitor) and
then the output from the sensor is read at a fixed interval after the start of
the pulse. The result is a voltage output that is proportional to the angle of
the sensor. One of the four amplifiers in the quad op-amp is used to boost the
output of the sensor (by a factor of 2) and provide manual mid-point setting
via a preset.
The controller reads the tilt sensor via one of the A/D channels. The
driving pulse is provided via one of the controllers digital I/O ports. The
sensed value is averaged over eight samples to remove noise. This value is then
combined with the manual plane control to produce an error term. The use of the
manual input in this way provides for both manual trim adjustment and manual
plane control.
The level control algorithm makes use of a PD (Proportional +
Differential) control loop based upon the error term. Testing showed that a
proportional term on its own was not sufficient to ensure stability of a fast
moving small submarine. The differential term ensures fast reaction to errors.
The differential term is calculated over a sample period of 200mS. Using a
differential term makes the process very sensitive to noise, this is reduced by
the averaging process described above. The differential term also tends to slow
response to manual control, future versions may disabled the differential term
when large amounts of manual input are in use.
Ballast Control
As described above the diving system consists of an electrically powered
compressor and electrically controlled solenoid valve. The unit operates both
of these. The actual control input from the radio control transmitter is
provided by a three position switch (surface, neutral, dive). The software
provides fine trim control by pulsing the valve/compressor for a fraction of a
second when the switch is first set. Then there is a longer gap before the
valve/compressor is operated continuously. This allows the operator to provide
very small trim adjustments by toggling the control switch.
In theory it should be possible to provide fully automatic control of the
dive system using the depth sensor and control. However so far this has not
been attempted. One of the major obstacles in developing such a system is the
very large lag between operating the vale/compressor and the actual depth of
the submarine changing.
Planes Control
The system provides control for a single set of planes (normally the rear
planes). These are operated via a standard radio control servo. The system
operates this by providing a standard 2mS radio control pulse every 20mS, again
this pulse is generated using the 16C71s TMR0 function. The length of this
pulse is proportional to the desired planes setting. It can be seen from the
above that this value is a combination of automatic depth and automatic level
control units (both of which in turn combine manual and sensor inputs). These
values are simply mixed and throw limits applied to prevent over-driving the
servo.
Source Code
The source code and circuit diagrams for Neptune II are available here.
All of these items are released under GPL. Please let me know if you make use of
any of this information.
Acknowledgments
Skip Asay ofrcboats was good enough to supply me with
a small number of the tilt sensors for use in this project. If you are
interested in buying hardware that performs a similar task to that described
above then take a look at Skip's products. The hardware described here has been
produced for my own use and is heavily tailored to my own models. Skip's
products will operate with a wide range of Submarines and come highly recommended!
I would also like to thank all of the members of the PICLIST mailing list (in
particular Andy Kunz of Montana Design) for the help and information they have
provided.
SPD-1 PWM Speed Controller

Probably everyone that plays around with both radio control models and
microcontrollers has a go at this one! Having tried various commercial speed
controllers I decided to have a go myself. My original design made use of a MOSFET
H Bridge to avoid having a reversing relay (I really hated the way you had lots
of chatter from some speed controller's reversing relay). However this seemed
to be rather over the top for the type of scale models that I build. Instead I
decided to build a controller with a reversing relay but avoiding all of the
chatter. So the basic specification got to look like this
No Relay chatter.
Soft Start.
Safe switch on (the props on Submarines can be very sharp!).
5-10A current handling.
High frequency PWM.
Failsafe on signal loss.
LED status indicator (I like flashing lights!).
Hardware
As you can see from the photograph the hardware is minimal. A MOSFET to
provide the PWM switching, a small DPDT relay for reverse operation, a driver
transistor for the relay, the all important LED and a few smoothing capacitors.
The chip I used was the PIC 16C61 (basically a 16C71 without the A/D).
Radio Control Input
When developing theNeptune II I created a set of Macros that
provide a simple timer based scheduling system. This in a slightly
updated form was the base for this project. Again I make use of TMR0
to provide the underlying timing of the system. Making use of my
preferred setup so that a standard radio control pulse is
represented by a value of -64..+64. Unlike theNeptune IIthis
project does not perform most of the capture of the R/D pulse at interrupt
time. Doing things this way caused many problems with jitter in the PWM output.
Instead the interrupt routine simply captures the value in TMR0 at the start
and end of the pulse and schedules a non-interrupt task to actually perform the
processing. As with my previous project the R/C input routines provide
detection of loss of signal and trigger a failsafe mode.
PWM Generation
I wanted as high a frequency PWM as possible without using hardware or
fast clock rates. I use a standard 4MHz part, so I decided upon a 2KHz PWM
frequency. At this frequency I found I could generate a pulse train that had a
step granularity of 8uS which gives 64 distinct steps. The smallest pulse I
could generate was 16uS in length (16 instructions to decide what to do and do
it!). The code actually performs all of the setup work outside of the main PWM
loop. This loop is the highest priority task and when called assumes that it is
partway through the longer part of the cycle. It synchronizes with TMR0 and
completes this longer phase. It then makes use of a software loop to generate
the shorter part of the cycle. When this is complete it sets things up for the
longer cycle and allows other tasks to run.
All of the other tasks run during the longer part of the cycle. These
tasks include: R/C input helper task, PWM Move generation, PWM Parameter
generation, R/C timeout and the status indicator task.
Of these tasks perhaps the most interesting is the PWM move generation.
This task's job is to read the R/C input and to change the PWM output to match
it. It is this task that provides the soft start function by providing a smooth
ramp up of the PWM output rather than a sudden jump. This task also controls
the reversing relay. Providing two switching points rather than one, thus
introducing a degree of hysteresis prevents relay chatter. A nice additional
touch is the use of a timer so that the relay is always turned off when the R/C
stick is at neutral for any length of time. The final function that is provided
by this task is to ensure that the relay is only switched when the motor is at
rest. This allows a lower rated (and smaller) relay to be used. A control input
moving from full forward to full reverse results in output from this task that
takes the PWM to zero, a small pause (to allow the motor to stop), the relay is
switched, then a smooth ramp up to full power.
The actual translation of R/C input to PWM output is done via a look up
table. This allows the power curve to be soft. In the current implementation
the curve provides a slower ramp in speed at the low to middle part of the
curve. This allows finer control at the more commonly used speeds.
Source Code
The source code and circuit diagrams for SPD-1 are available here.
All of these items are released under GPL. Please let me know if you make use of
any of this information.
|