BASIC Stamp RCtime command

performance and applications

(c) 1998, 2001, 2004 EME Systems, Berkeley CA U.S.A.
<stamp index> <home>

Contents: (updated 10/9/2005)


RCtime, applications and basic equations

top

The RCtime command on the BASIC Stamp is a quick and dirty analog to digital converter. RC stands for Resistance and Capacitance and the Time it takes to charge up a capacitor through a resistor. Thermistors and photocells and manual potentiometers are variable resistances and are standard fare for RCtime.

RCtime is a bit of a misnomer, because the command can do a lot more than just Resistance-Capacitance circuits. If it is set up right, it can also measure current, voltage, and capacitance, and the output of various transducers. Examples of sensors that can use RCtime are photodiodes, which are essentially current sources. Another current source sensor is the AD590 temperature sensor (or the TMP17 or the AD592 or the LM334 ). Capacitances too may be sensed with RCtime, for example, to construct a capacitance meter, or to read out certain kinds of humidity sensors.. My series for the stamps-in-class program on Earth Measurements develops a number of examples of using the RCtime command, in lieu of an analog to digital converter.


Circuit equations for standard RCtime use with a resistor and a capacitor:

RCtime circuit #1, resistor to +5 volts, voltage increases during RCtime toward the threshold at 1.3 volts.
          
