SOLVED: How can I reduce ADC jitter


+ Reply to Thread
Results 1 to 40 of 96

Hybrid View

  1. #1
    Join Date
    May 2013
    Location
    australia
    Posts
    2,645


    Did you find this post helpful? Yes | No

    Default Re: SOLVED: How can I reduce ADC drift

    i tried the burst mode averaging method. very nice if you don't need the adc for anything else, it would be ideal for monitoring a lifepo4 battery during all phases of discharge/charging/float. no great advantage for multiple inputs that i can see
    Warning I'm not a teacher

  2. #2
    Join Date
    Jan 2005
    Location
    Montreal, Quebec, Canada
    Posts
    3,170


    Did you find this post helpful? Yes | No

    Default Re: SOLVED: How can I reduce ADC drift

    Quote Originally Posted by richard View Post
    i tried the burst mode averaging method. very nice if you don't need the adc for anything else, it would be ideal for monitoring a lifepo4 battery during all phases of discharge/charging/float. no great advantage for multiple inputs that i can see
    I'm going to see about using something like your MEAN average example. I had something like that a while ago (inspired by Melanie), but I had noisy power supplies. The TPS56637 works nicely, so I was hoping ADC2 could make my life easier.
    My Creality Ender 3 S1 Plus is a giant paperweight that can't even be used as a boat anchor, cause I'd be fined for polluting our waterways with electronic devices.

    Not as dumb as yesterday, but stupider than tomorrow!

  3. #3
    Join Date
    May 2013
    Location
    australia
    Posts
    2,645


    Did you find this post helpful? Yes | No

    Default Re: SOLVED: How can I reduce ADC drift

    I only have a few 1000uF electrolytics, so I put 2 on each rail, same ADC flutter of mostly 1, sometimes 2.
    +- 2 counts is as good as it will ever get for raw adc reads on a breadboard, if you right shift 2 bits that's a 256 count resolution that should be very stable

    the scope is your friend here , measure the AC noise. every 5mV of noise on the rail and/or the pot wiper is +- 1 more count
    Warning I'm not a teacher

  4. #4
    Join Date
    May 2013
    Location
    australia
    Posts
    2,645


    Did you find this post helpful? Yes | No

    Default Re: SOLVED: How can I reduce ADC drift

    note some of the variations you are calling flutter are actually "Quantization noise" and can never be eliminated from the adc process,
    the best adc result is always +-1 count. at the expense of some resolution[level bandwidth etc] you can filter it out "mostly" people with "hifi" ears reckon they can hear it on the best of cd recoding's , yet scratched vinyl records are pure, go figure. as a true cloth eared pariah i call wtf
    Warning I'm not a teacher

  5. #5
    Join Date
    Nov 2003
    Location
    Greece
    Posts
    4,133


    Did you find this post helpful? Yes | No

    Default Re: SOLVED: How can I reduce ADC drift

    On a PCB of a irrelevant project I tested the simple ADCin and display the result on the LCD.

    As Richard says the +/-1 LSB is what I get with no process. Occasionaly 2 LSBs.

    I just sample every sec. and display it.

    Of course the PCB is double sided with lot of ground, a cap on the ADC input pin and linear 5Volt regulator. So any external noise is minimized.

    Breadboards are just a noise antennas and never give clean results.

    Ioannis

  6. #6
    Join Date
    Jan 2005
    Location
    Montreal, Quebec, Canada
    Posts
    3,170


    Did you find this post helpful? Yes | No

    Default Re: SOLVED: How can I reduce ADC drift

    Ultimately, the system has to be able to read ADC while managing to 2-3 LED strips and 4 LCDs with PWM.

    I'm trying a double PSU approach to see if the input PIC (right) can keep line noise to a minimum, and have all output functions on the output PIC (left).

    Input functions will consume very little current, it's the output functions that will consume a lot more, and have multiple PWMs.

    Name:  Dual PSU.jpg
Views: 29815
Size:  178.3 KB


    The only unknown is the rotary encoders; no idea if their rapid ON-OFF will create noise. I can always move them over to the output PIC.

    At worse, I'd end up with a "clean" PIC, and a "noisy" PIC instead of input/output.
    My Creality Ender 3 S1 Plus is a giant paperweight that can't even be used as a boat anchor, cause I'd be fined for polluting our waterways with electronic devices.

    Not as dumb as yesterday, but stupider than tomorrow!

  7. #7
    Join Date
    Jan 2005
    Location
    Montreal, Quebec, Canada
    Posts
    3,170


    Did you find this post helpful? Yes | No

    Default Re: SOLVED: How can I reduce ADC drift

    I've gone back to getting a "basic" ADC routine working for 1 voltage-divider and 2 pots (for a better sampling).

    Code:
    #CONFIG
        __config _CONFIG1, _FEXTOSC_OFF & _RSTOSC_HFINT32 & _CLKOUTEN_OFF & _CSWEN_OFF & _FCMEN_ON
        __config _CONFIG2, _MCLRE_ON & _PWRTE_OFF & _LPBOREN_OFF & _BOREN_ON & _BORV_LO & _ZCD_OFF & _PPS1WAY_OFF & _STVREN_ON & _DEBUG_OFF
        __config _CONFIG3, _WDTCPS_WDTCPS_11 & _WDTE_OFF & _WDTCWS_WDTCWS_7 & _WDTCCS_LFINTOSC
        __config _CONFIG4, _WRT_OFF & _SCANE_available & _LVP_OFF
        __config _CONFIG5, _CP_OFF & _CPD_OFF
    #ENDCONFIG
    
    DEFINE OSC 32
    
    DEFINE  ADC_BITS 10                 ' 10-bit Analog to digital
    DEFINE  ADC_SAMPLEUS 50             ' Set sampling time in uS
    
    DEFINE  HSER_RXREG PORTC
    DEFINE  HSER_RXBIT 7
    DEFINE  HSER_TXREG PORTC
    DEFINE  HSER_TXBIT 6
    
    DEFINE  HSER_RCSTA 90h              ' Enable serial port & continuous receive
    DEFINE  HSER_TXSTA 24h              ' Enable transmit, BRGH = 1
    Define  HSER_BAUD 115200
    DEFINE  HSER_CLROERR 1              ' Clear overflow automatically
    DEFINE  HSER_SPBRGH  0
    DEFINE  HSER_SPBRG  68
    
    ;--- Setup registers -----------------------------------------------------------
    
    BAUDCON.3 = 1                       ' Enable 16 bit baudrate generator
    
    FVRCON = %10000011                  ' FIXED VOLTAGE REFERENCE CONTROL REGISTER
    '   bit 7   FVREN: Fixed Voltage Reference Enable bit
    '       --->    1 = Fixed Voltage Reference is enabled
    '   bit 1-0 ADFVR<1:0>: ADC FVR Buffer Gain Selection bit
    '       --->    11 = ADC FVR Buffer Gain is 4x, (4.096V)(2)
    
    ADCON0 = %10000100                  ' ADC CONTROL REGISTER 0
    '   bit 7   ADON: ADC Enable bit
    '        --->   1 = ADC is enabled
    '   bit 2   ADFRM0: ADC results Format/alignment Selection
    '        --->   1 = ADRES and ADPREV data are right-justified
    
    ADCON2 = %00000000                  ' ADC CONTROL REGISTER 2
    '   bit 2-0 ADMD<2:0>: ADC Operating Mode Selection bits(1)
    '        --->   000 = Basic (Legacy) mode
    
    ADCLK = %00111111                   ' ADC CLOCK SELECTION REGISTER
    '   bit 5-0 ADCCS<5:0>: ADC Conversion Clock Select bits
    '        --->   111111 = FOSC/128
    
    ADREF = %00000011                   ' ADC REFERENCE SELECTION REGISTER
    '   bit 4 ADNREF: ADC Negative Voltage Reference Selection bit
    '        --->   0 = VREF- is connected to AVSS
    '   bit 1-0 ADPREF: ADC Positive Voltage Reference Selection bits
    '        --->   11 = VREF+ is connected to FVR_buffer 1
    
    ADPCH = %00000000                   ' ADC POSITIVE CHANNEL SELECTION REGISTER
    '        --->   000000 = ANA0
    
    ANSELA = %00000111                      ' Pin A2 = ADC (B5K)
                                            ' Pin A1 = ADC (B5K)
                                            ' Pin A0 = ADC (voltage divider)
    ANSELB = %00000000
    ANSELC = %00000000
    
    TRISA = %00000111                       ' Pin A2 = ADC input 2
                                            ' Pin A1 = ADC input 1
                                            ' Pin A0 = ADC input 0
    TRISB = %00000000                       ' Pin B7 = ...not available, ICSPDAT
                                            ' Pin B6 = ...not available, ICSPCLK
    TRISC = %11000000                       ' Pin C7 = RX      *** Datasheet requirement, INPUT ***
                                            ' Pin C6 = TX      *** Datasheet requirement, INPUT ***
    
    ADCinput            var WORD
    ADCtot              var WORD
    ADCcalc             var WORD
    ADCdiff             var WORD
    ADCLoop             VAR BYTE
    OldADC0             var WORD
    OldADC1             var WORD
    OldADC2             var WORD
    
        Pause 500                           ' Let PIC and LCD stabilize
        ADCinput = 0    : ADCdiff = 0
        OldADC0 = 9999  : OldADC1 = 9999  : OldADC2 = 9999
    
    Mainloop:
    
    rem                 ADC0, 4K7-4K7 voltage divider
    
        adcin 0, ADCinput : Pauseus 1               ' preliminary ADCIN to establish channel used
        ADCtot = 0
    
        FOR ADCLoop = 0 TO 15                       ' Load 16 ADC values
            adcin 0, ADCinput : Pauseus 1
            ADCtot = ADCtot + ADCinput
        NEXT ADCLoop
        ADCcalc = ADCtot / 16                       ' Average out
    
        if ADCcalc < oldADC0 then                   ' Calculate change in ADC
            ADCdiff = oldadc0 - ADCcalc
        else
            ADCdiff =  ADCcalc - oldadc0
        endif
    
        IF  (ADCdiff > 2) or _                      ' Check for Diff over 2 ... OR
           ((adccalc <> oldadc0) and _              '   ADC value changed ...   AND
             (adccalc = 0 or adccalc = 1023)) then  '   Reached end of rotation
            hserout [   "OldADC0:",     DEC4 oldadc0, "  ", _
                        "                            ", _
                        "ADCin:",       DEC4 ADCcalc, "  ", _
                        "Diff:",        dec4 ADCdiff, "  ", _                        
                        "Sum:",         Dec5 ADCtot, 10]                             
            while TXSTA.1 = 0               ' Check TRMT bit
            wend
            oldADC0 = ADCcalc
        endif
     
    rem                 ADC1, B5K pot
    
        adcin 0, ADCinput : Pauseus 1               ' preliminary ADCIN to establish channel used
        ADCtot = 0
    
        FOR ADCLoop = 0 TO 15                       ' Load 16 ADC values
            adcin 1, ADCinput : Pauseus 1
            ADCtot = ADCtot + ADCinput
        NEXT ADCLoop
        ADCcalc = ADCtot / 16                       ' Average out
    
        if ADCcalc < oldADC1 then                   ' Calculate change in ADC
            ADCdiff = oldadc1 - ADCcalc
        else
            ADCdiff =  ADCcalc - oldadc1
        endif
    
        IF  (ADCdiff > 2) or _                      ' Check for Diff over 2 ... OR
           ((adccalc <> oldadc1) and _              '   ADC value changed ...   AND
             (adccalc = 0 or adccalc = 1023)) then  '   Reached end of rotation
            hserout [   "              ", _
                        "OldADC1:",     DEC4 oldadc1, "  ", _
                        "              ", _
                        "ADCin:",       DEC4 ADCcalc, "  ", _
                        "Diff:",        dec4 ADCdiff, "  ", _                        
                        "Sum:",         Dec5 ADCtot, 10]                             
            while TXSTA.1 = 0               ' Check TRMT bit
            wend
            oldADC1 = ADCcalc
        endif
    
    rem                 ADC2, B5K pot
    
        adcin 2, ADCinput : Pauseus 1               ' preliminary ADCIN to establish channel used
        ADCtot = 0
    
        FOR ADCLoop = 0 TO 15                       ' Load 16 ADC values
            adcin 2, ADCinput : Pauseus 1
            ADCtot = ADCtot + ADCinput
        NEXT ADCLoop
        ADCcalc = ADCtot / 16                       ' Average out
    
        if ADCcalc < oldADC2 then                   ' Calculate change in ADC
            ADCdiff = oldadc2 - ADCcalc
        else
            ADCdiff =  ADCcalc - oldadc2
        endif
    
        IF  (ADCdiff > 2) or _                      ' Check for Diff over 2 ... OR
           ((adccalc <> oldadc2) and _              '   ADC value changed ...   AND
             (adccalc = 0 or adccalc = 1023)) then  '   Reached end of rotation
            hserout [   "                            ", _
                        "OldADC2:",     DEC4 oldadc2, "  ", _
                        "ADCin:",       DEC4 ADCcalc, "  ", _
                        "Diff:",        dec4 ADCdiff, "  ", _                        
                        "Sum:",         Dec5 ADCtot, 10]                             
            while TXSTA.1 = 0               ' Check TRMT bit
            wend
            oldADC2 = ADCcalc
        endif
    
      GOTO Mainloop
    
    end

    Checklist:

    - PIC 16F18855,
    - used legacy ADC (no ADC2),
    - did not touch VREFs,
    - used FVR 4x with 5 VDC in,
    - used FOSC / 128,
    - used average of 16 ADC readings,
    - removed all LCD logic (used for debugging),
    - used USART to show results
    - added PAUSEUS 1 after all ADC operations - THIS NEEDS TO BE VERIFIED IF IT'S NECESSARY, it was just to make sure things worked.


    ADC readings on the voltage-divider and 2 rotary pots did not "drift/vary/whatever" more than 2.

    I still have to:

    - try with slide pots, just to see if that fixed their "irregularities" that I experienced in the past.
    - reconnect the 2nd breadboard that displays to LCD with backlight PWM, and PWMs 2 LED strips.


    EDIT: This was working perfectly with the voltage divider (ADC0) and pot 2 (ADC2), now that I've put back in pot 1 (ADC1), the 2 pots don't reach 0 and stop at 2.

    ARGH...
    Last edited by Demon; - 3rd March 2025 at 03:16.
    My Creality Ender 3 S1 Plus is a giant paperweight that can't even be used as a boat anchor, cause I'd be fined for polluting our waterways with electronic devices.

    Not as dumb as yesterday, but stupider than tomorrow!

Similar Threads

  1. SOLVED - IOC works on B0 but not B5
    By Demon in forum General
    Replies: 19
    Last Post: - 26th September 2024, 21:11
  2. Replies: 6
    Last Post: - 5th November 2023, 16:26
  3. trying to reduce current consumption on a 12HV615
    By Max Power in forum mel PIC BASIC Pro
    Replies: 8
    Last Post: - 30th November 2011, 14:57
  4. Unwanted output signal jitter
    By LinkMTech in forum mel PIC BASIC Pro
    Replies: 20
    Last Post: - 18th January 2008, 02:31
  5. Dmx Solved !!!!!!!
    By oscar in forum mel PIC BASIC Pro
    Replies: 18
    Last Post: - 2nd July 2005, 21:57

Members who have read this thread : 17

You do not have permission to view the list of names.

Posting Permissions

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