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.
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.
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.
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.
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.
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!).
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.
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.
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.