+5-----/\/\--;---||------common x var word
R | capacitor loop:
| C RCtime 0,0,x
p0-----/\/\--' low 0
100 goto loop
1.3 = 5*(1 - exp(-tm/(R*C)) ' on a calculator (not stamp math!)

where 1.3 is the typical stamp input threshold, 5 is the power supply voltage, tm is time in microseconds, and R and C are resistance in ohms and capacitance in microfarads. This is shown on the graph below as a curve that rises from zero and crosses the threshold from below. The time interval is labeled RCtime#1. It is easy to solve the above equation for tm

tm = 0.301 * R * C 

The RCtime command returns a value where 1 unit= 2 microseconds, so value x should be 0.150 * R * C, when R is in ohms and C in microfarads. For example, 0.1 microfarad and 50kohms gives about tm=1505 microseconds or x=752 counts.

Graph: The lower curve that starts at zero and increases is for the above situation. The top curve that starts at 5 volts and decreases is for the next situation...


RCtime circuit #2, resistor to common, voltage decreases during RCtime toward the threshold at 1.3 volts.

In the graph above, this is the curve that starts at +5 volts and drops down to hit the threshold from above.

                     C        
;--||---;
| |
p0-----/\/\----o-/\/\--o---common x var word
100 R loop:
RCtime 0,1,x
high 0
goto loop

1.3 = 5*exp(-tm/(R*C)) ' on a calculator (not stamp math!)

where the parameters are the same as above. This has to drop a total of 3.7 volts to hit the threshold from above, so the time is longer:

tm = 1.347 * R * C

For example, 0.1 microfarad with 50kohms gives about tm=6735 microseconds or x=3367 counts on a BS2.

It does not matter where the "bottom" of the capacitor is attached. In the diagrams above, the "bottom" is attached to common. But it could just as well be attached to +5 volts or any DC source, for example as follows:

         C          R
+5------||---;---/\/\------common
|
|
p0-----/\/\--'
100

This choice does however affect two things. One is the noise level. If the 5 volt supply has lots of fluctuations, those will couple right through the capacitor to the measurement junction at P0, and the RCtime will fluctuate from one reading to the next. Another consideration is what happens when you turn on the power. In this circuit, P0 will start at a high level. In the circuits above, it starts at a low level. Usually that can be compensated by a PBASIC instruction, to initialize the p0 voltage to the correct starting value for the RCtime command.

 

RCtime circuit #3, constant current into or out of a capacitor:

The math is simpler when the capacitor is charged by a constant current source. The curves are straight lines instead of exponentials. The current source charges the capacitor towards more positive voltage, while a current sink pulls the voltage more negative. Examples of a current sources are photodiodes and AD590 temperature sensors.

RCtime with constant current charging

Here are the defining equations: Q=CV, charge equals capacitance times voltage. Differentiating I=C dV/dt, current equals capacitance times rate of change of voltage. Looking at only change in voltage and change in time, and rearranging, t=CV/I. For circuit #1, the change in voltage is 1.3 volts. For circuit #2, the change in voltage is 5-1.3=3.7 volts.

tm = 1.3 * C / I circuit #1

or

tm = 3.7 * C / I circuit #2

Usually in Stamp projects the RCtime command measures tm, and we have to calculate I or C. Practical examples are given below in this note, and in the Earth Measurements curriculum, and in the section on sensor interfacing.


Note re BS2sx and BS2p:

The timing on the BS2sx is a little different from the BS2. The unit of count is 0.8 microseconds, and the maximum is 65536*0.8=0.52428 second. On the BS2p, the unit of RCtime is 0.9 microseconds.

RCtime, error sources, drift and noise

top

The PIC microcontroller was not really designed to use the input pins as analog comparators in this way. It is a bonus that it works as well as it does. And it really does work well, up to 8 to 10 bits of accuracy. The main purpose of this note is to examine and quantify a couple of the major error sources, temperature drift, and noise.

Thermal drift:

The threshold voltage for a stamp input pin to go from "0" to "1" is about 1.3 to 1.4 volts. It has a temperature coefficient of about -625 ppm, referenced to ground. That means about a -1% change in the RCtime reading for a +16 degree Celsius change in temperature.

For example, with 39.2k resistor from +5 to the input pin, and a 0.1 uF capacitor from the input pin to common, the reading from this program:

 X var word
dirs =$ffff
loop:
pause 1000
RCtime 1,0,X ' get reading
low 1 ' discharge capacitor
debug dec X,CR
goto loop

is X=599 at 25 degrees C, but drops to X=584 at 65 degrees C. Only the BS2 was heated to determine this, not the capacitor or resistor. The threshold voltage is approximately 1.3 volts at 25 degrees C.

If the components are all in the same temperature environment, the capacitor could be chosen with a compensating positive temperature characteristic. However, if there are loads on the BS2, from driving l.e.d.s etc, then the temperature of the BS2 will change with the load. The compensating capacitor could be thermally coupled to the Stamp.

Other things being equal, the circuit A below will experience more effect due to the thermal drift of the threshold than will circuit B. The resistor can be replaced with a current source. The difference is in whether the threshold of 1.3 volts is approached from below or from above.

 +5-----/\/\--;---||------common
R | C
| RCtime 0,0,x (A)
p0-----/\/\--'
100


capacitor
+5------||---;---/\/\------common
C | R
| RCtime 0,1,x (B)
p0-----/\/\--'
100

In circuit A, the capacitor charges up from ground until it hits the threshold at about 1.3 volts across the capacitor. In circuit B, the capacitor charges down until it hits the threshold with about 3.7 volts across the capacitor. Small changes in the threshold are a smaller fraction of 1.3 than they are of 3.7, by a factor of about 3. So the first circuit, A, is affected more by the drift. As temperature rises, the times measured by circuit A decrease. The times measured by circuit B increase.

It may be possible to compensate for the drift of the threshold by using a capacitor with an equal but opposite drift. In circuit A, the capacitance would have to increase by about +625ppm.

The capacitor attached to the RCtime pin produces heat directly in the measurement area of the stamp's silicon when it is discharged. The error will be larger when the capacitor discharge current is large, say 10 uF, without a current limiting resistor, and when reading are taken often. It is better to use smaller capacitor values, say 0.1 uF or less. I have not quantified the effects of capacitor size and rate of sampling.

The coefficient of threshold change with power supply voltage is a whopping +4% per volt. Use a stable power supply!

Threshold Noise:

If the resistor in the above experiment is changed from 39.2k to 392k, the values returned by RCtime are much larger, but as others have observed, the values have a lot of "noise". In one trial I saw a statistical distribution of values that ranged from X=5940 up to X=6030, but the distribution was highly skewed, with the mode at 6025, and the low values were rare outliers.

The reason for this noisy behavior is ground bounce, which effectively adds in series with the voltage across the capacitor. As the voltage on the timing capacitor slowly approaches the threshold, a noise pulse can come along right at the instant of sampling. The noise adds in series with the capacitor voltage, and causes a premature "firing". The following figure illustrates this effect.

If you want to coax out the "correct" value, it is probably more reasonable to take the _maximum_ value from a number of samples. Do _not_ compute the _average_ value. This is not a Gaussian process. Compute the mode instead, or simply the sample maximum. The effect does not occur so much with low values of X from RCtime, because the approach to the threshold is much steeper and there is less chance for noise to affect the result. For example, when the R=39.2k, the fluctuation was limited to X=599 or X=598 (at 25 degrees C).

One way to reduce the effect of ground bounce is to keep the ground loop to a bare minimum. Attach the capacitor reference lead directly to the ground pin on the BS2, not to some ground point way the heck out on a carrier board. Get as close as possible to the ground pin, and bypass the supply with both tantalum and ceramic capacitors right at the stamp power pins. You could have best luck if you contruct your own "stamp", because then you could acutally reference directly to the PIC Vss pin.

Dave Carr suggested using the "noise" from RCtime as a "random number generator"!

Is it better to approach the threshold from above or from below, in consideration of noise? That is circuit A or circuit B above? As shown in the figure, the closer the voltage is to the threshold, the more subject it is to noise. A line coming up from below to hit the threshold at a certain point is always closer to the threshold than a straight line coming down from above to hit at the same point. So if the charging waveform is a straight line (from a current source), then the best noise immunity comes from the approach from above. There is less advantage with resistors, because of the concavity of the exponential curve.

Design considerations, ground loops:

Overriding design considerations may dictate whether to use circuit A or circuit B. For example, a current source like the AD590 temperature sensor might work okay with 3.7 volts overhead, but it will definitely not work with 1.3 volts, so circuit "A" is the only option.



Monitoring battery voltage with RCtime:

top

Suppose you want to monitor the voltage of a 12 or a 6 volt battery being used to power a project. There is no need to buy an analog to digital converter just for that. To measure the battery voltage, you can let it charge a capacitor through a resistor, and you can calculate the voltage from the charging time of the capacitor using the Stamp's RCtime command. Here is a circuit and some BS2 code. The following RC circuit is connected to BS2 pin P0:

      681 kohm        470 ohm 
Vx ----/\/\/\---o-----/\/\/\----P0 to stamp
unknown |
voltage ===== 0.01 uF film
|
Vss

Use stable components for best results, a 1% 681kohm resistor and a polystyrene or polycarbonate film capacitor. A BS2 test program is:

rct var word ' RCtime value
Vx var word ' voltage value calculated
' we want this to = applied voltage Vx
Cn1 con 48576 ' first constant, see below
Cn2 con 8 ' second constant, ditto
' circuit attached to P0
low 0
loop:
RCtime 0,0,rct
low 0
Vx=Cn1 / rct + Cn2
debug home,dec? rct,"Vx=",dec Vx/10,".",dec1 Vx
pause 500
goto loop

The program displays the raw RCtime value and the calculated voltage. You will see that as you increase the applied voltage, Vx, the time to charge up the capacitor up decreases.

Here is a table of actual values I collected experimentally: This shows the applied voltage measured by a voltmeter, and the raw RCtime value from the program (not the calculated Vx).

    volts Vx RCtime, rct
18 282
17 300
16 319
15 342
14 368
13 401
12 434
11 479
10 528
9 592
8 673
7 780
6 932
5 1152
4.5 1310
4 1514
3.5 1805
3 2201
2.5 2908 note--more fluctuation in rct at lower Vx

The RCtime values you find will be somewhat different, and the calculated voltages will be several tenths of a volt off from the true values. That is due to differences in component values from circuit to circuit. For best results you will have to find the appropriate values of the constants Cn1 and Cn2 for your particular circuit. You can find the appropriate constants to enter in the program by the following procedure.

Measure the applied voltage at two points, V1 and V2, and the corresponding raw values from the RCtime command, rct1 and rct2. Having these values, here is the formula to use on your scientific calculator to find the constants to use in the program: Just plug in the values to formula 1 to calculate Cn1 and then formula 2 to get Cn2:

V1: lower voltage applied to circuit
rct1: corresponding raw RCtime value
V2: higher voltage applied to circuit
rct2: corresponding raw RCtime value

Cn1 = 10 * (V1 - V2) * (rct1 * rct2) / (rct2 - rct1) formula 1
Cn2 = 10*V1 - (Cn1 / rct1) fromula 2


For example, here is the calculation for V1=10 volts and V2=14 volts, with the RCtime values taken from the above table. Note that this covers typical range of operation for a 12 volt gel-cell battery.

V1=14, rct1=368, V2=10, rct2=528:

Cn1 = 10*(14 - 10) * (368*528) / (528 - 368) = 48576
Cn2 = 10*14-(48576/368)= 8

The calculated values will be exact at 10 and 14 volts but will be approximate for other points. For example, when the input Vx is actually 12 volts, the equation

vx=48576 / rct + 8

on the Stamp comes up with 119, which is displayed as 11.9 volts. A better approximation can be had by using a second order formula, that makes use of the remainder from the second division. Explanation of improved division formula.

Vx=48576/rct*10+(48576//rct*10/rct) + 80 = 1199

which should be displayed as 11.99 volts, very close to the true value (12 volts, times 100).

The equation is an approximation, but it works because, 1) the battery voltage is several times higher than the 1.3 volt threshold of the BASIC stamp, so the charging curve is not too nonlinear, and 2) the battery voltage will be fairly constant around 5 to 7.2 volts for a 6 volt battery, or 10 to 14.4 volts for a 12 volt gel cell battery. Or 7.5 to 9.5 volts for a standard nine volt alkaline battery. It is a similar narrow range for other battery chemistries.

