REAL TIME SYSTEMS |
For several assignments you will control a special peripheral hardware device, which we call a "gizmo". This is a device originally designed by Jim Groh when he was a graduate student in CS, based on a description of a similar device used in a real-time programming contest. I have since seen a clock that displays the time using a mechanism very similar to this device. I constructed the actual gizmos you will be using myself, since the original ones built by Jim were variously lost or broken* years ago.
*Read and heed the section on "Care of Gizmos" near the end of this file!
The gizmo is intentionally simple, but not well behaved. In order to control it you will need to master several of the fundamental concepts in real time programming, including:
The gizmo has a bar of eight (8) discrete light emitting diodes (LEDs) attached to one end of a flat metal spring (a hacksaw blade). The other end of the blade is attached to a base, so that the blade can swing from side to side, in the form of an inverted pendulum. A pull-type solenoid is attached to the blade near the base, so that it is possible to move the blade by turning the solenoid on and off. If the solenoid power pulses are timed properly, the blade can be made to swing smoothly from side to side. On either side of the blade, just above the soloid attachment point, are two small metal spring contacts (springs from ballpoint pens). All I/O is through a data acquisition device (DAQ), which can be connected to the parallel port of a PC.
The LEDs are connected to the 8 bits of the DAQ's digital output port. The solenoid is connected to a relay that is turned on and off via the one and only analog output port of the DAQ. The two sensors are connected to the two low-order two bits of the DAQ's first 16-bit digital input port.
The control of the solenoid is just on and off (one bit). We chose to use the analog output port because it was the only output port left after we used up the digital port for controlling the LEDs. Analog voltage +5V turns on the solenoid, and voltage zero turns it off. Warning: Don't try any other voltage values! It won't vary the power of the solenoid. It will risk burning out the circuitry of the DAQ or gizmo!
You cannot directly vary the power to the solenoid, but the force with which the solenoid pulls does vary, depending on how far the slug is extended from the coil. You get a weaker pull when a small part of the slug is in the coil (when the blade is further to the right) and a stronger pull when more of the slug is in the coil (when the blade is further to the left, up to some limiting point where the slug is all the way home). Thus, when you choose the time you have the solenoid on you are also indirectly choosing how strongly it will pull.
The two bits of digital input input are connected to the two spring contacts. Since the blade carries +5 volts, the lowest order bit is turned on when there is contact between the blade and the left sensor, and the other bit indicates is turned on when there is contact between the blade and the right sensor. The possible sensor values are as follows:
The eight LEDs are in one to one correspondence with the eight discrete output bits. The value 0xFF turns on all LEDs, and the value 0x00 turns them all off.
If you push the blade by hand and look at the blade while it is swinging it will appear to blur, because it is moving faster than the latency of the human visual system. If the blade is swinging back and forth rhythmically, and you turn all the LEDs on at once (and the room lights are not too bright) you should be able to see eight amber arcs against the dark back panel of the gizmo, corresponding to the amber dashed arcs in the diagram below.
If you turn the lights on and off at the right times, precisely and consistently, you can create the illusion of any chosen pattern of lighted dashes "hanging in the air". Of course, since the frequency of the blade is not quite as high as the frame rate of a movie or television, the illusion is not quite as good. (It helps if you squint your eyes a bit.)
The objectives in controlling the gizmo are:
Keep the blade swinging smoothly, back and forth, left and right.
Turn the LEDs on and off in synchronization with the blade movement, so as to display a line of text using the eight arcs traced by the moving LEDs as raster lines.
Keeping the blade swinging smoothly is tricky. Timing is critical. Each blade has its own fundamental frequency. You need to time the soloid pulls to match this frequency, and stay in sync with the blade motion. If you leave the solenoid on too long, you will stop the blade. If you don't leave it on long enough you will not be able to swing the blade in a wide enough arc to display many characters. If you pull a the wrong time you can do all kinds of harm, including:
The latter problems are due to the complext dynamics of the blade. I've been told by a person who claims some expertise in the subject that there is no good way of directly computing the required timing from theory. To appreciate the complexity, observe that the point where the solenoid pulls on the blade is well below the center of mass. You will deform the blade when you pull on it. The shape of the deformation depends on where the blade was and how it was already flexed at the time of the pull. In simplistic terms: if the blade is flexed toward the right [like this (], a pull will add to the flex, and if the blade is flexed toward the left [like this )], a pull will create a secondary deformation (like a double S) in the blade. This is simplistic, since the movement of the blade is like a wave (wiggly/undulating). It can have components of many different frequencies and magnitudes.
In controlling the blade, you want to limit the motion, as nearly as possible, to the fundamental (lowest) harmonic frequency. All other motions can only do harm. To achieve this, you want to pull gently and briefly (once it is going, the blade will have a lot of momentum and stored spring energy) at a time when the blade is moving toward the solenoid.
To accomplish this, you will need to:
This system is similar to what electrical engineers call a phase-locked loop (e.g., see http://www.uoguelph.ca/~antoon/gadgets/pll/pll.html). (A difference is that EE's are usually controlling electrical signals, and we are controlling a physical system.) The basic idea is to use the left and right sensors to measure the actual frequency and phase of the blade's motion, and feed this back to compute minute adjustments to the time until the next turning on of the solenoid.
You need to poll the sensors repeatedly, and frequently enough that you do not miss any important changes in values. If you do, you can infer some information about the motion of the blade. Unfortunately, this inference process needs to be very tolerant of bad sensor values, for reason we will explain now.
Ideally, the left sensor should report a logic value one if and only if the blade is somewhere left of center, and the right sensor should report a logic value one if and only if the blade is somewhere right of center. Both values should be zero when the blade is in some region around the center. That is, if we view the sensor values as a pair for bits, the values should be 10 (left), 00 (center), and 10 (right), and the sequence of values should look something like this:
10...10 00...00 01...01 00...00 etc.
That is, they should conform to the regular expression ((10)+(00+)(01)+)*, and we could model the position of the blade as a finite-state machine with the following states:
Observe that the blade position at rest should be state 0. The transition to blade state 1 is due to spring action, and so is not under your direct control, but you can force the blade toward state 2 by turning on the solenoid and leaving it on for a while. How far this will deflect the blade to the left varies from one gizmo to another, depending on the stiffness of the hacksaw blade and the geometry of the linkage between the hacksaw blade and the solenoid. (You may be able to fine-tune the latter, if you are willing to play with a bent paper clip.)
Unfortunately, reality is a lot uglier than the abstract model above. The dyamics of the sensors are at least as complex as the blade. Each sensor is a coil spring. When the blade hits the spring its edged scrapes and bounces along the coils of the spring, alternately making and breaking contact, and imparting oscillatory motion to the sensor spring. You can get sequences that alternate between contact and no contact on one side, like 1000101010000010. You will also get this kind of pattern if the sensors are not exactly centered (the positions vary a bit from gizmo to gizmo) and the blade is moving through only a small arc, so that it only touches the sensor on one side. If the left sensor is swinging to the right while the right sensor is swinging to the left, you can even get the ideally "impossible" sensor value 11, indicating that both left and right sensors are making simultaneous contact. In the worst case (which should not happen unless you are swinging the blade too violently) a sensor spring may become caught and tangled behind the blade.
How can you extract useful information from these noisy sensors? Doing that creatively is part of your assignment, so I will only make a few suggestions.
You do not need to know the exact position or state of blade at all times. It will be enough if you can determine the time at which the blade reaches some reference position, for each cycle. By comparing this with the time you expected the blade to be at that point, you can determine how far out of phase the real blade is from your computational model. If the blade reaches the reference point earlier than you were expecting, you can shorten slightly the time to the next pull of the solenoid, and vice versa, to keep you. pulls in sync with the blade's motion.
Because there will always be some error in your computation of the phase, you probably do not want to work directly with the just the most recently measured data. It will probably be better if you use an average, so that you do not try to compensate for what turn out to just be random measurement errors. The principle is that such errors should average out over time. That should be true of the errors in time measurement due to the polling interval, at least. Errors due to minor oscillations in the sensor springs should also average out over time.
However, you need to limit the window over which you average, or use an exponentially weighted average, or else after the system has run a long time it will become unresponsive to phase errors.
To handle extreme cases of sensor errors, such as those due to wildly bouncing sensor springs, you may want to filter out data that is obviously. The following are a few ideas that might work:
What reference position of the blade can be determined most precisely, given the sensors may be bouncing and swinging from side to side, out of phase with the blade?
My guess is that you can get the most precise timing of the transition from the "left" state to the "right" state; that is, the reference event would be the first sensor 01 value, after a sufficiently long sequence of 10 and 00 values. You can fairly reliably infer from the long sequence of 10 and 00 values that the blade was on the left, and from the 01 value that the blade is now moving right and has moved past the midpoint. I chose the right-to-left direction, the speed will depend on the solenoid action, and the motion may be jerky. On the return cycle (driven by the spring), the motion will be more uniform.
If you write code that polls the sensors and tries to measure the time between reference events, as suggested above, you should first test it without the solenoid. Use your finger to gently push or pull on the hacksaw blade. You try you find that you can get a "feel" for when the blade is moving nicely. Look at the measurements you get. Try varying the amplitude of the swing, by pushing a bit harder for a while, and then a bit softer. Look at the timing measurements. Does the period change as the amplitude changes? If it does, you may be able to use this information as a secondary feedback loop, to keep the amplitude of your pendulum swings within a desired range. You can increase the amplitude of the swing somewhat by lengthening the interval in which the solenoid is on, and/or delaying the time of the solenoid pull (so the slug is deeper in the solenoid), subject to the limitation that you don't want the solenoid to stay on past the point where the slug is all the way home.
I know the following to be workable approaches to starting up the gizmo:
Using the hand method above, determine an initial value for the solenoid period, and just start pulling with that period. The blade will probably move moderately well, close enough for you your feedback control method to fine tune it.
Pulse the solenoid once, and let it bounce back under spring action. That is, turn the solenoid on once, for long enough to take the slug all the way home, and then immediately release it. If you are lucky in the geometry of your gizmo you may get enough measurable sensor events to make an initial estimate of the blade period, and then proceed using the feedback control as above. If this does not work you may be able to improve on the result by adusting the physical linkage (a bent paper clip) between the blade and the solenoid. If it still does not work, you can fall back to (3) below.
Try one of the methods above, and if you don't get enough measurable sensor events to make a reliable estimate of the period, wait for a human to hand-pulse the blade long enough to get the requisite number of timed events. Then, using this as the initial solenoid period, proceed using the feedback control as in the other cases.
Try (1) above, and if you don't get enough measurable sensor events to make a reliable estimate of the blade period, try varying the period (longer and shorter) until you get data from your sensors that is consistent with cyclic movement. Run the feedback control algorithm on each trial initial period value for long enough to see if it is working before you try another (random?) variation.
To poll the sensors accurately you will need a precisely timed high frequency task. It may work best to drive this directly from a timer interrupt. If you do, take care that you do not set the timer frequency to high, or you will miss interrupts and/or lose response from the keyboard.
To control the lights you will also need a precisely timed high frequency task. You may be able to drive this directly from the same timer interrupt as the sensor polling, perhaps using a divisor so that you update the LEDs every N timer interrupts. A problem with this solution is is that the time between LED updates will be uniform, but the motion of the blade will not be uniform. Near the end of each swing it slows down and becomes briefly motionless, before reversing direction. If you time the LED updates evenly your virtual pixels will be bunched together at the ends and stretched out in the middle. This will cause distortion when you are displaying characters.
Alternatively, you may be able to use a cyclic RTLinux thread with a variable time delay. If the latter does not have too much overhead, it may give you more precise control over the radial positioning of your display. The dealy between sensor updates can be computed based on the estimated position of the blade. You can use shorter delays near the middle and longer delays near the two limits of the blade motion.
Generally, the blade will move faster right to left (under solenoid power) than it moves from left to right (under spring power). Also, under solenoid power it will move irregularly, as the soleoid cuts in and out. You can compensate a bit for the left-right and right-left difference by varying your timings in each direction. To even out the timing, one student tried using the lights only in one direction. It reduced the jitter, but it cut the "refresh rate" in half, and made it much harder to see the display.
The best way to handle the irregularities due to solenoid action is to use the solenoid "gently". That is, to only turn it on for short periods of time, and to time the pulls while the slug is far enough out of the solenoid coil that the pull is not too strong. Generally, smooth and precise control of the blade motion simplifies the job of keeping down the jitter in the LED display.
Take care to power down your gizmo when it is not in use. The power switch is a push-button on the end of the black cable that is looped and tied up with the colore cables on the left side of the power supply.
Take care to leave you data acquisition module (DAQ) with all inputs in the off state when you are not actively testing code.
Do not allow the solenoid to stay on for long periods of time. It is designed for intermittent use. If you have a bug in your code, so that it leaves the solenoid in the on state, turn off the power supply to the gizmo until you have recompiled and are ready to test again.
Take care when writing code not to output a voltage other than zero or five to the analog output of the DAQ. Any voltage outside this range runs a risk of burning out a component.
You may tinker (only) with the bent paper clip link that connects the solenoid to the blade.
Do not tinker with the electronics or wiring. I have tried to insulate everything, but there is always a possibility of a short circuit, which could fry a device. If you smell something like burning or melting insulation, or see smoke, power down the gizmo, unplug the DAQ, and reoprt the problem to me immediately.
If you break a gizmo let me know right away. I will work with you to repair it, subject to my other FSU responsibilities. I do have a few spare parts. If the repair requires a new part that I do not have you will have to order the part yourself, and will have to do without the gizmo until the part comes in and the repair can be completed.
Do not steal/borrow/swap another team's gizmo, or its parts, or tinker with the gizmo of another team. That is sabotage. It will be punishable by an "F" in the course.
If you would like to build your own gizmo, you can, but you will need to get started early in the term so that it is ready when you need it. I guess the parts will cost around $200. More precisely, you will need the following:
You will need a soldering iron, and some hand tools. Anyone who is interested can talk with me for more details. I may be able to arrange for you to use some of my soldering station if you do the work in the lab at FSU.
This discussion will be continued in class. If interesting ideas comeup, and permits, this web page may be updated to summarize some points from those discussions.
© 2003 T. P. Baker. No part of this publication may be reproduced, stored in a retrieval system, or transmitted in any form or by any means without written permission. (Last updated by $Author: baker $ on $Date: 2006/08/29 13:22:26 $.) |