Satellite Dish Positioner using RTAI
Most motorised dish systems consist of an actuator arm containing a motor and a simple position-sensing mechanism with a reed-relay. As the motor rotates the relay opens and closes. By counting the number of pulses from one extreme one can establish the position of the dish.
Normally positioners consist of a pulse-counting circuit, and then some interfacing logic for the PC. My aim with this project was to let a PC do the pulse counting, however use of any multi-tasking operating system risks missing some of the pulses. There are two solutions:
1. Use interrupts, and write a kernel module to process them.
2. Use Real-time extensions to Linux.
The first option requires a Schmidt trigger for debouncing, and also that your digital IO is capable of generating interrupts, so being a purist I decided that if I had a hard real-time task I could do the debouncing programmatically, so could lose an extra component. This pushed me to spend a surprisingly long time trying to figure out what the heck real-time linux was, and how I could use it. Surprisingly, the amount of code needed was quite modest.
Linux. This should work with any distribution, but Slackware with kernel 188.8.131.52 was used for development.
RTAI. Realtime Application Interface. I've used version 3.3. Available from http://www.rtai.org
PC with serial port. 386 or higher will do.
ACME Actuator. The controlling interface should be four wires. Two of them connect to the motor, the other two across a reed relay that opens and closes as the positioner extends or retracts. Some actuators have 6 wires: I have no idea how you interface to these.
A 12v power supply. I'm using an ATX supply from an expired PC. AT PSUs usually go for a few quid on ebay. You could use the PSU rails from the controlling PC, but that might be risky as the actuator draws 2.5amps, it's an inductive load and it's not constant.
A 2-channel relay control board. You could make your own, or buy one off Ebay as I did (cost was about 5 pounds).
Some electronic components (as detailed in the circuit diagrams below). All of them are available from Farnell (http://www.farnell.co.uk).
Preparing the PC system
Install your favourite Linux Distribution (Slackware 10.2 was mine).
Update the kernel to 184.108.40.206 (latest supported by rtai)
tar xvf linux-220.127.116.11.tar.bz2
ln -s linux-18.104.22.168 linux
Get RTAI. I used version 3.3. On the RTAI page you'll see a lot of stuff you don't understand. Don't worry. Go and get the tarball and unpack it, because installation is quite simple.
Apply the RTAI HAL patch to the kernel source. You'll find it in one of the subfolders
patch -p1 < /usr/src/rtai-3.3/base/arch/i386/patches/hal<version>patch
For <version> substitute the closest match to your kernel, but be careful because the minor-minor version (2.6.15.XXX) can be different but not the minor version (2.6.XXX.5), or it probably won't work.
Compile and install the new kernel (reboot)
Compile and install RTAI
Load the RTAI modules if they're not already
In my case 'lsmod' gives
Module Size Used by
rtai_fifos 26540 0
rtai_usi 992 0
rtai_lxrt 76344 1 rtai_fifos
rtai_hal 24248 2 rtai_fifos,rtai_lxrt
Actuator Power Supply
I found quite a good link on converting an ATX PSU for use outside a computer. I followed this to get myself 12 volts for driving the positioner motor. Because my relay control board was 6 volts, I went between the 5v and 12v rails to get 7v for the board (close enough to 6v). Switching PSUs don't like this kind of abuse at the best of times, but without any load mine gave distinctly poor regulation on 12v, so I introduced some load for the 5v rail in the form of a 1watt 80 ohm resistor, and then all was well.
Pulse counting circuit
The reed relay connections are wired directly to DSR and TX of the serial port
| Serial O +12v
| port |
| D1 |
| DTR O---------:>|-----\| R1
| RTS O---------:>|-----/ |
| D2 |
| DSR O---------------------------------------O------O
| To Reed Relay
| TX O----------------------------------------------O
TX is normally at -12v when not sending data. When DTR or RTS are brought high, current flows through R1. This results in DSR being pulled high (+12v). When the reed relay is shorted, however, TX asserts -12v on the DSR line. So long as either DTR or RTS are high there is power for the pulse counting circuit, and DSR reflects the state of the reed relay. DTR and RTS supply the control signals for the motor, and since the motor has only three states (driving East, driving West or stopped), we can make the logic so one of these lines is always high.
Motor Control Circuit
The motor is driven by two relays in an arrangement like this
| +12v -----O motor .O-------- +12v
| terminals /
| O------O O-------O
| 0v -----O' O-------- 0v
| RELAY1 RELAY2
(In this example state the motor would be on). The relay driving circuit gets superimposed on top of the pulse counting one, it's just easier to show them in separate diagrams
| D3 (OPTO) R2
| DTR O-------|<:-----------\/\/\/\-----------.
| D4 (OPTO) R3 |
| RTS O-------|<:-----------\/\/\/\-----------O----O +12v
D3 and D4 are the diode inputs of the opto isolators. If DTR is brought low current will flow through D3, causing the output of the isolator to change state. This switches one of the driver relays on, and the motor will be powered. When the dish has moved to the correct position DTR is brought high again and the motor stops. When the dish needs to be moved back in the other direction RTS is brought low and the second relay channel is activated moving the dish in the other direction.
Since the DTR and RTS between them power the +12v point, the actuator should strictly be 'halted' before being reversed to avoid spurious pulses on DSR. In practise this has not been needed.
R2 and R3 must be chosen so as to limit the current flowing through the diodes to 20mA, but in any case the serial port can provide only 10mA or so. For sensitive devices like the 6N138 3mA is plenty, so I've used 10K resistors.
Any diodes will do for D1 and D2 (apart from zeners). R1 should prevent more than 2-3mA from flowing when the reed relay closes, (10K or higher should do) or the +12v may drop and insufficient power be available for motor control.
A 6N138 was used for isolation but other darlington devices might be suitable (current draw of the sensing device should be no more than 3mA). The 6N138 output pins directly drive the relay module inputs. Here's what it looks like put together:
By observing the speed at which pulses were produced from the actuator, a debounce timing period of 50mS was chosen. This is the period at which DSR gets sampled. All the position sensing software has to do is count the state transitions of DSR. The software is split into two parts:
- A Daemon program written in C, running with realtime priveledges to
handle counting the pulses and setting the motor control inputs.
- A Python program issuing commands to the Daemon.
All the sources can be found attached. You will need to change act.c (the daemon) if you want to use a serial port other than COM1.
Copyright (c) firstname.lastname@example.org Feb 2006
LICENSE: You are free to do what you like with this code so long as you retain the copyright notice in derived works, either in the source code (in the case of source distributions) or in the documentation (in the case of binary distributions).