measuring voltage with RC slope
ManAtWork
Posts: 2,176
I need a simple way to measure a voltage over an isolation barrier. An ADC would be much to complicated and expensive and I don't need high precision so I thought I could do it by comparing the voltage against the slope of an RC oscillator and sending the result to the propeller with an optoisolator.
The C of the RC oscillator is charged with a resistor from a 5V supply. It is discharged when the voltage reaches aprox. 4V (exact value doesn't matter). The voltage to be measured is divided down to a range from 0 to 2.5V. At the trigger point of the comperator the input voltage is equal to the slope voltage
V(t) = 5V * (1 - exp(-t/RC))
where t is the time from the end of the discharge pulse to the trigger point of the comperator. Unfortunatelly, the relation is non-linear opposed to the RC decay example in the propeller education kit example where R is measured. To avoid floating point math, we could use the antilog table in the propeller.
As the input is limited to half the supply voltage t/RC stays between 0 and 1 which means the argument to the e-function is between 0 and -1. How can this be shifted to the correct range for the antilog table? I know it must be simple but I just can't get rid of the board before my head, at the moment, and math at school was too long time ago...
The C of the RC oscillator is charged with a resistor from a 5V supply. It is discharged when the voltage reaches aprox. 4V (exact value doesn't matter). The voltage to be measured is divided down to a range from 0 to 2.5V. At the trigger point of the comperator the input voltage is equal to the slope voltage
V(t) = 5V * (1 - exp(-t/RC))
where t is the time from the end of the discharge pulse to the trigger point of the comperator. Unfortunatelly, the relation is non-linear opposed to the RC decay example in the propeller education kit example where R is measured. To avoid floating point math, we could use the antilog table in the propeller.
As the input is limited to half the supply voltage t/RC stays between 0 and 1 which means the argument to the e-function is between 0 and -1. How can this be shifted to the correct range for the antilog table? I know it must be simple but I just can't get rid of the board before my head, at the moment, and math at school was too long time ago...
Comments
TI makes a newer version (CD74HCT4046A) that works up to about 15 MHz.
Google vco ic for others.
For RCTIME though, for low accuracy, you may get away with a simple inverse relationship, It works best when the voltage to be determined is more than twice the threshold trigger voltage. A second constant result = k/t+c can improve it a bit.
To do what you ask, the equation needs to be adjusted to fit the power of two hub table. It is a process--Deep breath!
Vtrig = Vtbd * (1 - exp(-t/RC))
Vtrig= Vtbd * (1 - 0.693 * 2^(-t/(R*C*0.693))) base 2 exp
You know RC in advance, and the Prop measures t. Keep them in commensurate units. Both in microseconds say. Then when doing the division on t/RC, have it come out normalized to a denominator of 2048, that is Z + F/2048, where Z is the integer part of the division and F/2048 is the fractional part. Use 2048 because that is the number of words in the exp hub table. Since the exponent is negative, adjust both integer and fractional parts to make the fractional part positive... -Z - F/2048 = -Z-1 + (2048 - F)/2048.
Now, (2048 - F)*2 is the index into the EXP hub table based at $D000 (*2 for word address). The value returned is a 16 bit integer X, which represents a fraction X/65536, and you have to supply and implied integer part. 1+X/65536. (The answer is a number between 1 and 2, because the exponent of 2 is between 0 and 1). In binary, you have a 17 bit number with a 1 in bit 16 and the fractional part in bits 0 to 15. Now adjust that answer by the integer part from above, -Z-1. That is an integer exponent of 2, so it represents a shift. For example, if Z=0, then you have to multiply the 17 bit number times 2^-1, that is, shift it one right. Okay, still interested? We're halfway there!
* multiply t with the time-scale factor to fit the address range of the table
* lookup y:= table[2048-t] + $10000
* calculate v:= ($20000-y) * voltage-scale
The table holds a "window" of the exp-function y=2^x in the range 0<=x<1 and 1<=y<2. That window looks exactly like the range -1<=x<0 and 0.5<=y<1 except for x-offset and y-scale.
The correct scaling factors can be found as follows: an input (after the divider) of half the supply voltage has to result in t=2048. Then, y is equal to $10000 and the final result has to be the voltage before the divider.
RickB, thanks for the hint but I prefer the RC+software solution because...
* it's more "the propeller way": make use of what's already there instead of adding external hardware
* math exercises are good for the brain
* I hate adding yet another bin to my IC stock
PS: Tracy, I think we started typing about the same time but you were faster. Thanks for the detailed explanation.
Vtrig = Vtbd * (1 - exp(-t/RC))
Vtrig= Vtbd * (1 - 2^(-t/(R*C*0.693))) base e to base 2, ln(2)=0.693
That is easier because it is all rolled into one constant, R*C*0.693 before the division in the exponent.
Of course, all that and more is taken care of automatically if you use the floating point package, but what fun is that?!
A propeller based VFD
Attachment not found.