In this project, we will read the inputs from a unique, inexpensive, two-axis gravity sensor and use them to control the horizontal position of a table.
We will use this very interesting and tiny electronic gravity sensor to build a table that stays horizontal while the base of the table is disturbed (within about 20 degrees) relative to the horizon. The sensor we will use is the Memsic 2125 dual-axis accelerometer. This sensor is available from Parallax Inc. already mounted on a tiny board with 6 pins that are 0.1 inches on centers.
The following is Parallax Inc.’s information on this Memsic accelerometer:
“The Memsic 2125 is a low cost, dual-axis thermal accelerometer capable of measuring dynamic acceleration (vibration) and static acceleration (gravity) with a range of ±2 g. For integration into existing applications, the Memsic 2125 is electrically compatible with other popular accelerometers.”
Key features of the Memsic 2125 are.
Measures 0 to ± 2 g on either axis; with a surprising resolution of less than 1 mg. (This means that if you weigh 200 lb, this sensor could detect a change of 0.5 lb in your weight as affected by gravity.)
Fully temperature compensated over a 0°C to 70°C range
Simple pulse output of g-force for x and y axis
Analog output of temperature (T-Out pin)
Low current operation: less than 4 mA at 5 volts dc
A sampling of possible BASIC Stamp module applications with the Memsic 2125 include:
Dual-axis tilt sensing for autonomous robotics applications
Single-axis rotational position sensing
Movement/lack-of-movement sensing for alarm systems
R/C hobby projects such as autopilots
Memsic (www.memsic.com) provides the 2125 in a surface-mount format. Parallax mounts the circuit on a PC board providing all I/O connections so it can easily be inserted on a breadboard or through-hole prototype area.
The actuators we will use for the horizontal position correction of the table will be two radio control (R/C) hobby servos.
There are two ways we can mount the sensor to correct the tilt of the table. We can mount the sensor on the base that is being tilted or we can mount the sensor on the actual table we want to keep level. (A third way would be to correct for the tilt in one direction by sensing base tilt, and in the other direction by detecting table tilt. This is an interesting academic exercise that we will not undertake here [but you may want to play with it on your own].)
Figure 19.1 An artificial horizon–a basic unadorned cardboard horizontal table with a couple of levels and a gravity sensor. (Simple inexpensive construction is adequate for our purposes.)
If we mount the sensor on the base that will be tilting, we will get error signals that we will interpret, and then output the corrections to the target table. We may have to create a lookup table if there is any nonlinearity either in the response of the sensor or the mechanical linkages that connect the base to the top. In this case, the signal we detect is absolutely related to the position of the base. We are reading the actual error at the base. What we do with the signal is up to us, and how we design the linkages to level the table is also up to us. This is not the best way to do it in most cases, but this method may be the only one available to us in some situations.
If we mount the sensor to the top table, the signal we get will be a measure of how far the table has tilted. We can make the table come back to horizontal if we keep making an integrating correction till the table becomes horizontal; we stop when the error signal goes to zero. It is an integrative process over time. (If we wanted to know how large the correction was, we would have to keep track of how far we had moved the table to get it back to horizontal, but we do not need this information in an integrating system.)
Simply stated: it is better to mount the detector to the actual table because that is the surface we are interested in keeping level. It is best to get the error signal as directly as possible: at the source.
The instrument/controller we will create needs to read two inputs from the sensor and put out two outputs to the servos. The inputs are in the form of two frequencies we will read from the X-Out and Y-Out connectors of the sensor, and our outputs are the two 1 to 2 millisecond pulses we will output to the radio control hobby servos. See Figure 19.2.
The PBP language has a command (PULSOUT) that lets us output appropriate pulses on PORTC.0 and PORTC.1 on the LAB-X1, but in this exercise we will create our own pulses with the PAUSEUS command. However, we are still tied to PORTC.0 and PORTC.1 because that is how the circuitry for the LAB-X1 is laid out. The servo output pins on the LAB-X1 are hard wired to PORTC.0 and PORTC.1. The servos are fed from these two pins. If we were laying out a new board, we could choose to use any free port/pins.
We will use a ten-pin connector P2 on the LAB-X1 for all our connections because that is the connector that has PORTC.0 and PORTC.1 on it. This will allow us to use PORTC.2 and PORTC.3 as the inputs from the gravity sensor and so all the connections can be on one four-pin cable. The servos can plug into the standard servo connectors at J7 and J8. The circuitry for this is shown in Figure 19.2.
First, let’s write a program to get a feel for what kind of pulses we are going to be getting from the Memsic sensor (we are interested in the pulse width, the frequency, and the range). To do this, we need to read the pulses from just one of the outputs and display them on the LCD as we move one axis though 180 degrees. Let’s arbitrarily decide on the x axis output and write a program to read it. See Program 19.1.
Figure 19.2 Wiring diagram for the stable table; connecting the Memsic accelerometer to two servos. (There are four wires between the sensor and the processor; both sides of Memsic must be grounded.)
What the literature tells us is that the output is a simple pulse output of the g-force. This is not very specific, so we will measure the length of the high portion of the pulse and the length of the low portion of the pulse. This will give us the total pulse cycle length (and the frequency, too). See Program 19.1
Program 19.1 Looking at the nature of the pulses received from the gravity sensor
CLEAR ; always start with clear
DEFINE OSC 4 ; define oscillator speed
DEFINE LCD_DREG PORTD ; define LCD connections
DEFINE LCD_DBIT 4 ; 4 bit path
DEFINE LCD_RSREG PORTE ; select reg
DEFINE LCD_RSBIT 0 ; select bit
DEFINE LCD_EREG PORTE ; enable register
DEFINE LCD_EBIT 1 ; enable bit
LOW PORTE.2 ; make low for write only
ADCON1=%00000111 ; make ports digital
PAUSE 500 ; pause for LCD startup
LCDOUT $FE, 1 ; clear the LCD
TRISB=%11111111 ; set register for PORTC
X VAR WORD ; set variable x
Y VAR WORD ; set variable y
; body of main loop
LOOP: ; start loop
PULSIN PORTB.0, 1, X ; measure pulse from Memsic
PULSIN PORTB.0, 0, Y ; measure pulse from Memsic
LCDOUT $FE, $80, DEC5 X,” “,DEC5 Y, “ P Width” ; print
; conditions
LCDOUT $FE, $C0, DEC5 X + Y, “ Total” ; print conditions
PAUSE 50 ; pause 1/20 seconds
GOTO LOOP ; back to loop
END ; always end with end
Surprise, surprise! The Memsic puts out a fixed frequency pulse with a variable duty cycle. Not exactly what you might expect from the information on the box the sensor comes in. On my sensor, I received a wavelength of almost exactly 1000 units (999 to 1001). Since I have the LAB-X1 set to 4 MHz, the resolution of the system is 10 μsec, and it gives a total cycle time of each cycle of 10,000 μsec, which is a frequency of 100 Hz. There is an important lesson in this: always check it out for yourself, because the instructions can be confusing.
The high side of the cycle varied from 380 to 620 units, or 500 + or − 120 units, as I moved the sensor around through 180 degrees.
The servos we are using require a center position pulse of 1520 μsec bracketed with a range of + or − 750 μsec. (You have to check this for your specific servos.)
The equation for converting what we read into what the servos need will be as follows:
Output pulse length = 1520 + (reading – 500)*5
We can implement the preceding conditions with the following for single-axis operation.
SINGLE-AXIS SOFTWARE
Let’s first, as always, set up the DEFINEs for the LCD. We are using the LAB-X1 as our controller here so the standard port designations will need to be used. See Program 19.2.
Program 19.2 Program for single-axis artificial horizon
CLEAR ; always start with clear
DEFINE OSC 4 ; define oscillator speed
DEFINE LCD_DREG PORTD ; define LCD connections
DEFINE LCD_DBIT 4 ; 4 bit path
DEFINE LCD_RSREG PORTE ; select reg
DEFINE LCD_RSBIT 0 ; select bit
DEFINE LCD_EREG PORTE ; enable register
DEFINE LCD_EBIT 1 ; enable bit
LOW PORTE.2 ; make low for write only
ADCON1=7 ; make A, E ports digital
PAUSE 500 ; pause for LCD startup
X VAR WORD ; set variable x
Y VAR WORD ; set variable y
TRISB=%11111111 ; set register for PORTC
TRISC=%11111100 ; set register for PORTC
LCDOUT $FE, 1 ; clear LCD
;
LOOP: ; start loop
PULSIN PORTB.0, 1, X ; measure pulse from Memsic
PULSIN PORTB.1, 1, Y ; measure pulse from Memsic
;
LCDOUT $FE, $80, DEC4 X, “ ”, DEC4 (1520+6*(500-X)) ;
LCDOUT $FE, $C0, DEC4 Y, “ ”, DEC4 (1520+6*(500-Y)) ;
;
PORTC.0 = 1 ; start servo pulse
PAUSEUS (1320+6*(500-X)) ; length of pulse for servo
PORTC.0 = 0 ; end pulse
;
PORTC.1 = 1 ; start servo pulse
PAUSEUS (1320+6*(500-Y)) ; length of pulse for servo
PORTC.1 = 0 ; end pulse
GOTO LOOP ; back to loop
END ; always end with end
In Program 19.2, the multiplier, 6 in the PAUSEUS command, determines the sensitivity of the response. It is multiplying what is essentially the error signal. Try changing its value to 20 and see what happens. Try 10 and try 1. Selecting the right gain for the error signal is important.
The 500 is the at rest (horizontal) reading from the Memsic on my particular sensor. There may be slight variations in the value from sensor to sensor, so we may want to add a potentiometer to the circuit wiring. That would allow us to make an adjustment (say, to always bring this value to 500). On the servo I was using, the center position was 1320 μsec. The theoretical value for this is usually stated as 1520 μsec (by Futaba). Each servo can be expected to be slightly different, and the mounting position of the servo arm/horn to the servo also affects the mechanical response we will get. Here again, we could provide a trim potentiometer to adjust this value.
The preceding exercise demonstrates the relative ease with which we can make a fairly sophisticated instrument, like an artificial horizon, when we use a PIC microcontroller as our logic engine.
This instrument could easily be modified to show how may g-forces you went through as you turned a corner in a car. In this case, the sensing axis of the sensor would have to be placed left to right across the automobile, and a multiplier would have to be adjusted to give a reasonable display on the LCD.
TWO-AXIS SOFTWARE
To make a two-servo table that keeps the table top horizontal in both directions, we have to add the code for the second servo (see Program 19.3) The LCD part of the program does not change. After that…
Program 19.3 Program for the dual-axis artificial horizon
; Set up the variables to be used
ALPHA VAR WORD ; set variable alpha
BETA VAR WORD ; second variable for second axis
; body of main loop
LOOP: ; start loop
PULSIN PORTC.2, 1, ALPHA ; measure pulse from Memsic for x
PULSIN PORTC.2, 1, BETA ; measure pulse from Memsic for x
;
LCDOUT $FE, $80, DEC4 ALPHA,” ”, DEC4 BETA, “ Memsic”
; print conditions
LCDOUT $FE, $C0, DEC4 ((5*(ALPHA-493))+1310),” Pulse to servo”
; print conditions
;
PORTC.0 = 1 ; start servo 1 pulse
PAUSEUS (1310+(5*(ALPHA-493))) ; length of pulse for servo 2
PORTC.0 = 0 ; end pulse 1
;
PORTC.1 = 1 ; start servo 2 pulse
PAUSEUS (1310+(5*(BETA-493))) ; length of pulse for servo 2
PORTC.1 = 0 ; end pulse 2
;
PAUSE 15 ; pause about 1/60 seconds
GOTO LOOP ; back to loop
END ; always end with end
The easiest way for us to build the table is to build two tables one above the other with the two controlled axes at right angles to one another. The problem is that the two axes will not be completely independent because of the mechanical interactions in a simple, and not very precise, cardboard construction. This can be taken care mathematically in the software with a lookup table or an equation depending on how well the mechanism responds to the tilt of the base. Since the correcting mechanism designed for each table setup will be different, the implementation of this will be left up to each individual constructor, but we will cover the general principals. If we put the sensors at the table surface, none of this matters because we are sensing the actual tilt of the table and this is beyond the effect of the linkages, and so on.
I think it is really important for you to actually build a table. It does not have to be anything fancy, and you will discover all kinds of things about controlling the table that just will not occur to you if you don’t have a table to play with. Though the concept is losing currency among our educators, nothing beats working with your hands and your mind. They reinforce one another. I built everything in this book many times over!
Figure 19.3 shows a picture of a table I built out of cardboard. The table components were cut out from an old cardboard box with a box knife and a pair of scissors, and then glued together with hot glue. Since our interest is in the control of the table as opposed to the table itself, a simple cardboard model lets us do what we want at minimal cost and with minimal effort. Fortunately, the slight sloppiness and inaccuracies in the construction of the table lend themselves to software corrections. My table is shown in Figures 19.3 and 19.4.
Figure 19.3 Picture of simple horizontal table and the gravity sensor; the basic table mechanism can be made out of cardboard.
Figure 19.4 Picture of the cardboard table mechanism with servos installed. (Mechanical inaccuracies will be compensated for by the software.)
The Memsic detector we are using needs four wires between the sensor and the PIC. A simple extension cable with a four-point female end can be made to fit to the high nibble of PORTC. Since we are using a relatively expensive sensor, we will not want to solder to it. Therefore, suitable slip-on connections should be provided on the sensor end also.
It is left up to you to modify the software to increase the speed with which the table returns to horizontal after the base has been moved.
1. Make a sensor to investigate the gravity changes your body experiences as you travel up and down in a commercial elevator. How do the values vary between a hydraulic elevator in a small building and a traction elevator in a tall building. Were you surprised by what you found? (Investigate both the magnitude and duration of the accelerations.)
2. Investigate the gravity changes experienced by a passenger in a car. Both sideways motion and forward motion/acceleration should be studied.