Shop OBEX P1 Docs P2 Docs Learn Events
Sigma-delta A to D with a 20kHz clock?? — Parallax Forums

Sigma-delta A to D with a 20kHz clock??

Thought I would just check before I spend the time testing. Is it possible to do Sigma-delta Analog to Digital conversion when running the prop with internal clock RCSLOW ~20kHz? I just want to keep an eye on my battery voltage, not looking for a high-resolution solution. I'm pretty sure the answer is no way! But if someone with more experience thought there was a chance, I would give it a try.

The sigma-delta white paper has everything running at 80Mhz.

Comments

  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2017-08-28 17:33
    I don't know why it wouldn't work. It'd be slow, of course, and you'll want much larger RC values. But other than that the principle remains intact with a slow clock.

    -Phil
  • Cool I will get to work. Thanks!
  • MJBMJB Posts: 1,235
    JohnR2010 wrote: »
    Thought I would just check before I spend the time testing. Is it possible to do Sigma-delta Analog to Digital conversion when running the prop with internal clock RCSLOW ~20kHz? I just want to keep an eye on my battery voltage, not looking for a high-resolution solution. I'm pretty sure the answer is no way! But if someone with more experience thought there was a chance, I would give it a try.

    The sigma-delta white paper has everything running at 80Mhz.
    Hi John,
    you know the simple RC test, where you want to measure usually R - but could be C,
    by loading a RC circuit and then timing the pin change?
    with given R & C it should give you a rough indication of the voltage.
  • jmgjmg Posts: 15,173
    JohnR2010 wrote: »
    Thought I would just check before I spend the time testing. Is it possible to do Sigma-delta Analog to Digital conversion when running the prop with internal clock RCSLOW ~20kHz? I just want to keep an eye on my battery voltage, not looking for a high-resolution solution. I'm pretty sure the answer is no way! But if someone with more experience thought there was a chance, I would give it a try.

    Possible ? Yes.
    Is it a good idea ? hmm...
    One issue to check with P1 SigmaDelta is the Pin is operated very close to the threshold and that means transition currents.
    It will take many clocks, all of which have the pin near the threshold.
    ie Try it and Check Icc.

    The other easy ADC is a simple Ramp, and that spends less time at/near the threshold. It can start from 0V, with a grounded cap.
    Tolerance is a little worse, as the threshold voltage is the reference, but calibration would give reasonable performance.

    If that is still too much Icc, you can add external parts, such as a nano-power comparator, or voltage sensing components.

  • jmg wrote:
    One issue to check with P1 SigmaDelta is the Pin is operated very close to the threshold and that means transition currents.
    It will take many clocks, all of which have the pin near the threshold.
    Yes, but the transitions are occurring a kilohertz rates, so I doubt that current consumption will be a big deal. Besides, you only need 256 clocks per read for 8-bit precision.

    -Phil
  • BTW there's a good video on sigma-delta conversion on TheSignalPath youtube channel - he builds one from discrete opamps and a single flip-flop and shows the performance for various clock rates IIRC:

    https://youtube.com/watch?v=z9u-QTDAeaM

    Hop to about 30:00 to see the breadboarded version...
  • jmgjmg Posts: 15,173
    jmg wrote:
    One issue to check with P1 SigmaDelta is the Pin is operated very close to the threshold and that means transition currents.
    It will take many clocks, all of which have the pin near the threshold.
    Yes, but the transitions are occurring a kilohertz rates, so I doubt that current consumption will be a big deal. Besides, you only need 256 clocks per read for 8-bit precision.

    256 clocks at a low 20kHz is a reasonable time, plus you need a lead-in time.
    Also at 20kHz, I'd expect those linear-region currents to be much higher than the Digital Icc. At 80MHz, they matter less.
    So I still say, try it and measure Icc.



  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2017-08-28 21:54
    jmg wrote:
    ... plus you need a lead-in time.
    Yeah, there is that, depending upon the time between reads, cap charge/discharge/leakage rate, etc. A good strategy might be to take several readings until you get two in a row that differ by no more than one or two bits. Of course that depends upon the stability of the measured voltage, too, at 13 ms intervals.

    -Phil
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2017-08-28 22:34
    Another tactic might be to use lower-than-normal RC values. That way each feedback transition will tend to throw the input well into the other side of the logic threshold, rather than straddling the razor's edge. Statistically, the counts over one 256-clock epoch should average out the same -- or not. 'Worth testing, at any rate...

    BTW, I also wondered about the EEPROM current and whether it would be prudent to power it off after IPL. But the CAT24C512, for example, has a quiescent current in the low single-digit microamp range, so no worries there.

    -Phil
  • jmgjmg Posts: 15,173
    Another tactic might be to use lower-than-normal RC values. That way each feedback transition will tend to throw the input well into the other side of the logic threshold, rather than straddling the razor's edge. Statistically, the counts over one 256-clock epoch should average out the same -- or not. 'Worth testing, at any rate...
    Yes, higher amplitude of the triangle/sawtooth would help a little, but even an ideal external integrator cannot exceed +/- 25%.

    For highest precision, I'd use a 2 pin RC ADC, using a Single Cap configuration. (Similar to a HEF4046 Osc)
    = 2 Pins, one Cap, 2 resistors. One R to battery, and one R to Vcc/ref
    Ramp time twice, once for each resistor with other side pulled low, and Ratio Time is VBat/Vcc
    This removes the CAP tolerance and the Vth tolerance effects.

  • Tracy AllenTracy Allen Posts: 6,664
    edited 2017-08-29 04:45
    Had a setup going for something else. Here are a couple of 'scope images that show the output of the following bare-bones sigma-delta feedback program:
    CON
      _clkmode = RCSLOW
    PUB sigma
      dira := $fffb  ' all pins are outputs except p2
      outa := $3000  ' all pins except 28,29 (scl,sda) are low
      ctra := (%01101<<26) + (1<<9) + 2    ' NEGDET for sigma delta
      frqa := 1 . ' would be counting instances of high and low.
      repeat
        waitcnt(0)  
       ' next step, accumulate phsa in reference to system clock, ADC result is ratio.
    
    The NEGDET with feedback is set up with p2 as the summing input (red trace) and p1 as the feedback output (yellow trace).
    They are connected by a 100kohm resistor, and there is a capacitor from p2 to Vss.
    The first image has a capacitor of 100nF and the second image has 10nF.
    The circuit is sitting near it's neutral point, no input signal except for loading by the 'scope probe.
    With 100nF compared to 10nF, the trace sits much closer to the threshold, and the current is indeed higher, 681µA for 100nF versus 235µA with 10nF. And the signal with the 100nF looks a lot messier, but I suspect it will also converge faster to a stable count ratio.
    640 x 480 - 20K
    640 x 480 - 23K
  • Thanks very much everyone. This is more than I hoped for. I should get to this yet this week and will post back my results.
    Here is a little more detail on what I would like to do. I want to measure the battery voltage of my 4 AA batteries in series. They feed my LDO regulator (MCP 1700-30001E). I’m running the prop at 3.0v and was thinking it would be optimal to tune the Sigma-delta circuit to measure between 6.5v and 3v if practical.
    I have two sleep modes. In deep sleep everything (including the LDO regulator) pulls 0.013mA. In standby sleep mode (I have an Ir receiver active) everything pulls 0.341mA. I plan on checking the battery voltage once a day so I can afford a little power then. However, I can’t afford any more current when it is sitting idle. This is a nice to have, so if there is a full time current drain of more than a few microamps I probably won’t use it.
  • Update:
    All works as expected with internal clock RCSLOW (prop running at 20kHz 100% of the time). I used this circuit to measure voltage from my battery. I tuned the circuit to roughly support voltage ranges 7.5v to 3v. The sad part is this circuit added around ~90uA to my deep sleep load. That bumped it up from 13uA to over 100uA. I think I could have tuned it a little more and got the current even lower. But, for this project it is not worth the extra load so I’m going to skip it. Time was well spent, I can see using this in the future.

    Thanks again for everyone's help!


    IMG_0793%5B1%5D.JPG
    CON
      INP_PIN       = 0             'Counter input pin for sigma-delta.
      FB_PIN        = 1             'Counter feedback pin for sigma-delta.
      ADC_INTERVAL  = 512           'Time interval over which to accumulate counts. 
      BtnPin        = 25
    
      OkThold       = 255           ' aValue below this number considered a low battery.
        
    VAR
      long cog
    
      ' Do not change the order of the following:
      long aValue
    
    
    PUB Start(logAdd) : okay
      '**************************************
      ' logAdd is the address of a byte sized value to watch and display on eight LEDs
      '
      ' Returns oaky = cog number + 1
      '**************************************
      lg := logAdd
      
      Stop
      cog := okay := cognew(@adcStart, @aValue) + 1       'Launch new cog  
      return okay
    
    PUB Stop
      '**************************************
      ' Stop cog
      '**************************************  
      if cog
        cogstop(cog - 1)
        cog := 0
    
    PUB IsBatOkay
      if aValue > OkThold
        return 1                    'Okay
      else
        return 0
    
    PUB GetRawValue
      return aValue
    
    DAT
                            org       0
    adcStart
                            mov     t1, #3
                            wrlong  t1, lg
                            
                            mov     frqa,#1                 'Initialize frqa to count up by one.
                            movi    ctra,#%0_01001_000      'Set ctra mode to positive w/feedback.
                            movd    ctra,#FB_PIN            'Write fback pin number to dst field.
                            movs    ctra,#INP_PIN           'Write input pin number to src field.
                            mov     dira,fb_mask            'Make the feedback pin an output.
                            mov     result_addr,par         'Save @value into result_addr.
    
    main_loop               call    #adc                    'Get a new acquisition.
                            wrlong  acc,result_addr         'Write result to hub.
                            'mov     slong, acc
                            'call    #showLong
                            jmp     #main_loop              'Back for another.
    
    adc                     mov     time,cnt                'Get the current counter value.
                            add     time,#16                'Add a little to get ahead.
                            waitcnt time,interval           'Sync to clock; add interval to time.
                            neg     acc,phsa                'Negate phsa into result.
                            waitcnt time,#0                 'Wait for interval to pass.
                            add     acc,phsa                'Add phsa into result.
    adc_ret                 ret
    
    showLong                                        '' set slong = to long value to log to 8 leds a byte at a time
                            wrlong  slong, lg
                            waitpeq BtnSt, Bmask
                            waitpne BtnSt, Bmask
    
                            shr     slong, #8
                            wrlong  slong, lg
                            waitpeq BtnSt, Bmask
                            waitpne BtnSt, Bmask
    
                            shr     slong, #8
                            wrlong  slong, lg
                            waitpeq BtnSt, Bmask
                            waitpne BtnSt, Bmask
    
                            shr     slong, #8
                            wrlong  slong, lg
                            waitpeq BtnSt, Bmask
                            waitpne BtnSt, Bmask
    showLong_ret            ret
    
    
    ' Data
    fb_mask                 long 1 << FB_PIN                'Mask for feedback pin.
    result_addr             long 0-0                        'Result address gets plugged in here.
    interval                long ADC_INTERVAL               'Acquisition time.
    
    
    ' My additions follow
    BtnSt                   long 0
    Bmask                   long |< BtnPin
    
    
    ' set the following before starting cog
    lg                      long 0                          ' Set this to address of the logging address before starting cog  
    
    slong                   res     1
    t1                      res     1
    acc                     res     1                       'General-purpose accumulator.
    time                    res     1                       'Time variable use for waitcnt.
    
       
                            fit   496
    
    4032 x 3024 - 2M
  • Maybe multiply your resistors, and divide your caps, by 10?

    -Phil
  • jmgjmg Posts: 15,173
    edited 2017-08-31 21:09
    JohnR2010 wrote: »
    The sad part is this circuit added around ~90uA to my deep sleep load. That bumped it up from 13uA to over 100uA.


    Two effects to watch out for :

    a) Simple divider currents 7.5/(150k+56k) = 36.4uA

    and, you also need to avoid linear region currents, in idle.

    b) 7.5*56/(56+150) = 2.03V, that's not close enough to Vcc or GND to avoid extra currents.

    As Phil mentions, bump the R's by 10 and the a) can drop by 10.
    b) can be mitigated by simply removing the now 560k, and lower the now 1M feedback to keep 7.5V upper point. (~390k?)
    The ADC operate point shifts slightly, but that's only an offset.

    Make P1=H when disabled, and check if P0 driven H in disable, has any effect on current.

    You need to check the 1.5M clamp current, to make sure it cannot lift up the 3v3
    (7.5-(3.3+0.6))/(1.5M) = 2.4uA - with the bottom R removed, this should be your new disable current.

    I think is OK if you draw more than that from 3v3.
  • Tracy AllenTracy Allen Posts: 6,664
    edited 2017-08-31 22:35
    Nice indeed.

    Are those capacitors 10nF or 10µF? Sorry, can't read it! Vcc=3.0V, right?

    Increase the input resistor R3 to 1M, but make the feedback resistor, R1 = 250k. And remove R2, the one to Vss.
    That makes the gain (R1/R3)=1/4 and the the total range becomes -4.5V to +7.5V. Good enough for battery monitoring.
    That eliminates current lost through R2.

    No need for continuous measurement.
    During quiescent intervals, make the feedback pin and the input pin high outputs. Then current from the battery (4.5 µA maximum) will flow into the power supply and contribute to running the Prop, not wasted.

    Pretty much what jmg said.



  • To avoid battery drain, do not use Sigma Delta to measure voltage of battery.
    Use RC Time instead. When using RC Time, there is no need for a voltage divider.

    For example you can use a 6M Ohm resistor to charge a 1uF capacitor.
    Measure the time it takes to charge to calculate the voltage of the battery.
  • John,
    How stable is the reading you get with that setup, ENOB?
  • I decided to give her another try since I got such great feedback. I went with Dr. Allen’s suggestions that were all very close to JMG’s and Phil’s input. I now get about a 1uA hit with the new sigma delta circuit. After I take my measurement I stop my cog and float both delta sigma pins. I will do more testing with them held high next week.
    Here is a snapshot of my new delta sigma schematic, the output in binary, and my bread board circuit. To see the results, I shift the long out to eight LEDs one byte at a time in little endian format.

    With the PASM above I get sigma delta values of: 338=3.0v, 443=5.0v, 481=5.8v. This is enough resolution for my needs. I will do more testing next week when my new variable power supply gets here.

    Thanks everyone for the input!!

    IMG_0796%5B1%5D.jpg
    3024 x 4032 - 1M
Sign In or Register to comment.