A Circuit For Measuring Supply Voltages with the BS2 Stamp Module

Return to Desufator Help Page

Stamp volts

The above circuit can be used to measure slowly varying voltages by means of the RCTime instruction. R1 is connected to some voltage which is to be monitored. It needs to be somewhat higher than 1.5 volts, which is the logic threshold of the input pin. C1 is initially discharged, and the RCTime command is used to measure the time taken to charge C1 to 1.5 volts. The higher the voltage connected to R1, the faster will be the charge time. R1/C1 can be changed to suit other voltages or time constants, if one only needs to check for the raw data. This can be calibrated against an external reference, and software constants chosen accordingly. The 220 ohm resistor and diode are for protection purposes.

There is at least one other author who has done this sort of thing, with more in-depth analysis. Take a look at http://www.emesys.com/BS2rct.htm#B_voltage for some further ideas. His calibration methods are easier to program than what I have come up with below.

If it is desired to display actual voltage, then one needs to convert the raw data. The equation for the charge on the capacitor is:

V(t) = V(1-exp(-t/RC))

where V is the voltage to be measured. V(t) is 1.5 volts at the end of the RCTime command. Solving for V,

V = 1.5/(1-exp(-t/RC))

In order to calculate with the Stamp, it is useful to use the Power series approximation for exp(X):

exp(x) = 1 + x + (x^2)/2
Substituting and simplifying results in:

V = K/((t^2) - 2tRC)

where K is a constant to be determined by calibration. (ie trial and error). For easy calculation, it is possible to ignore the2tRC term, as t^2 will be much higher if RC is chosen to give a long enough count. This gives

V = K/(t^2)

In order to calculate this with 16 bit integer math and maintain a reasonable accuracy, we need to avoid calculating t^2 directly. So it is possible to calculate instead

V= (K'/t)*(K'/t)

where K' is a new constant that is the square root of K. K is actually somewhat arbitrary and can be choosen to scale the results to the desired reading. It should be as large as possible given the RC and the voltage you are measuring. The R value can then be fine tuned to give the correct reading. Here is a code fragment to demonstrate this:

	result	var	word
	volts	var	word
start:	low 	15			Discharge C1
	pause 	1			Wait to make sure
	rctime	15,0,result
	volts = 16100 / result	16100 was cut and try value. Other values for other voltages.
	volts = volts * volts
	pause	500			Loop delay
	debug	?	result		Output
	debug	?	volts
	goto	start

Note that the accuracy will be poor over a wide range, so one needs to calibrate at the center of the desired values. This is useful as a way to measure the small changes in a battery output, as an example. In displaying the readout it will be necessary to insert the decimal point in the appropriate place.