If you build the circuit, you should measure the actual RCtime value recorded at two known voltages in your circuit. Don't trust the table of data I collected. It should be close, but not right on. The exact values of the components in your circuit determine the constants that you calculate in the calibration formula.

Note that you can't use a value of greater than 65535 for Cn1, due to the 16-bit limit of the stamp. The components in the circuit have been chosen so that the constant will have a comfortable margin allowed for component tolerance. Any combination of resistor and capacitor that have the same product should give approximately the same result. For example, you could use a 0.068uF capacitor with a 100kohm resistor. Or a 0.001uF capacitor with a 6.8 megaohm resistor (but high value resistors tend to be relatively unstable).

One reason to use a high value of resistor is to avoid leakage current when you are not measuring the voltage. Consider a stamp that is powered by a 9 volt battery, and the battery is hooked to a 681kohm resistor/capacitor as above. Now suppose the Stamp needs to go to sleep. If the measurement pin is left low, then a current of 9/681000 = 13 microamps will flow, which is wasted current. But it won't hurt anything. Moreover, consider what happens if you leave the measurement pin in the high state instead of low. Then the current will be (9-5)/681000 = 5.8 microamps. But that current will flow into the power supply and contribute to keeping the Stamp alive as it sleeps, so the current is not as much wasted. Just a side commentary.

