
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:
where V is the voltage to be measured. V(t) is 1.5 volts at the end of the RCTime command. Solving for V,
In order to calculate with the Stamp, it is useful to use the Power series approximation for exp(X):
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
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
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.