Strategy for Porting "ANALOGIN" (Sigma-Delta) to ISR?
![Zoot](https://forums.parallax.com/uploads/userpics/559/nW4UO23UEIWZ4.png)
I've been playing with ANALOGIN so I can have a few channels of ADC on some SX projects w/o having to add more chips. In these projects the mainline (a state machine) can't really be expected to run it's individual pieces with any particular regular time period, so it tends to add jitter to ANALOGIN readings, so I've been scratching my head over how to run it in the ISR.
It's not much code, I don't think since I only need to keep track of the current loop through the 255 charge/read cycles and if the read is in progress or if it's ready for the mainline to parse....
... but I'm having trouble wrapping my head around time requirements here. Given what I see happening in generated code for ANALOGIN, and given that I'm working with ISR periods of say 13us, it would seem that readings wouldn't be taken quickly enough? Do I have that right? Would I need to use larger cap so that the charge/discharge cycle is long enough to be read? My rough count of analogin time as used normally in the mainline (with 1 priming cycle) is about 1200us (at 20MHZ) so it's not exactly a fast conversion to begin with.
Suggestions? Theory? Ideas?
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
When the going gets weird, the weird turn pro. -- HST
1uffakind.com/robots/povBitMapBuilder.php
1uffakind.com/robots/resistorLadder.php
Post Edited (Zoot) : 12/4/2008 6:59:24 PM GMT
It's not much code, I don't think since I only need to keep track of the current loop through the 255 charge/read cycles and if the read is in progress or if it's ready for the mainline to parse....
... but I'm having trouble wrapping my head around time requirements here. Given what I see happening in generated code for ANALOGIN, and given that I'm working with ISR periods of say 13us, it would seem that readings wouldn't be taken quickly enough? Do I have that right? Would I need to use larger cap so that the charge/discharge cycle is long enough to be read? My rough count of analogin time as used normally in the mainline (with 1 priming cycle) is about 1200us (at 20MHZ) so it's not exactly a fast conversion to begin with.
Suggestions? Theory? Ideas?
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
When the going gets weird, the weird turn pro. -- HST
1uffakind.com/robots/povBitMapBuilder.php
1uffakind.com/robots/resistorLadder.php
Post Edited (Zoot) : 12/4/2008 6:59:24 PM GMT
Comments
When you use it in an interrupt you don't need the priming cycle, since it is continuous.
So the rate would be 13uS * 256 = 3.328mSec or about 300 Hz.
Basically every interrupt you sense the input pin. If the input pin is high, you add one to a temp value and make the output pin low. If the input pin was low, then just make the output pin high.
Next you increase a counter, when the counter rolls over to zero, you copy the temp value to the variable to hold the ANALOGIN value and possibly set a flag to indicate that a new value has been aquired.
I could whip-up some code if you need more help.
Bean.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
"The welfare of the people in particular has always been the alibi of tyrants." ~ Camus
www.iElectronicDesigns.com
·
Oh, sure, the cap will always be charging/discharging at a regular interval unlike a mainline analogin which may have a substantial amount of irregular time between calls to the command. I didn't think of that.
The code is simple, but where I'm scratching my head is how to go about choosing the best cap/resistor values for a given interrupt rate.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
When the going gets weird, the weird turn pro. -- HST
1uffakind.com/robots/povBitMapBuilder.php
1uffakind.com/robots/resistorLadder.php
I'm sure there is a way to calculate it, but I would start with 10K resistors and 1uF cap.
If you get unsteady readings or use larger values. If the response time is to long use smaller values.
If the values are too large, you will get· values that skip around alot (like 128 to 192 in one jump).
Bean.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
"The welfare of the people in particular has always been the alibi of tyrants." ~ Camus
www.iElectronicDesigns.com
·
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
When the going gets weird, the weird turn pro. -- HST
1uffakind.com/robots/povBitMapBuilder.php
1uffakind.com/robots/resistorLadder.php
Attached is a document with ADC calculations.
Step 4 calculates the C for a given resolution N and interrupt rate.
The calculated C will result in a ripple at the adc input pin (= ripple over C)
that hoovers between 0.5Vdd-0.5LSB and 0.5Vdd+0.5LSB
A larger C decreases the ripple, a smaller C increases the ripple.
The value is a guiding value but it also sets the signal bandwidth that
you can sample (you must sample at least at 2x the input BW).
regards peter
Peter, just a few questions on your notes:
- under step 2, is the following
2*Vdd - 2*Uinmin
to be read as
(2*Vdd) - (2*Uinmin)
- under step 3, is the following
Vdd - 2^(N-1) * ( Uinmax - Uinmin )
to be read as
Vdd - ( 2^(N-1) * ( Uinmax - Uinmin ) )
or
( Vdd - 2^(N-1) ) * ( Uinmax - Uinmin )
- under step 4 I'm a bit confused by Fs and N:
-- for example, N (bit resolution) would be 8 if I'm using a byte as the final ADC value? 16 if a Word? etc?
-- Fs is how many times per second a converted sample is desired, or how many times per second the state of the output pin will be set? I believe it's the latter?
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
When the going gets weird, the weird turn pro. -- HST
1uffakind.com/robots/povBitMapBuilder.php
1uffakind.com/robots/resistorLadder.php
Step 2:
(2*Vdd) - (2*Uinmin)
Step 3:
Vdd - ( 2^(N-1) * ( Uinmax - Uinmin ) )
Step 4:
N is bit resolution, so·8 for byte, 16 for word, 10 for 10bits ADC.
Fs is interrupt frequency in Herz.
For example, if FREQ = 50MHz and intperiod=217 (prescaler 1:1)
then Fs = 50MHz/217 = 230415 Hz
With Fs in Herz and R in ohms yields C in Farad
With Fs in Megahertz and R in ohms yields C in microfarad
regards peter
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
When the going gets weird, the weird turn pro. -- HST
1uffakind.com/robots/povBitMapBuilder.php
1uffakind.com/robots/resistorLadder.php
Now, I have a few other questions.
1. Should I presume that this circuit will be more sensitive to temperature swings and the like than an ADC chip? Ditto that it will be sensitive to tolerances in the resistors and cap(s)?
2. Is there any way to combine pins if I wanted to set up 4 or 6 sigma delta ADCs? I'm thinking not, because I can't see a way around the need for isolating the input and output of each circuit. And if I had that many it would probably be easier to just hook up a multi-channel ADC IC anyway, but in a pinch it would be nice.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
When the going gets weird, the weird turn pro. -- HST
1uffakind.com/robots/povBitMapBuilder.php
1uffakind.com/robots/resistorLadder.php
Post Edited (Zoot) : 12/8/2008 5:41:40 AM GMT
For tolerance, consider this: (adcValue =·0 to 2^N - 1)
······Uinmax - Uinmin···········································
Uin =·
* adcValue +·Uinmin =
··········2^N - 1
·······R1···· ··· 1····················Vdd········ R1·· R1·· R1
Vdd·* ----·*
* adcValue +·
* (1 - -- - -- + --)
·······R2····· 2^N - 1··················2········· R2·· R3·· R4
You can calculate the minimum and maximum for Uin using minimum and maximum values for
the resistors and calculate relative tolerance from that.
But a very good approximation would be
dUin···dVdd··· dR1·· dR2
---- =
+ --- + ---
·Uin··· Vdd···· R1··· R2
In words:
relative tolerance in Uin equals rel.tol. of Vdd + rel.tol. of R1 + rel.tol. of R2
So if tol.Vdd =·5%, tol.R1 =·1%, tol.R2 =·1% then tol.Uin =·7%
regards peter
Post Edited (Peter Verkaik) : 12/8/2008 1:42:56 PM GMT
You should set the output pin at equal intervals
so charge and discharge time are equal when
hoovering around Vdd/2.
Interrupt_Handler:
'...
Read_Sigma_Delta:
·· Sample = AdcIn0·· 'set output at equal intervals
·· AdcOut0 = ~Sample
···adcVal·=·adcVal·+·Sample
···INC·adcCntr
···IF·adcCntr·=·0·THEN
······sensed·=·adcVal
······adcVal·=·0
···ENDIF
'...
RETURNINT
regards peter
Actually, Peter, here is another question regarding your Sigma Delta calc. worksheet -- choosing R1 to start -- what should I be considering when choosing this first value?
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
When the going gets weird, the weird turn pro. -- HST
1uffakind.com/robots/povBitMapBuilder.php
1uffakind.com/robots/resistorLadder.php
is a virtual ground for small ac signals superimposed on a dc input voltage,
R1 should be large compaired to the output resistance of·your
Uin voltage source (those 2 form a divider), but 10k should do
fine for·most applications.
regards peter
While I still sometimes (wistfully) wish that the SX had 1-5 analog channels like some of the PICs, this is a superb way to add one or two ADCs to a project without having to purchase an ADC chip. Sweet.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
When the going gets weird, the weird turn pro. -- HST
1uffakind.com/robots/povBitMapBuilder.php
1uffakind.com/robots/resistorLadder.php
Rick
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
When the going gets weird, the weird turn pro. -- HST
1uffakind.com/robots/povBitMapBuilder.php
1uffakind.com/robots/resistorLadder.php
increases (eg. sample rate decreases) by powers of 2.
Here is code for a 15bit adc. Note that this code was set up
to use dynamic ports and pins, so you could simplify it
when used with fixed pins.
regards peter
Rick
but with the following consideration:
Rather than the sx I/O pins have a fixed treshold point (eg. Vdd/2)
they have a small treshold gap around Vdd/2. A pin input voltage
fluctuating within that gap may not be detected as an input state change.
So this puts a limit on the value for N.
If we name the gap value GV then
Vdd
---- > GV·· to make the input state change happen
2^N
This yields 2^N < Vdd/GV
Unfortunately, I don't know the value for GV
But there is·a simple test:
If the calculated value for C,·does not give stable adcValues
of 2^(N-1) when applying Uin = (Uinmax-Uinmin)/2
(or remove R3 and R4 and do not apply Uin)
then the value for C is too large (eg. ripple accross C is smaller than GV).
Then you must decrease resolution N·which·yields a lower value for C.
regards peter
··