The equation suggested above is a simplified version of the exponential charging equation that governs the circuit. The simplification works best when the voltage Vx is several times greater than the 1.3 volt threshold voltage of the BASIC Stamp chip. For better accuracy, you may want to use a lookup table and interpolation, or a more accurate equation:

Vunknown = 1.3 / (1 - exp (-t/0.068))

where 1.3 volts is the BS2 input threshold
0.068 is the RC time constant (0.68E-6 farad * 0.1E6 ohms)
t is the measured time (seconds)

The BS2 math notes show how to implement the natural logarithm on the Stamp. The equations given above are a hyperbolic approximation.


Monitoring power supply current with RCtime and the MAX471 or MAX472:

top

circuit diagram using MAX472A good way to monitor power supply current is by using the MAX471 or MAX472 chips from Maxim. While it is possible to do this with an op-amp (see sidebar box), the Maxim chip makes it easy. These chips work by inserting a small-value resistor in series with the power supply on the high side. In the MAX471, this resistor is inside the chip and is approximately 35 milliohms. The chip can handle up to 3 amp, and at that current the chip inserts only about 0.1 volt loss in the circuit being measured. The MAX472 requires an external resistor, but allows more flexibilty in the design. For example, a 0.2 ohm sense resistor can be used so as to measure currents on the order of 500 milliamps, or a 0.0033 ohm resistor would be good for high currents up to about 30 amps. The output of the chip at pin 8 is a small current that is proportional to the supply current that is flowing through the power sense resistor. For example, the MAX471 produces an output ratio of 500 microamps per amp, so at 3 amps full scale, the current from pin 8 is 1.5 milliamps. Normally, a designer would put a resistor in series with the output current, to convert it to a voltage. For example, 1.5 milliamps into a 2 kohm resistor would produce 3 volts to and analog to digital converter when the power current was 3 amps. The chip can monitor currents in either direction, for example, to track the charging and discharging of a battery. The sign output (pin 5) is zero or one to indicate which direction the current is flowing. That would normally go to another pin on the controller.

Stamp RCTIME Circuit using MAX471It is possible to direct the output current into a capacitor, instead of a resistor. Use the RCtime command to measure the current. To the left is a circuit using the MAX471. There is a 0.1 microfarad capacitor connected from pin 8 of the MAX471 to common, and a 100 ohm resistor to pin P0 of a BASIC Stamp. With a 0.1 microfarad integration capacitor, the RCtime value would be about 260 microseconds when the power current is 1 amp. Lower current, longer time. 520 microseconds at 1/2 amp. 2600 microseconds at 100 milliamps. 130000 microseconds at 2 milliamps. This last one is important because the Stamp RCtime command is limited to less than about 130000 microseconds (0.13 second). So 2 milliamps is about the minimum current this setup can measure. Of course, if you really need to measure less than 2 milliamps, you could use a capacitor smaller than 0.1µF. Or, if you need to improve the resolution at the high (1 amp) end, at the expense of the low end, use a larger capactor. Or, use the MAX472, which has more parameters to play with.


 time = C * Vthreshold / Iout
= 0.1 µFarad * 1.3 volt / (500E-6 amp/amp * Ipwr amp)
= 260 / Ipwr microseconds

Ipwr = 130/countvalue <--- using BS2 COUNT value, 2 microseconds per count

The stamp BS2 counts to 130 in 260 microseconds. (other Stamp models have different count ratios). After the stamp determines the countvalue, it brings P0 low to discharge the 0.1µF capacitor for the next round, and it has to calculate the reciprocal to find the current. The following uses long division to calculate the fractional amps. There are other ad-hoc ways to do this, but the long division is really the most versatile.

x var word
n var word ' for numerator of division
j var nib ' for division loop
i var nib ' for integer amps
f var word ' for fractional amps
' refer to math division notes for explanation
low 0 ' discharge the capacitor
loop:
RCtime 0,0,x
low 0 ' ready for the next round
debug dec x," " ' show raw count
N=130 ' initialize
I = N/X ' whole amps
'---------binary division loop-----------
for J=15 to 0 ' 16 bits
N=N//x<<1 ' remainder*2
F.bit0(J)=N/x ' next bit
next
f = f**1000 ' renormalize, to 1/1000ths of an amp (mA)
debug dec i,".",dec3 f," amps",CR ' show x.xxx amps
pause 100
goto loop ' do it again


One pin, many switches using RCtime:

top

I saw some instructions on a way to setup multiple push switches onto one pin in the 1.9 manual and i'm trying to figure out basically how to do it with a basic stamp and RCTime instead of Pot, but i'm completely stumped.

(The reference is to BASIC Stamp I app note 18, titled, "One Pin, Many Switches")

You can use a very similar circuit on the BS2, modified as follows for use with the RCtime command in (5 switches shown):

                    10k    10k   10k    10k    10k
+5 Vdd --o-/\/\-o-/\/\-o-/\/\-o-/\/\-o-/\/\-o
| | | | | |
N.O. switches %0 %1 %2 %3 %4 |
| | | | | |
stamp P0 -/\/\-o------o------o------o------o------o
1k |
=== 0.01uF mylar film
|
Vss

When a circuit calls for several resistors of one value, you can often get them all in one SIP or DIP package. That would go for the series 10k resistors in this circuit. The circuit with 5 switches would require one 10kx5 resistor network, one 0.01uf capacitor, and one 1kohm resistor, plus the 5 switches. The purpose of the 1k resistor is to protect the input from currents when switch 0 is held pushed down, and to protect the input from static electricity from the switches. Note that the chain is a closed at the end, without a switch. It is straightforward to extend this circuit for additional switches.

