+ Reply to Thread
Page 1 of 2 12 LastLast
Results 1 to 20 of 37

Thread: EasyADC - call for feedback

  1. #1

    Default EasyADC - call for feedback

    Hi, All.

    Here is a(nother) simple sigma-delta ADC 2 channel object. The main difference here is that the output for all sample rates is automatically scaled to a 16-bit number, and I tried to give some simple-to-follow theory about the circuit fundamentals.

    I would really appreciate any feedback on the writeup or code. Note that I intentionally avoided using the schematic symbols to keep the file simple ASCII.

    thanks,
    Jonathan

    Edited:
    * added fast median-of-3 filtering (thanks, Dave Hein!!)
    * added Rbias, did easy then complex circuits, changed Tau recommendation again.
    * to change the wording around Tau
    * to incorporate some clarification, and changed to either frequency or period specification.

    Code:
    {{
            Easy ADC
            Jonathan "lonesock" Dummer
    
            Sigma-Delta ADC is very easy with the propeller.  This object shows a simple
            implementation of a 2-channel ADC input.  Here's how to wire it up:
    
            Simplest ADC circuit:
    
            In ----------+ <= common node, at threshold voltage
                         |
            Out ---Rout--+---Rmeasure---* Voltage_to_measure
                         |
            Gnd ----C----+
    
            
            Using counter mode POS (or NEG) w/ feedback, the propeller makes Out-pin the opposite of In-pin,
            while counting the number of clock cycles that A was high (or low for NEG mode).  The threshold
            for the input pin is halfway between VDD and Gnd, or ~1.6V. If the common node voltage is above the
            threshold, the In pin will read high, and the propeller's counter will drive the Out pin Low, and
            vice-versa, effectively pulling the common node to the threshold voltage.  Over a given time
            period, the percentage of time spent pulling the common node voltage low is proportional to the
            input Voltage.
    
            The capacitor acts in conjunction with the resistors to act as a RC low-pass filter for the Out-
            pin's output.  The capacitor is needed, otherwise as soon as the Out pin is set, the voltage at
            the common node changes instantaneously, with no chance for the counter to actually count anything.
            So, the cap and resistor are a simple RC filter, smoothing out high-frequency noise, with the
            corner-frequency of the filter at 1/Tau, where Tau is the time constant of the filter, which for
            a RC filter is simply:
    
                    Tau = Rout*C
    
            Various values of C seem to work fine, so I am recommending setting the C value as if you were using
            the RC filter for a DAC, so Rout*C ~= 1 / typical_output_sample_frequency.  NOTE: this recommendation
            is subject to change!!
    
            With a little bit of Kirchhoff's Current Law (KCL, a.k.a. "summing the current into a node should equal 0"),
            and assuming steady state (so the capicitors act as an open circuit):
            * The maximum input is hit when the Out pin is driven low 100% of the time: Voltage = 1.6 * (1 + Rmeasure / Rout)
            * The minimum input is hit when the Out pin is driven high 100% of the time: Voltage = 1.6 * (1 - Rmeasure / Rout)
    
            The maximum value coming out of the counter is simply the period over which you sample.  For example,
            with a 80 MHz system, running a sampling rate of 44.1 kHz means the sampling period is 1814 clocks.
            The minimum value coming out of the counter is obviously 0, and the maximum possible value of the counter
            is 1814 (if the In pin was high the whole time, the counter would add 1 to PHSx for each clock).  This
            is equivalent to about 10.8 bits.  If you wanted the module to report a 16-bit number exactly, you
            would need to make sure the sampling period was 65535 (or 1.22 kHz on a 80 MHz system).  To make the
            output of the system easier to use, I adjust the FRQx value so that period * FRQx = 2^31-1.  That way,
            after a full period is complete, I can shift right by 15 bits, yielding a 16-bit number.  Note that
            this does _NOT_ mean you are getting 16 significant bits, only that the reading are always scaled to
            that range. 
            
            Things to note:
    
            * you want large resistor values if you are trying to measure an unbuffered voltage source
                    - for example, if you want to measure the voltage on a capacitor...the circuit
                      will bleed current (V_measure_me - 1.6) / Rmeasure.  If you are measuring the
                      output of an op-amp, the resistor values you choose are no big deal (other than
                      setting gain).  Note that the larger the Resistors, the noiser the system can get.
            * keep your traces as short as possible
            * use non-adjascent pins for In and Out if possible (to reduce cross-talk)
            * if possible use a low cog for pins P0..P15 (cog 0 is best, then 1, etc)
            * if possible use a high cog for pins P16..P31 (cog 7 is best, then 6, etc.)
            * there is no point summing then averaging N values...it's the same as using sample-rate / N
            * averaging is still useful if you are smoothing a waveform
            * restart the cog to change the sampling rate
            * the PASM loop takes about 80 clocks, so don't try to go over clkfreq/80 Hz for the sample-rate
    
            
            Here is a more complex version of the circuit, to add some features:
    
                 +-Rbias-+ 
                 |       |
            VDD -+---C---+ <= common node 
                         |
            In -----Rin--+---Rmeasure--- Voltage to measure
                         |
            Out ----Rout-+
                         |
            Gnd -----C---+
    
            Rin does nothing as the input pin is high impedence, but can be used to switch the function
            of the In and Out pins, changing the ADC's range.  For example, if Rin = 0.5*Rout, switching pin
            functions (Out is now the sense pin, and In is now the feedback pin) would yield a new range that
            is 2x larger.
    
            Note that if you have 2 capacitors to constant voltages (VDD and GND), the equivalent capacitance
            of the system looks like both capacitors are in parallel, or 2*C (2 caps are very useful since
            noise on either VDD or Gnd can affect the threshold voltage).
    
            Rbias can be left out of the circuit as well, but since the sum of the current coming into the
            node is 0, you can use Rbias to inject a constant current into the node (since VDD is constant,
            and the threshold voltage is constant (thanks to the prop's counter) we are basically offsetting
            the center point).  As a useful example, if Rbias == Rmeasure, you effectively shifted the input
            range to be +- 1.6 * Rmeasure/Rout, centered around 0 V!  You can verify this using KCL.  The more
            intuitive way to see this, at least for me, is to note that Rmeasure & Rbias form a resistive divider
            between Vin and VDD such that the common node is exactly 1/2 way between the the two, i.e. when the
            input voltage is 0 then the common node voltage would be at VDD/2, which is already the threshold
            voltage, and the counter doesn't have to sink or source any current.  If you want to push the center
            point around you can change Rbias, and/or connect it to Gnd instead of VDD.  For extreme flexibility,
            you could even use a potentiometer with one leg each to Gnd and VDD, or even another output pin via
            a RC filter DAC connected via a resistor to the common node, to affect fine tuning electronically.         
    }}
    
    VAR
      long control
      byte cog
    
    PUB start_freq( Ain, Aout, Bin, Bout, SampleHz )
      '' helper function, to convert Sample Hertz to (rounded) period in system clocks
      return start_period( Ain, Aout, Bin, Bout, (clkfreq + (SampleHz >> 1)) / SampleHz )  
    
    PUB start_period( Ain, Aout, Bin, Bout, PeriodClocks )
      '' initialize the sigma-delta ADC cog
      stop
      drive_mask := (|<Aout) + (|<Bout)
      period := PeriodClocks #> 10 ' 80 for non-filtered, 144 for filtered
      ctra_val := constant(%01001 << 26) | (Aout << 9) | (Ain)
      ctrb_val := constant(%01001 << 26) | (Bout << 9) | (Bin)
      frq_val := POSX / (period - 4) ' -4 because I am resetting PHSx immediately after reading it, so that instruction costs me 4 clocks
      control~~
      return cog := cognew( @EasyADC_pasm, @control ) + 1
    
    PUB fill_buffer( buffer_ptr, num_samples, filter )
      '' fill a buffer with alternating channel A & B 16-bit unsigned samples
      '' period must be 80 clocks or more
      repeat
      while control
      if filter AND (period > 143)
        ' THE FILTERED VERSION IS SLOWER!  period must be 144 clocks or more
        control := -((num_samples << 16) + buffer_ptr)
      else
        ' unfiltered...the minimum period was enforced at start
        control := (num_samples << 16) + buffer_ptr
    
    PUB wait_till_full
      '' you can call fill_beffer earlier, then just spin here until the buffer is full 
      repeat
      while control
    
    PUB stop
      '' kill the cog
      if cog
        cogstop( cog~ - 1 )
    
    DAT
    ORG 0
    
    EasyADC_pasm            ' initialize
                  mov       ctra, ctra_val
                  mov       frqa, frq_val
                  mov       ctrb, ctrb_val
                  mov       frqb, frq_val
                  mov       dira, drive_mask
                  mov       buf_ptr, #0
                  wrlong    buf_ptr, par   
    
                  ' spin until I get a non-zero pointer
    get_buffer    rdlong    buf_ptr, par wz
                  mov       timeout, cnt
            if_z  jmp       #get_buffer
                  ' prime the pump:
                  ' - set initial old* values to be 0 and max, so the 1st value will be the median
                  ' - start my timer and clear the PHSx values to 0 (note the offset relative to when cnt was sampled)
                  mov       phsa, #0
                  mov       oldA1, #0              
                  mov       phsb, #0
                  ' now I have some time to waste, while the 1st sample is gathered              
                  neg       oldA2, #1
                  mov       oldB1, #0
                  neg       oldB2, #1
                  add       timeout, period                                
                  ' if negative, we want filtering
                  abs       buf_ptr, buf_ptr wc     ' C flag holds if I want to filter
                  ' the high 16 bits of the pointer are actually the sample count
                  ' (note: this won't affect the pointer...the upper bits are ignored (anything above 32kB is wrapped)
                  mov       buf_cnt, buf_ptr
                  shr       buf_cnt, #16
    
    sample_loop   waitcnt   timeout, period
    
                  ' grab the new values and reset the counters (saves 2 instructions and 2 variables, costs 4 clocks per counter)
                  mov       A, phsa
                  mov       phsa, #0
                  mov       B, phsb
                  mov       phsb, #0
    
                  ' should I skip the brilliant median filter? (courtesy of Dave Hein...thanks!) 
            if_nc jmp       #:skip_median_filter
    
                  ' Store the original value of A
                  mov       filter0, A   
                  ' Get the minimum of each of the 3 possible pairs ( A & oldA1, A & oldA2, oldA1 & oldA2 )              
                  mov       filter1, oldA1              
                  max       filter1, oldA2
                  max       oldA2, A                ' this modifies oldA2, but it will be overwritten soon anyway
                  max       A, oldA1                ' A is modified (will be the median filtered value)
                  ' find the maximum of those 3 minima               
                  min       A, oldA2
                  min       A, filter1
                  ' update my tracking variables               
                  mov       oldA2, oldA1
                  mov       oldA1, filter0
    
                  ' repeat for channel B
                  mov       filter0, B   
                  mov       filter1, oldB1              
                  max       filter1, oldB2
                  max       oldB2, B                
                  max       B, oldB1                
                  min       B, oldB2
                  min       B, filter1
                  mov       oldB2, oldB1
                  mov       oldB1, filter0
    
    :skip_median_filter
    
                  ' scale the values
                  shr       A, #15              
                  shr       B, #15
                  { limit the values (I shouldn't need this!)
                  max       A, limitFFFF    
                  max       B, limitFFFF
                  '}
    
                  ' write the value (putting A in the high 2 bytes of the long...Little-Endian)
                  shl       A, #16
                  or        A, B
                  wrlong    A, buf_ptr
                  add       buf_ptr, #4
    
                  ' keep going?
                  djnz      buf_cnt, #sample_loop
    
                  ' done...signal done-ness
                  wrlong    buf_cnt, par
                  jmp       #get_buffer
                                                      
    
    {===== PASM Parameters and 'constants' =====}
    drive_mask    long      0
    ctra_val      long      0
    ctrb_val      long      0
    period        long      0
    frq_val       long      0
    limitFFFF     long      $FFFF                                                                 
    
    {===== PASM scratch variables =====}
    timeout       res       1
    buf_ptr       res       1
    buf_cnt       res       1
    A             res       1
    B             res       1
    filter0       res       1
    filter1       res       1
    oldA1         res       1    
    oldA2         res       1      
    oldB1         res       1      
    oldB2         res       1
    Attached Files Attached Files
    Last edited by lonesock; 04-12-2011 at 08:34 PM. Reason: now with optional median-of-3 filtering
    Free time status: see my avatar [8^)
    F32 - fast & concise floating point: OBEX, Thread
    Unrelated to the prop: KISSlicer

  2. #2

    Default Re: EasyADC - call for feedback

    Nice work, looks good. Good to see nice explanations.

    I don't understand this comment:
    * you want large resistor values if you are trying to measure low impedence sources

    Can you clarify that?

    Nice to see an explanation of tau. I still don't have a good feeling for the time constants at work...

    BTW: Regarding min and max readings, I have a calculator here:
    http://www.pulsedpower.net/Applets/E...igmaDelta.html

  3. #3

    Default Re: EasyADC - call for feedback

    Fixing output to 16 bit is a great idea, I away from home now but will try it in several days. my Poor man's Digital 'scope needs this
    I was playing with moch code trying to make up for the variable A/D timeings allowed.

  4. #4

    Default Re: EasyADC - call for feedback

    Great sudo tutorial. I have long known the math and had a very basic idea of its operation, this actually has me understanding this form of ADC in a functional sense (witch is good as I use it quite a bit).
    There is no need for Bloated code.May code optimisation return for all.Multi Processing with out interrupts, now anything is possible.RISC-Prop, A RISC OS like System for ARM9 + P8X32A : WIPRISC OS. True Power for ARM based computers.

  5. #5

    Default Re: EasyADC - call for feedback

    OK, I updated the code above to clarify & fix some stuff. I also changed to 2 start methods, one where you specify the period, and another where you specify the frequency. I also switched to using simple division to calculate the FRQx values, instead of the more complex ratio code.

    @ Rayman: Oops, sorry about that. It was A) confusing, and B) wrong! I meant that if you are measuring the voltage coming off an op-amp or something, then using small resistor values is OK. But if you need to measure something where leaking current will affect the voltage, you should use larger resistors. The voltage at the common node is ~ 1.6V, so you will actually be sinking or sourcing some current with this ADC circuit: (V_measure_me - 1.6) / Rmeasure. In these cases, you may want to make Rmeasure large, like 1 Mohm or so, then adjust your other resistors and caps to match. I really like that calculator! I had found it before, then lost it, so thanks for the (now bookmarked) link!

    @ Perry: Thanks! Your scope is actually why I finally wrote this up ;-) EasyADC is pretty simple to embed, but I actually want to add the option of triggering to EasyADC, as monitoring the values in PASM is much more feasible than in Spin. Let me know when you get back home, we can collaborate [8^)

    @ David: Thanks, I'm glad it helped! Hopefully the recent updates helped more, rather than hindered.


    Thanks for your feedback, more is still welcome! [8^)

    Jonathan
    Free time status: see my avatar [8^)
    F32 - fast & concise floating point: OBEX, Thread
    Unrelated to the prop: KISSlicer

  6. #6

    Default Re: EasyADC - call for feedback

    I've been wondering about tau too. One analysis that makes sense to me requires that the voltage ripple at the summing node be on the order of one bit during one clock period. That comes out to
    tau = RC = 2^bits / clkfreq ----> note that the resolution is a factor.
    That differs from your prescription of
    tau = ~100 / clkfreq.
    We agree for a level of around 7 bits. Suppose you are shooting for 11 bits. In a time interval of 100/clkfreq the summing node can slew the equivalent of 16 bits. Is that important?

    I really don't have a handle of this and I'd like to hear reasoning or empirical experience that leads to one conclusion or another. A longer tau will also slow down the step response.

  7. #7

    Default Re: EasyADC - call for feedback

    Hi, Tracy. Thanks for the feedback. Here's my reasoning for the Tau selection: once you pick your C and R values, you are limiting the physical response of the system to input...i.e. you can not respond any faster. Numerically, you can increase the averaging (or with this code, just decrease your sample rate) to go slower, but you have no option of sampling anything of higher frequency, as it's already been filtered out. So, for my purposes, I say that I would never want < ~6-bits resolution, so I pick the RC time constant to match (Ideally, though I don't want to be sampling at my corner frequency, especially with a RC filter, only 3dB falloff per octave).

    I'm sure that's all stuff you knew, it's just my reasoning for the recommendation. If I really wanted to do 1Msps, I'd probably pick a Tau that was only about 10 / clock_rate.

    Jonathan
    Free time status: see my avatar [8^)
    F32 - fast & concise floating point: OBEX, Thread
    Unrelated to the prop: KISSlicer

  8. #8

    Default Re: EasyADC - call for feedback

    Hi Jonathan,

    I suspect that the RC time constant, tau, is not low-pass filtering your input signal in the manner that you describe. The capacitors are sitting at a summing junction, and a suitable analogy would be an inverting op-amp with a capacitor from the inverting input to ground. To first order, the capacitor at virtual ground sees no voltage changes and does not enter into the equations for gain or frequency response. It does enter into the noise gain of the op-amp, but in the sigma-delta that is a different issue (jitter).

    A separate point that I wanted to raise is that the input to the summing junction is a current. Voltage in series with a resistor is just one way to supply that current. The current might instead come from a photodiode, or a transistor collector, or an AD592 temperature sensor, or a charge displacement device like a piezo film tab, etc..

    This is related to the tau issue. Suppose there happens to be a step change in current at the input. That might be a step change in the voltage at your resistor input, or a step change in light level falling on a photodiode. The response of the sigma delta is immediate. That is, if the ADC synchronously starts counting at the onset of the step, the count is correct for the new step value at all bit levels. (I'm currently working with a system where the prop controls the flash of a laser and also reads the photodiode response, so it can be synchronous in that manner.) On the other hand, if the ADC sampling is asynchronous, it will take one sampling period for the step to resolve, but that is a digital issue that has nothing to do with the input RC. My point again is that the choice of C does not affect the step or frequency response in the analog domain, pre-delta. The sigma in the prop is done by the summation.

    I know, this does not resolve the issue of how to choose the capacitors!

  9. #9

    Default Re: EasyADC - call for feedback

    Hi, Tracy.

    Thanks for the feedback. I definitely need to think about this some more, but here's my current take on it:

    * regarding the filtering, I was saying that the RC lowpass filter is essentially for the feedback Out pin. As such, it does limit the response speed of counter-driven "keep the common node at 1.65V", so I would think that if the input changes faster than circuit can keep up, I'd have an issue. I will definitely do some experimentation and simulation this coming weekend.

    * regarding the input to the common node actually being a current, that is an excellent point! I was writing this assuming someone wished to measure voltage, but I should definitely include this. (I've used some piezos' current as a cheap electronic drum sensor before in a similar circuit...fun stuff!) Thanks!

    Thanks for all the help & insight!

    Jonathan
    Free time status: see my avatar [8^)
    F32 - fast & concise floating point: OBEX, Thread
    Unrelated to the prop: KISSlicer

  10. #10

    Default Re: EasyADC - call for feedback

    Here is a graphic that I hope shows the effect of the capacitor, and also what I mean about its non-effect as a low-pass filter for the analog input.
    Click image for larger version

Name:	sigmaDeltaSeeSaw1.gif
Views:	96
Size:	11.9 KB
ID:	79955
    The blue line is an exaggerated graph of voltage fluctuations around the threshold associated with three different voltage inputs, 1/2, 3/4 and 7/8 of the power supply voltage Vdd. This assumes that your Rin = Rout, so that the full scale range is nominally 0 to 3.3 V. Feedback holds the Prop input pin close to its threshold, nominally 1.65V. The fluctuations are exaggerated and would normally be much smaller in amplitude, but they are in scale with one another.

    On the left is the case where the summing node input is at Vdd/2, right at threshold, so the voltage across Rin is zero and it contributes no net current. The feedback pin flips with every clock cycle, and the voltage moves up and down accordingly, at clkfreq/2. I won't get quantitative about the amplitude right away, but suffice it to say that the amplitude easy to calculate from the current through Rout, the capacitance, and the clock period.

    The fluctuations have a bit of exponential character, but in this situation a linear approximation will be very good. Also, noise will add a chaotic element to the real, observed pattern, but the average of 50% high and 50% low holds as if it were the ideal pattern. The model system has zero noise and a razor sharp threshold.

    When the input voltage takes a step up to 3/4 * Vdd (red line in the middle segment of the graph), the feedback pin immediately goes into a cycle of 4, with 1 high clock period and 3 low clock periods, a base frequency now of clkfreq/4 instead of clkfreq/2. That comes from charge balance, the requirement that current coming into the summing node has to balance with current leaving. In this case both Rin and Rout enter into the calculation, and it turns out (not surprisingly) that the current when the feedback pin is high is 3 times the current when the feedback pin is low. The voltage cycle around threshold has a steep rise and a slow fall. The amplitude is higher than the previous case, but not by much (* 1.5 to be exact).

    The third step goes up to 7/8 of Vdd. The analysis again comes out with a steep rise and a slow fall, due to resistor currents adding in one direction and subtracting in the other direction. It is a cycle of 8 with a base frequency of clkfreq/8, consisting of 1 high period and 7 low periods, and the amplitude is 7/4 of the amplitude when Vin = Vdd/2.

    As Vin goes closer and closer to the limit at Vdd, the compensating fluctuations continue so long as feedback is capable of maintaining the charge balance. Frequency tends to zero (impossible to filter!) and amplitude goes to twice the value it had when Vin = Vdd/2. (The math is basic Ohm's law and I = C dV/dt).

    The effect of increasing the value of the input capacitor is only to decrease the amplitude of the fluctuations around the threshold, as seen here...
    Click image for larger version

Name:	sigmaDeltaSeeSaw2.gif
Views:	76
Size:	7.6 KB
ID:	79956
    The threshold is ideally razor sharp and detects the transitions no matter how closely they split on either side. The graph below shows a "small" capacitor with small RC on top versus a "big" capacitor with long RC on the bottom. Same timing, squashed amplitude. Conclusion: The input time constant has nothing to do with low-pass filtering the input signal.

    It must be said also that in reality the pattern will be subject to dithering due to noise and the ADC result is an average ratio of high to low that comes out in the count over many cycles. The dithering may be a good thing up to a point.

    Note that there is not a period where the feedback pattern has to "catch up" with the input step due to the time constant of either Rin or Rout with the input capacitor. Depending on where the step happens within one clock period, there may be a brief period of adjustment, but that will resolve within a few clock cycles. Other than that, the pattern associated with the new input level starts immediately, so you might say that the step response is on the same order as clkfreq. Of course, practically that is irrelevant, because nothing can get around the time required to accumulate enough counts for the desired resolution.

    There are situations that can put the system in a state where it takes time to recover. Examples are: 1) taking the input voltage out of range, or 2) replacing the input resistor with a capacitor and trying to feed in an AC square wave (which takes it out of range because I = C dV/dt) or 3) making a sudden change in the value of C (which also takes it out of range, because I = V dC/dt).

    I think the choice of capacitor comes down to second order effects. It has to be large enough to keep the fluctuations small around the threshold. There may be a wide optimum having to do with noise around the threshold. The totem pole input is biased in its linear region at threshold,so it will be generating power supply spikes. Non-ideal characteristics of the capacitor might be important, things like ESR and soakage.

  11. #11

    Default Re: EasyADC - call for feedback

    Tracy, beautiful analysis, thanks!

    I will immediately remove the portion about the speed of the "response to an input" regarding the capacitor value. However, I would still like to make some recommendation as to the minimum value of C (as that seems to be missing from most sigma-delta adc math I've seen, perhaps for good reason!). Do you have a recommendation for a value that will be large enough to keep the fluctuations small around the threshold? This will be a function of at least the clock speed of the counter (so people running at PLL1x would need to adjust their minimum values, for example), and the Rout value.

    Just another quick thought...the larger the value of C, to more the threshold will jump around if there is noise on VDD or GND, right? So I'm guessing there's a "large large enough to keep the fluctuations small around the threshold" factor, but also a "small enough to minimize any effects of noise on the supply lines" factor.

    Again, I really appreciate the feedback, Tracy! Thanks!!

    Jonathan
    Free time status: see my avatar [8^)
    F32 - fast & concise floating point: OBEX, Thread
    Unrelated to the prop: KISSlicer

  12. #12

    Default Re: EasyADC - call for feedback

    Well, I'd like to come up with an answer to that question this time around, but I'm still not sure on what basis. I went back and read through the 5 page thread Troubles with Sigma-Delta ADC, which brought a lot of Prop sigma-delta issues to the fore. It did not resolve the issue of capacitor selection, at least for some of us. There were many contributors, including very interesting thoughts and empirical results from Ray (Rayman--Hey Ray, it still makes me smile to revisit rejoinders to your questioning from the illimitable deSilva!)

    Ray experimented with capacitor values from zero (+ parasitics) up to (his words, responding to Peter Verkaik, middle of page 3): "Peter, I tried using a really big C, and it didn't work very well... Individual samples all had values of 0, 50, or 100%. (This is with DC input). So, I think there must be some upper limit on RC as well, regardless of the input frequency."

    That might have something to do with the less than ideal characteristics of really big C's, and the fact that the Prop threshold is less than razor sharp. Maybe there is small hysteresis due to internal wiring. Question up in the air.

    For the lower limit of capacitor value, another factor may be how closely the signal has to approach to the full scale rails. The period between compensating pulses become longer as the signal approaches full scale, so a larger capacitor value (RC product) is required to keep the voltage within some delta of the threshold. For example, if the signal stays within a factor of 7/8 of the full scale, then the minimum base frequency that has to be filtered is 10 MHz, and the time constant RC should be >> 0.1΅s. Suppose Rin=10k and Rout=10k, parallel equivalent = 5k. That makes RC >> 20pF. So a choice of 470 pF or 1 nF should be good. Probably NPO/COG. A corollary is that signals should be centered around the threshold if possible and avoid coming too close to full scale.

    That is a less stringent requirement than the criterion that involves resolution. There the RC product should be chosen so that the summing node voltage changes at most by one bit during one clock tick, and comes down to RC = 2^n / clkfreq. For R=5k and n=11 bits and clkfreq = 80MHz, that would be C = 5 nF.

    I'm not sure if either of those criteria stand on firm ground or are just rules of thumb.

  13. #13

    Default Re: EasyADC - call for feedback

    Tracy, I just had to read that thread again... Good times...

    I learned a lot from deSilva's comments in other threads. But, in that one, I still don't know for sure what he was trying to say (except that he was right all the time

  14. #14

    Default Re: EasyADC - call for feedback

    Just read through the other thread...seems there's nothing new under the sun (hey, that's a cool quote, bet it's never been used before [8^).

    So, in a politician-style issue dodge, maybe I'll change my writeup to say "Pick the value C so that if you want, you could use the circuit as a DAC with the RC low-pass filter", that way people can use the circuit for multiple purposes. [8^)

    Jonathan
    Free time status: see my avatar [8^)
    F32 - fast & concise floating point: OBEX, Thread
    Unrelated to the prop: KISSlicer

  15. #15

    Default Re: EasyADC - call for feedback

    Tracy Allen:
    Thank you for that link to the old Post. I learned a lot from that.

    Also to note: using what I have learned here from Lonesock, Tracy, and deSilva I have managed to get the poor mans Oscilloscope working on bread board with a 1.2MHz sample rate. This was accomplished using 0.001uf caps, with R1 = 5.6K and R2 = 11.2K, with a signal diode on the input, and a ground line on one side, a Vdd line on the other side of the line between R2 and the connector for the 'Probe'. works great this way, and is stable. I am going to modify my PerfBoard version of the Pore Mans Oscilloscope to reflect these changes and see how well it does. Of course it is limited to measuring positive signals.
    There is no need for Bloated code.May code optimisation return for all.Multi Processing with out interrupts, now anything is possible.RISC-Prop, A RISC OS like System for ARM9 + P8X32A : WIPRISC OS. True Power for ARM based computers.

  16. #16

    Default Re: EasyADC - call for feedback

    If you look at the calcultator on that website I mentioned, there's an "alternate version" link that can help you pick resistors to measure bipolar signals...

  17. #17

    Default Re: EasyADC - call for feedback

    Actually, now that I think about it, the idea lonesock floated about using two different feedback resistors to adjust measurement range could also be used to switch between monopolar and bipolar sampling...

  18. #18

    Default Re: EasyADC - call for feedback

    I do not know how well that would work with the diode.
    Last edited by davidsaunders; 04-08-2011 at 02:44 PM. Reason: Typo
    There is no need for Bloated code.May code optimisation return for all.Multi Processing with out interrupts, now anything is possible.RISC-Prop, A RISC OS like System for ARM9 + P8X32A : WIPRISC OS. True Power for ARM based computers.

  19. #19

    Default Re: EasyADC - call for feedback

    I just posted an updated version, added info about a bias resistor to center the input range around 0. Cheated on my C value recommendation ;-). Etc.

    Jonathan

    P.S. At the risk of hijacking this thread, David, I'd love to help on the scope code, if you'd like...just let me know!
    Free time status: see my avatar [8^)
    F32 - fast & concise floating point: OBEX, Thread
    Unrelated to the prop: KISSlicer

  20. #20

    Default Re: EasyADC - call for feedback

    I am now using the Easy_ADC in the Poor Man's Digital Oscilloscope"

    The only thing I am concerned about is the loop waiting for more to do. That should be wraped around a waitcnt as when doing nothing the cog will be rdlongs on memory as fast as it can affecting the memory bandwidth available for other tasks.

    You can find the latest version at:
    http://forums.parallax.com/showthrea...-Oscilloscope-

    Perry
    Attached Thumbnails Attached Thumbnails Click image for larger version

Name:	PMDO_010.png‎
Views:	79
Size:	29.0 KB
ID:	80059   Click image for larger version

Name:	PMDO_000.png‎
Views:	67
Size:	36.3 KB
ID:	80060  

+ Reply to Thread

Similar Threads

  1. Help! feedback sensors
    By yarisboy in forum Propeller 1 Multicore Microcontroller
    Replies: 0
    Last Post: 06-15-2009, 08:16 PM
  2. Soleniod feedback?
    By Jsav in forum BASIC Stamp
    Replies: 7
    Last Post: 04-23-2009, 04:25 AM
  3. Feedback on schematic please...
    By Jed in forum BASIC Stamp
    Replies: 16
    Last Post: 03-04-2008, 10:01 AM
  4. Haptic Feedback
    By Paul Hoover in forum BASIC Stamp
    Replies: 5
    Last Post: 05-02-2007, 12:53 PM
  5. No feedback from pushbuttons
    By Mauver Olsen in forum Robotics
    Replies: 2
    Last Post: 11-04-2004, 03:49 PM

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts