
A paper copy of this discussion consisting of 25 pages, including the figures may be obtained from the author for $2.50. In addition, we offer the various electrical parts. This is discussed in the conclusion.
(April, '99). This material is now available in the C on a PIC using the
(April, '04). PICAXE. Many of these applications have been reworked and others added for the amazingly inexpensive PICAXE-18X which costs about $10.00. These include measuring baromteric pressure using a Motorola MPX4114AP and a Microchip MCP3208 eight channel 12-bit A/D, measuring temperature using a Dallas DS18B20 or using an LM34DZ and measuring relative humidity using a Sensirion SHT-71.
Overview.
This is one discussion in a series generally related to the use of the Basic Stamp 2 in weather measurement applications. Others relate to measuring temperature, wind speed, relative humidity and rainfall. Another discusses interfacing with a SGS Thompson 24256 so as to log data to a 32K X 8 EEPROM. The idea is to provide the hobbyist with low cost documentation and inexpensive parts and allow them to use their creativity in realizing the desired system.
Introduction.
This discussion focuses on interfacing the Basic Stamp 2 with a Motorola MPX4115AP pressure sensor and a Linear LTC1298 dual channel 12-bit analog to digital converter. This provides the capability for measuring atmospheric pressure and also provides a user A/D input.
The discussion also deals with interfacing a Basic Stamp 2 with a second LTC1298 A/D which uses a 360 degree potentiometer with two wipers which are positioned 180 degrees relative to one another. This dual wiper potentiometer is used by Fascinating Electronics (FE) in their Wind Vane and the focus of the discussion is to measure wind direction. However, FE also sells the dual wiper potentiometer as a standalone unit and it might possibly be used in many rotary positioning arrangements.
Fascinating's URL is .
Analog to Digital Converter.
See Figure #1A which illustrates a Basic Stamp 2 interfacing with two LTC1298 A/D converters. Note that a separate chip select lead is devoted to each A/D, but the AD_CLK and AD_DTA leads are shared by both ICs. (Note that this could be extended to three, four or more devices with each A/D having a dedicated chip select and the CLK and DTA leads shared by all).
The following illustrates how to perform an A/D conversion on the A/D identified as AD_0.
Note that a logic one on A/D input CS0 causes AD_0 to be turned off. In this state, inputs CLK, D_OUT and output D_IN are in a high impedance state.
A measurement is initiated by bringing the CS0 lead low which resets the internal registers in the LTC1298. It is important to note that it is the negative transition on the CS lead, and thus CS must first be high and then brought low.
Note that output CS1 is high during this entire routine, disabling the second A/D AD_1.
AD0: DIRB = $F ' Make P7, P6, P5 and P4 outputs CS1 = 1 ' be sure AD_1 is off CS0 = 1 ' CS high AD_CLK = 1 ' CLK high - initial state of CLK is high CS0 = 0 ' CS low, AD_0 LTC1298 resetsThe LTC1298 is then ready to receive a four bit command from the Stamp which defines how the measurement is to be performed as shown in the following table;
Binary Hex Equiv Function 1 0 0 1 9H Differential Voltage CH0 relative to CH1 1 0 1 0 AH Differential Voltage CH1 relative to CH0 1 1 0 1 DH Voltage at CH0 relative to ground 1 1 1 1 FH Voltage at CH1 relative to ground.This command is sent to the A/D, most significant bit first by first bringing the DATA lead to the appropriate state and then clocking on the CLK lead. This is repeated for all of the four bits.
FOR J = 3 TO 0
AD_DTA_OUT = (AD_COMMAND >> J) & $1
' send bit 3, bit 2, bit 1 and bit 0
AD_CLK = 0 ' negative clock pulse
AD_CLK = 1
NEXT
A dummy clock pulse is then sent.
AD_CLK = 0 AD_CLK = 1The A/D is then in a position to send the 12-bit result to the Stamp, beginning with the most significant bit. The CLK lead is clocked and the DATA lead is read for each of the 12 bits.
AD_DTA_DIR = 0 ' make DATA_IO an input AD_BAND = 0 ' result initialized to zero FOR J = 1 TO 12 AD_CLK = 0 ' clock pulse AD_CLK = 1 AD_BAND = (AD_BAND << 1) | AD_DTA_IN NEXTFinally, the device is "unselected" by bringing the CS lead high and control is passed back to the calling program with the 12-bit result in word variable AD_BAND.
CS0 = 1 ' CS back high RETURNNote that the 4-bit command is passed to function "AD0" by the calling routine. It is $0D for a measurement of Ch0 relative to ground and $0F for Ch1 relative to ground. The output of the MPX4115AP pressure sensor is connected to Ch0 and thus command $0D is used for measuring atmospheric pressure. Command code $0F is used for measuring any voltage in the range of 0.0 to 5.0 VDC that the user may desire on Ch1 of AD_0.
A measurement may be made on the other A/D, AD_1 in a very similar manner.
AD1:
DIRB = $F
CS0 = 1 ' be sure AD0 is off
CS1 = 1
AD_CLK = 1 ' CLK high
CS1 = 0 ' CS1 low, LTC1298 resets
FOR J = 3 TO 0 ' send the command
AD_DTA_OUT = (AD_COMMAND >> J) & $1
AD_CLK = 0 ' clock pulse
AD_CLK = 1
NEXT
AD_CLK = 0 ' dummy clock pulse
AD_CLK = 1
AD_DTA_DIR = 0 ' make DATA_IO an input
AD_BAND = 0
FOR J = 1 TO 12
AD_CLK = 0
AD_CLK = 1
AD_BAND = (AD_BAND << 1) | AD_DTA_IN
NEXT
CS1 = 1 ' CS1 back high
RETURN
Note that a dedicated CS lead is used for each of the LTC1298's. However,
the clock and data leads for the two are shared. Thus, when performing a
measurement on AD_0, CS1 is always high and CS0 is used to select AD_0.
When performing a measurement on AD_1, CS0 is always high and CS1 is used
to select AD_1.
Two points.
One might argue that the similarity of the two routines AD0 and AD1is such that they might well be combined into one so as to save program memory. However, bear in mind that as it is, each routine is currently used in two modes; to measure the voltage at Ch0 and at Ch1. My fear in developing both routines AD0 and AD1 into a single routine is one of losing clarity.
Conservation of program memory is important and of course becomes critically important when you are at a point where there is not enough to accommodate your code. However, if there is enough memory, why sacrifice clarity.
The greatest concern of industry is of course, code that works and they have found that clarity is vital for debugging and maintaining code. And, after all, it is not as if your company is going to pay half the price of a Stamp if only half of the program memory is used. Rather, you pay the full $49 even if only ten bytes are used.
The second item is that I didn't use the SHIFTOUT and SHIFTIN commands. Indeed, these are very powerful commands, but they can hide the understanding and thus become difficult when attempting to understand the interface with a device which is new to the user. Once the device is understood, one may then feel confident in determining whether it is a pre clock or post clock and whether the clock is positive or negative and then map over to these commands. I don't, as I think some of the clarity is lost. If I found myself in a situation where I was out of program memory, I might take this step.
Note that with a 12-bit A/D, there are 4096 quantizing bands over the range of 0.0 to 5.0 VDC and thus each band corresponds to about 1.25 millivolts which is very small, particularly when one considers the digital switching noise associated with the Stamp and noise which may be picked up on a cable extending from the A/D to a remotely located wind vane.
There are a number of steps that one might take; terminations, shunt capacitors and running twisted pairs to the remote device and avoiding ground loops and all of these are dealt with in the following discussion.
However, one nice thing about a computer is that it works tirelessly and thus one technique is to perform many measurements, add them and then divide by the number of measurements so as to obtain an average.
In the following routine, two 16-bit words (BAND_ACCUM_HI and BAND_ACCUM_LO) are used for the summing. 256 measurements are performed and each result is added to this 32-bit accumulator. The division is then quite simply a matter of taking the low byte of BAND_ACCUM_HI and the high byte of BAND_ACCUM_LO. This concept is illustrated in Figure #1B.
MEAS_AD0: ' performs 256 conversions using AD_0
' on Channel specified by AD_COMMAND,
' $0D for Ch0, $0F for Ch1
' result is returned in AD_AVG
BAND_ACC_HI = 0
BAND_ACC_LO = 0
FOR I = 1 TO 128
GOSUB AD0
BAND_ACC_LO = BAND_ACC_LO + AD_BAND
IF (BAND_ACC_LO >= AD_BAND) THEN MEAS_AD0_1 ' no carry
BAND_ACC_HI = BAND_ACC_HI + 1 ' there was a carry
MEAS_AD0_1:
NEXT
FOR I = 1 TO 128
GOSUB AD0
IF (AD_BAND = $0FFF) THEN NOT_EQUIPPED
BAND_ACC_LO = BAND_ACC_LO + AD_BAND
IF (BAND_ACC_LO >= AD_BAND) THEN MEAS_AD0_2 ' no carry
BAND_ACC_HI = BAND_ACC_HI + 1
MEAS_AD0_2:
NEXT
AD_AVG = (BAND_ACC_HI.BYTE0 << 8) | BAND_ACC_LO.BYTE1
RETURN
Thus, the result is passed back to the calling program in AD_AVG.
One item of interest is;
FOR I=0 TO 255 ... NEXTIf variable I is a byte, this will operate as a continuous loop as once I is 255, it is incremented, which rolls it over to 0 and the whole process repeats. The designers of the Stamp implemented the FOR NEXT as initializing I to 0, performing the task and then incrementing and testing if the result is outside the defined range and if not, the program stays in the loop. The program exits the loop when the result of the increment is outside the defined range. Unfortunately, in this example, there is no value outside the defined range.
Thus, in the above routine, I opted to perform the 256 A/D conversions by first performing 128 and then performing another 128.
Note that much the same may be done with A/D AD_1 either in a separate routine, or with minor changes to the above. Note that the only difference between the two is whether routine AD0 or AD1 is called.
Atmospheric Pressure.
See Figure #2 which illustrates the connection of the MPX4115AP to A/D AD_0.
The voltage on Ch0 is calculated as;
(1) V_CH0 = AD_AVG / 4096 * V_refwhere band is the 12-bit quantity in the range of 0 through 4095 and V_ref is the nominal +5 VDC supply.
The MPX4115AP sensor outputs a voltage to Channel 0 which is proportional to pressure.
(2) V_CH0 = V_ref * (P * 0.0009 - 0.095)where P is the pressure in millibars.
Equating expressions (1) and (2)
V_ref * (P * 0.0009 - 0.095) = AD_AVG / 4096 * V_refEliminating V_ref and solving for P;
P = (AD_AVG / 4096 + 0.095) / 0.0009 or (3) P = 0.27 * AD_AVG + 105This is calculated and displayed using the Basic Stamp 2 as;
PRESS = (2*AD_AVG/10) + (7 * AD_AVG/100) + 105 DEBUG "AT millibars ", DEC PRESS, CRNote that this is in millibars.
In the United States, we use inches of mercury. One millibar corresponds to 0.02953 inches of mercury.
Thus expression (3) may be modified to calculate the pressure in inches of mercury times 100.
(4) P_in_Hg_100 = 0.797 * AD_AVG + 295This may be calculated and displayed using the Stamp as;
PRESS_Hg_100 = (7*AD_AVG/10) + (9*AD_AVG/100) + (7*AD_AVG/1000) + 295 DEBUG "AT in Hg", DEC PRESS_Hg_100/100, ".", DEC PRESS_Hg_100//100, CRDetails for calibrating this value and adjusting it for your altitude appear below.
User A/D.
Note that the use you make of this depends on your specific application. Note that the voltage at Channel 1 is calculated as;
(5) V_CH1 = AD_AVG / 4096 * V_refwhere V_ref is the value of the +5 VDC supply.
Note that the signal provided to the input of channel 1 must be in the range of 0.0 to 5.0 VDC.
Program BAROM.BS2.
This program draws together all of these points. Note that I opted to only deal with AD_0 in this routine.
' BAROM.BS2
'
' Illustrates interface with LTC1298 A/D on Stamp IO Pins 4, 5 and 6.
' Performs 256 measurements of Ch0 relative to ground, averages and
' displays atmospheric pressure in millibars and in inches of mercury
'
' Performs 256 measurments of Ch1 relative to ground, averages and
' displays user A/D.
'
' copyright, Towanda Malone, Baltimore, MD, Aug, '98
PRESS VAR WORD
PRESS_Hg_100 VAR WORD
AD_BAND VAR WORD
AD_AVG VAR WORD
BAND_ACC_HI VAR WORD
BAND_ACC_LO VAR WORD
AD_COMMAND VAR BYTE
I VAR BYTE
J VAR BYTE
CS0 VAR OUT4
CS1 VAR OUT7
AD_CLK VAR OUT5
AD_DTA_OUT VAR OUT6
AD_DTA_IN VAR IN6
AD_DTA_DIR VAR DIR6
MAIN:
AD_COMMAND = $0D ' Ch 0 relative to ground - Atmospheric Pressure
GOSUB MEAS_AD0 ' perform 256 measurements and average
IF (AD_AVG = $0FFF) THEN AT_INVALID
PRESS = (2*AD_AVG/10) + (7 * AD_AVG/100) + 105
DEBUG "AT millibars ", DEC PRESS, CR
PRESS_Hg_100 = (7*AD_AVG/10) + (9*AD_AVG/100) + (7*AD_AVG/1000) + 295
DEBUG "AT in Hg", DEC PRESS_Hg_100/100, ".", DEC PRESS_Hg_100//100, CR
GOTO MAIN_1
AT_INVALID:
NOT_EQUIPPED:
DEBUG "A/D Not Functioning", CR
MAIN_1:
PAUSE 1000
AD_COMMAND = $0F
GOSUB MEAS_AD0
IF (AD_AVG = $0FFF) THEN USER_INVALID
DEBUG "USER ", DEC AD_AVG, CR
GOTO MAIN_2
USER_INVALID:
DEBUG "A/D Not Functioning", CR
MAIN_2:
PAUSE 10000
GOTO MAIN
MEAS_AD0:
BAND_ACC_HI = 0
BAND_ACC_LO = 0
FOR I = 1 TO 128
GOSUB AD0
BAND_ACC_LO = BAND_ACC_LO + AD_BAND
IF (BAND_ACC_LO >= AD_BAND) THEN MEAS_AD0_1 ' no carry
BAND_ACC_HI = BAND_ACC_HI + 1 ' there was a carry
MEAS_AD0_1:
NEXT
FOR I = 1 TO 128
GOSUB AD0
IF (AD_BAND = $0FFF) THEN NOT_EQUIPPED
BAND_ACC_LO = BAND_ACC_LO + AD_BAND
IF (BAND_ACC_LO >= AD_BAND) THEN MEAS_AD0_2 ' no carry
BAND_ACC_HI = BAND_ACC_HI + 1
MEAS_AD0_2:
NEXT
AD_AVG = (BAND_ACC_HI.BYTE0 << 8) | BAND_ACC_LO.BYTE1
RETURN
AD0:
DIRB = $F
CS1 = 1 ' Be sure AD_1 is off
CS0 = 1 ' CS high
AD_CLK = 1 ' CLK high
CS0 = 0 ' CS low, LTC1298 resets
FOR J = 3 TO 0
AD_DTA_OUT = (AD_COMMAND >> J) & $1
AD_CLK = 0 ' clock pulse
AD_CLK = 1
NEXT
AD_CLK = 0
AD_CLK = 1
AD_DTA_DIR = 0 ' make DATA_IO an input
AD_BAND = 0
FOR J = 1 TO 12
AD_CLK = 0
AD_CLK = 1
AD_BAND = (AD_BAND << 1) | AD_DTA_IN
NEXT
CS0 = 1 ' CS back high
RETURN
Wind Direction.
See Figure #3A which illustrates the connection of the Fascinating Electronics 360 degree dual wiper potentiometer to A/D AD_1.
Note that a 100 Ohm series limiting resistor is included to protect the +5 VDC supply or even the potentiometer in the wind vane in the event the PWR lead or one of the WIPER leads is accidentally grounded.
The general theory of the operation is illustrated in Figure #3B. The wind vane element is physically connected to a potentiometer and determining the wind direction is a simple matter of measuring the voltage at the potentiometer's wipers.
Unlike most potentiometers, for example, volume controls, this potentiometer turns a full 360 degrees. Of course, there must be a point of discontinuity in the resistive material and this is commonly termed the "dead zone". Many weather equipment manufacturers "solve" this problem by suggesting you orient the potentiometer such that the wind never comes from that direction.
However, Fascinating has been very clever in using a dual wiper potentiometer where the two wipers are positioned opposite to one another. Thus, if one wiper is in the dead zone, the voltage on the other may be determined and thus the angle of the potentiometer may be calculated.
In program WIND.BS2 the voltage on Wiper #1 is measured and if it does not appear to be in the dead zone, the angle is calculated as;
Angle = AD_AVG / 4096 * 270 = 0.066 * AD_AVGThis calculation is performed by the Stamp as;
ANGLE = (6 * AD_AVG/100) + (6 * AD_AVG/1000)If however, the voltage on Wiper #1 is either close to ground or to +5 VDC or open, it is assumed the wiper is in the dead zone and the voltage on Wiper #2 is measured, the angle is calculated and 180 degrees is added.
Angle = (AD_AVG / 4096 * 270) + 180 = (0.066 * AD_AVG) + 180This calculation is performed by the Stamp as;
ANGLE = (6 * AD_AVG/100) + (6 * AD_AVG/1000) + 180 ANGLE = ANGLE // 360The last statement assures that the result is in the range of 0 to 359 degrees.
If you do use this to implement a weather station, note that when mounting the windvane on the roof or whatever, it really isn't necessary for you to get up on the ladder and have a big fight with your wife because she doesn't know how to use your STAMP2.EXE in order to align the wind vane. Rather, climb up the ladder and orient it any way that is convenient. After all, the 0 to 359 reading that this system provides is relative. The beauty of the Stamp is that you do the programming and it is an easy matter for you to add a constant in your software and then adjust to assure the angle is in the range of 0 to 359.
ANGLE = ANGLE + ANGLE_CORR ANGLE = ANGLE // 360Program WIND.BS2.
All of these concepts are implemented in the following program.
' WIND.BS2
'
' Interfaces with LTC1298 A/D on Stamp IO Pins 7, 5 an 6 to measure wind
' direction.
'
' Performs 256 measurements on Ch0 and if not in dead zone, calculates
' and displays the angle as 0.066 *AD_AVG. However, if it appears
' Wiper #1 is in the dead zone, 256 measurements are performed on Ch1
' and the angle is calculated as 0.066 * AD_AVG + 180. If both
' channels appear to be in the dead zone, as would be the case if the
' A/D or dual wiper potentiometer is not connected, an "Invalid" message
' is displayed.
'
' copyright, Towanda Malone, Baltimore, MD, Aug, '98
ANGLE VAR WORD
AD_BAND VAR WORD
AD_AVG VAR WORD
BAND_ACC_HI VAR WORD
BAND_ACC_LO VAR WORD
AD_COMMAND VAR BYTE
I VAR BYTE
J VAR BYTE
CS0 VAR OUT4
CS1 VAR OUT7
AD_CLK VAR OUT5
AD_DTA_OUT VAR OUT6
AD_DTA_IN VAR IN6
AD_DTA_DIR VAR DIR6
MAIN:
AD_COMMAND=$0D ' CH0 - Wiper #1
GOSUB MEAS_AD1
IF ((AD_AVG < $100) OR (AD_AVG > $0F00)) THEN IN_DEAD_ZONE
ANGLE = (6*AD_AVG/100)+(6*AD_AVG/1000)
' Angle = band * 270/4096
DEBUG "WD = ", DEC ANGLE, CR
GOTO MAIN_1
IN_DEAD_ZONE:
AD_COMMAND=$0F
GOSUB MEAS_AD1
IF (AD_AVG > $0F00) THEN NOT_EQUIPPED
ANGLE = 180 + (6*AD_AVG/100)+(6*AD_AVG/1000)
ANGLE = ANGLE // 360
DEBUG "WD = ", DEC ANGLE, CR
GOTO MAIN_2
NOT_EQUIPPED:
DEBUG "AD1 Not Present", CR
MAIN_2:
PAUSE 5000
GOTO MAIN
MEAS_AD1:
BAND_ACC_HI = 0
BAND_ACC_LO = 0
FOR I = 1 TO 128
GOSUB AD1
BAND_ACC_LO = BAND_ACC_LO + AD_BAND
IF (BAND_ACC_LO >= AD_BAND) THEN MEAS_AD1_1 ' no carry
BAND_ACC_HI = BAND_ACC_HI + 1 ' there was a carry
MEAS_AD1_1:
NEXT
FOR I = 1 TO 128
GOSUB AD1
BAND_ACC_LO = BAND_ACC_LO + AD_BAND
IF (BAND_ACC_LO >= AD_BAND) THEN MEAS_AD1_2 ' no carry
BAND_ACC_HI = BAND_ACC_HI + 1
MEAS_AD1_2:
NEXT
AD_AVG = (BAND_ACC_HI.BYTE0 << 8) + BAND_ACC_LO.BYTE1
' DEBUG "AD_AVG = ", DEC AD_AVG, CR
RETURN
AD1:
DIRB = $F
CS0 = 1 ' be sure AD0 is off
CS1 = 1
AD_CLK = 1 ' CLK high
CS1 = 0 ' CS1 low, LTC1298 resets
FOR J = 3 TO 0
AD_DTA_OUT = (AD_COMMAND >> J) & $1
AD_CLK = 0 ' clock pulse
AD_CLK = 1
NEXT
AD_CLK = 0
AD_CLK = 1
AD_DTA_DIR = 0 ' make DATA_IO an input
AD_BAND = 0
FOR J = 1 TO 12
AD_CLK = 0
AD_CLK = 1
AD_BAND = (AD_BAND << 1) | AD_DTA_IN
NEXT
CS1 = 1 ' CS1 back high
RETURN
Use of the Atmospheric Pressure in Computing Barometric Pressure.
Single Point Calibration.
The following discussion deals with how to perform a one time calibration such that your unit does in fact accurately measure station pressure and how to convert this to sea level pressure.
Of course, in the US, we have one system and just about everyone else has another. The discussion focuses first on the SI system and then with "our" system.
For Most of the World.
Note that station pressure varies with altitude in accordance with the following expression;
(1) P_station = P_sea_level * exp (-z/H)Where z is the height above sea level in meters and H is 7000.
For example, assume a local radio station announces the barometric or sea level pressure as 1013 millibars (or hectoPascals) and you live in the mountains at 1760 meters. From equation (1), your station pressure is;
P_station = 1013 * exp(-1760/7000)
= 788 millibars
Assume you observe that your system is reporting 802 or 14 millibars too
high. You then know that;
P_station = P_measured - 14Note that this is a one time calibration. Note that the -14 calibration constant might be stored in the Stamp's EEPROM quite like the offset correction associated with the discussion of the Analog Devices TMP04 to measure temperature or you could simply hard code it in your program.
By rearranging equation 1, you have an expression which permits you to then convert your station pressure to sea level pressure.
(2) P_sea_level = P_station / (exp (-z/H).
In this example;
P_sea_level = (P_measured - 14) / (exp (-1760/7000))
= 1.28 * (P_measured - 14)
Thus, in developing your Stamp program, you might consider something of
the following form.
AD_COMMAND = $0D ' Ch 0 relative to ground - Atmospheric Press GOSUB MEAS_AD0 ' perform 256 measurements and average IF (AD_AVG = $0FFF) THEN AT_INVALID PRESS = (2*AD_AVG/10) + (7 * AD_AVG/100) + 105 PRESS = PRESS - 14 'correct with calibration constant B_PRESS = PRESS + (2*PRESS/10) + (8*PRESS/100) ' perform correction for altitude DEBUG "BP millibars ", DEC B_PRESS, CRFor the United States.
For those of us more comfortable with inches of mercury, feet above sea level and such, equation (1) may be written as;
(3) P_station_in_Hg = P_sea_level_in_Hg * exp (-z_ft/H_ft)
where z_ft is the number of feet above sea level and H_ft is 22,965.
Assume, you live in Denver at 5200 feet and hear on the radio that the barometric pressure is 30.03 inches of mercury.
P_station_in_Hg = 30.03 * exp(-5280/22965)
= 23.86 inches of mercury
But, alas, your unit is reporting 22.94 which is 0.92 too low. Thus,
your calibration constant is +0.92 or, as the Stamp doesn't perform
decimal arithmetic, +92
Rearranging equation (3);
(4) P_sea_level_in_Hg = P_station_in_Hg / exp(-5280.0/22965.0) = 1.259 * P_station_in_Hg or = 1.259 * (P_measured_in_Hg + 0.92)Your Stamp program, might be of the following form.
AD_COMMAND = $0D ' Ch 0 relative to ground - Atmos Press GOSUB MEAS_AD0 ' perform 256 measurements and average IF (AD_AVG = $0FFF) THEN AT_INVALID PRESS_Hg_100 = (7*AD_AVG/10) + (9*AD_AVG/100) + (7*AD_AVG/1000) + 295 PRESS_Hg_100 = PRESS_Hg_100 + 92 'correct with calibration constant DEBUG "AT in Hg", DEC PRESS_Hg_100/100, ".", DEC PRESS_Hg_100//100, CR B_PRESS = PRESS + (2*PRESS/10) + (5*PRESS/100) + (9*PRESS/1000) ' perform correction for altitude DEBUG "BP in Hg ", DEC B_PRESS/100, ".", DEC B_PRESS//100, CRNoise and Cabling Considerations.
As previously noted, in using a 12-bit analog to digital converter over the range of 0 to 5.0 VDC means that each of the 4096 quantizing bands corresponds to nominally 1.25 mV which is quite small. Note that if even 10 mV of noise is present on the input signal, the uncertainty of the measurements may be up to eight quantizing levels and the user might have simply used a 9-bit A/D to achieve the same accuracy. This really calls into question applications which use 14-bit or even 16-bit A/D converters where each band is 300 or 75 uVolts. One wonders if the noise is not entirely masking the accuracy the designers are striving for.
One technique for reducing the inaccuracy due to noise is to perform many measurements and then average. This is a valuable tool that has only become available with low cost processors.
The following deals with other techniques for reducing noise.
Turn Everything Off.
Turn everything else off when performing an A/D conversion. That is, turn off such noise makers as free running TMP04 temperature sensors and 555 circuits which are being used to measure relative humidity. (These are both treated in other discussions).
In this application, we can't turn off the Stamp which generates a fair amount of noise. It is interesting that Microchip PICs which have on-board 8-bit A/D converters do permit the user to enter a "sleep" mode where most circuitry is turned off and when the conversion is completed, the processor is interrupted and wakes up and resumes its operation. The folks at Microchip are very clever people.
Terminate the A/D Input.
See Figure #4.
Terminate the input of the A/D with as low a resistance as possible without loading down your source. In this application we used 100K as the MPX4115 has a relatively high output impedance.
Note a noise source coupling into a lead may be approximated as a voltage source in series with a very high resistance R_coupling. The input to the A/D is quite high.
Thus, in the absence of a terminating resistor, the noise is reduced by a factor of;
R_in_AD / (R_in_AD + R_coupling)A terminating resistor R_term will cause the noise to be reduced by a factor of;
R_term / (R_term + R_coupling)Thus, the improvement with the terminating resistor may be approximated as;
R_term / R_in_ADFor example, if R_in_AD is 5.0 Megs and R_term is 100K, the improvement is a factor of 50.
Shunt Capacitance.
See Figure #4.
Note that the series R_coupling and the shunt capacitance forms a low pass filter and the higher the capacitance the better. However, recognize that many capacitors, notably electrolytics are not capacitors at frequencies much above audio. Disk ceramic capacitors are recommended as they have excellent high frequency properties.
Twisted Pair.
See Figure #3C.
In the case of measuring wind direction, the signal source may be located several hundred feet from the A/D converter and thus the cable run is highly susceptible to all manner of noise.
Twisted pair cable is strongly recommended. Consider that for over 100 years the telephone company has used twisted pair to carry analog voice conversations on the order of millivolts right along side power lines carrying potentials of many kilo volts of commercial AC power and past all manner of other troublesome noise sources; vapor lamps, arc welders and commercial radio transmitters. It may not always work, but in the main, it does.
The general idea is that the magnetic field associated with a noise source induces currents which flow one way in one twist and the opposite way in the next loop and thus cancel one another.
Thus, in Figure #3C, I have shown three pairs to the remotely located dual wiper potentiometer, power and ground, Wiper #1 and ground and Wiper #2 and ground. However, note that with the last two, the ground is connected at the processor side to prevent ground loop currents.
CAT 5 network cable provides four twisted pairs in a single jacket and thus it lends itself to this application. Note that the fourth pair may be used with the an anemometer which is usually co- located with the wind vane.
Summary.
This discussion centered on the Linear Technologies LTC1298 dual 12-bit A/D. Simple routines were presented to illustrate how to make measurements from either channel 0 or channel 1 to ground.
Three applications were discussed; use of the A/D to perform a straight forward conversion (user input channel), interfacing with an MPX4115AP pressure sensor and interfacing with a dual wiper potentiometer to determine angular position.
Points were offered that when doing any programming, first strive for clarity so that you and others can debug your code. If you later learn you do not have enough memory, you will most likely see obvious paths to "crunch" the code without substantially sacrificing clarity. If you strive for compactness in writing each fragment and in doing so, sacrifice clarity, you may well find you have used but half the memory but neither you nor your replacement can hope to maintain it.
The SHIFTIN and SHIFTOUT are without question powerful commands. But, first understand the nature of the interface by "pushing bits" and then possibly move to these commands. Again, clarity is considered by most industries to be paramount.
Various concepts in reducing noise including averaging, terminations and the use of twisted pair cable were presented.
Parts.
To encourage people to learn by tinkering we offer inexpensive parts to tinker with the concepts discussed in this discussion.
Note that the wind vane must be ordered from Fascinating Electronics. The dual wiper potentiometer which is included in the FE wind vane package is also available from FE as a separate item.