With one switch at a time down, the time required to charge the capacitor from zero volts up to the BS2 switching threshold at 1.3 volts is about:

tm = 30E-6 * k second, where k is the switch index, 0 to 4.

That is, switch 0 takes ~zero time, switch 1 takes 30 microseconds, switch 2 60 microseconds, and so on, ... and if no switch at all is pressed, the time is 150 microseconds.This comes from solving,

1.3=5*(1 - exp(tm/k*RC))

The value returned by RCtime is in units of 2 microseconds, or about 15 units per switch. Note that if you leave the end of the loop open, the RCtime command will time out after 0.1307 second, and would return a value of tm=0. Having the short circuit on the end speeds up the response when no key is pressed.

' example program for BS2 "one pin, many switches"
tm var word
k1 con 15 ' RCtime difference, switch to switch
k2 con k1/2 ' half the above for offset
low 0
loop:
RCtime 0,0,tm ' get time
low 0 ' get ready for the next try
debug dec tm,tab,dec tm+k2/k1,cr ' show time and key number
' key #0 to #4 down
' note that key=5 means that no key is pressed.
pause 200
goto loop

It is possible that the user might press the key exactly in the middle of the RCtime command, and that would give a bogus result. If it matters, it would be best to read the RCtime value twice in a row, and only accept a key if the two values agree.

Be aware that this circuit will not allow you to sort out two or more switches pressed at the same time. If two switches are down at the same time, the value of the one with the lower index is returned. (See below for a circuit that sorts out two or more pressed at the same time.)

Another way to scan multiple keys would be with an external chip. See http://www.rentron.com/Ser-Key.htm Bruce Reynolds has developed a nice keypad chip that handles up to 10 keys, and it sends back its data via the serial port. That still needs extra parts, a crystal, a capacitor, and a handful of resistors. Also there is the MEMKey from Solutions-Cubed at http://www.solutions-cubed.com/memkey_main.htm, which scans matrix keypads up to 4x5 and returns data on one or two serial lines. And there is the PAK-6 for Al Williams, which can scan up to a full 101 switch keyboard, at http://www.al-williams.com/awce/pak6.htm.  There is also the combination LCD/keypad, from Scott Edwards http://www.seetron.com

What if you want to detect more than one switch pressed at the same time? Then your program could react to key combinations. This is a very useful function to have when there are only a few keys avaialble and when you want to have "special" access codes. For this to work, the switches have to be connected in parallel, and the resistor values should be binary weighted :

         1     10k       All Rs, 1% film
+5 Vdd;--%---/\/\---;
| |
| 2 20k |
o--%---/\/\---o
| |
| 3 40.2 |
o--%---/\/\---o
| |
| 4 80.6k |
o--%---/\/\---o
| |
| 160.2k o--/\/\- P0 on Stamp
'------/\/\---o
|
=== 0.1 film
|
Vss

Note the 0.1uF capacitor, which we need to get more time and more resolution to sort out the key combinations. Also note that the key index starts with one next to the smallest value resistor. The time for the capacitor to charge from zero to +1.3 volts is governed by

1.3 = 5*(1 - exp(-tm/(R*C)) ' on a calculator (not stamp math!)

solving this is:

tm = 0.301 * R * C 

where tm is in microseconds, and R in ohms, and C in microfarads.

If the 160kohm resistor were taken out of the circuit, then with single switches pressed, the times would about, 300, 600, 1200, and 2400 microseconds, and with no key pressed, 0.1307 second (because that is the timeout value with no key pressed). With the 160kohm resistor in place and no key pressed, then the longest time is about 4800 microseconds (K=5). The math gets a little more complicated with the parallel combinations of resistors in the circuit. But you can think of it as a combination of 160kohm resistors in parallel. Basically though, it comes out that 1/tm is a linear combination of the keys that are down. The following table illustrates the point. You can get the values in the table by plugging the parallel combinations of resistors into the above equation for R. The 160kohm resistor is always in circuit, and is represented by the "1" in the least significant bit in each "key combo" in the table. The 10kohm resistor and its switch (0 or 1) is the most significant bit in the key combo.

key combo

R, kohms

tm, usec

48160/tm

00001

160

4816

10

00011

53.3

1605

30

00101

32

963

50

00111

22.9

688

70

01001

17.8

535

90

01011

14.5

438

110

01101

12.3

370

130

01111

10.7

321

150

10001

9.4

283

170

10011

8.4

229

190

10101

7.6

209

210

10111

7.0

193

230

11001

6.4

178

250

11011

5.9

166

270

11101

5.5

155

290

11111

5.2

146

330

Observe that the last column on the right is a number that goes up in equal steps as a function of the key combinations. Considering those values, compute this:

keys = (48160/tm)/20

This in the integer math of the stamp will give 0,1,2,3,...,15 as we go down the rows of the table, and these are exactly the binary values of the switches that we started with in the lefthand column.

Here is a program that takes all this into account.

' example program for BS2 "one pin, many switches"
tm var word ' RCtime value in units of 2uS
keys var nib ' will display this as a binary value
' with a 1 meaning key pressed.
low 0
loop:
RCtime 0,0,tm ' get time
low 0 ' get ready for the next try
tm=tm*2 ' time in microseconds for BS2
debug dec tm,tab ' show time
keys = 48160/tm /20 ' trim the constant to get good key separation
debug bin4 keys,cr ' show keys as binary nib
' key #1 to #4 pressed, pressed bit=1
pause 200
goto loop

The factor 48160 will need to be trimmed in an actual situation so that the binary values for each key fall into place.The exact times of course depend on the exact component values, and it is most important that the ratios of the resistors are correct. Using 1% resistors is important to keep up the accuracy. It is possible to add more switches and weighted resistors,. The more switches there are, the greater the accuracy of the ratios is required.

 


Measuring small voltages with RCtime

top

The problem is to find a way to measure a small input voltage using the RCtime command. The answer here is an integrater circuit using an op-amp. The output voltage, V(t), approaches the threshold steadily with time, at a rate determined by Vin. The circuit uses a transistor current sink in the amplifier output, to get simple current characteristics. The collector of the transistor (or n-channel mosfet) in the circuit acts as a stiff current sink, and the voltage at pin p0 starts at +5 volts and decreases toward the Stamp threshold at 1.4 volts. The voltage across R1 is equal to the input voltage at pin 3 of the op-amp, and for the circuit to operate properly, the input voltage Vin has to be less than 1 volt. For higher input voltages, the signal input voltage must be attenuated with a voltage divider. 

small voltages with RCtime
rct VAR Word
HIGH 0 ' initially start with p0 high
DO
RCTIME 0,1,rct ' voltage on p0 decreases at rate proportional to Vin
HIGH 0
DEBUG ? rct
LOOP
' 2*rct ~= 3.6 * R1 * C1 / Vin
' R1 in ohms, C1 in microfarads, Vin volts.
' rct in units of 2 microseconds (BS2, BS2e, BS2pe), 2*rct is units of microseconds.

The op-amp needs to be a single supply type, and preferably one with rail to rail output capabilities.   It needs to respond to Vin down to zero, and the output needs to swing high enough to drive the transistor base into conduction.   That will be the voltage across R1 (=Vin) plus the threshold voltage of the transistor (~0.6 volts for bipolar, more for mosfet).

When the Stamp does a HIGH 0 command, the pin p0 needs to be able to pull the node all the way up to Vdd.  However, it will be sourcing all of the current I, which will cause an undesireable error due to the output resistance of the Stamp pin, a voltage drop.   The output resistance of the Stamp 2pe is around 50 ohms, so the error with a 100 microamp current will be 5 millivolts.   That is probably not significant.  Keep the current low by choosing a high enough value of R1 for the application.   If Vin is as high as 1 volt, then R1= 10kohms.

Choose the capacitor so that the RCtime value will be approximately 100 when Vin is maximum.   For Vin=1 volt maximum and R1=10kohms, a good choice would be C1=0.01µF.

One nice thing about the circuit is that it can be made to operate with very low voltages, for example, voltages from pH probes.

If the input to the above circuit is a small AC voltage, the effect will be an integration of the positive half-cycles only. For example, if the input is piezo film or a microphone with a few tens of millivolts of output, responding to vibration, the circuit will integrate the sound intensity, and it will . 



<top> <index> <home> logo < mailto:info@emesystems.com>