-
Re: SOLVED: How can I reduce ADC drift
if your scope probes are ac coupled to measure rail noise [ as they should be ] then the DC offsets visible on the scope are not coming from your circuit the scope provides them , the drift you see is random, for stability each and every scope probe gnd reference lead needs to be connected to the same point
ps warning , do not try to measure rails that don't share a common gnd reference , or exceed the scopes safe working voltage
-
Re: SOLVED: How can I reduce ADC drift
raw adc readings of x + or - 1 count is as good as it ever gets
+-2 is very good +-3 is typical result for a designed system
what are your expectations ?
-
Re: SOLVED: How can I reduce ADC drift
Added DEFINE and doubled the ADCIN, no change really.
But I did notice a vulnerability in my system. Watch this when I gently touch power leads to the rails.
https://youtu.be/U4qEg-o7FGg
-
Re: SOLVED: How can I reduce ADC drift
the problem you see does not exist , its the scopes reaction to having an large antenna [YOUR HAND] capacitively coupled to all of its inputs providing an overwhelming signal on it most sensitive ac input range, the scope is unable to provide the dc bias needed to keep the traces aligned in the overwhelmed state
-
Re: SOLVED: How can I reduce ADC drift
Quote:
Originally Posted by
richard
the problem you see does not exist , its the scopes reaction to having an large antenna [YOUR HAND] capacitively coupled to all of its inputs providing an overwhelming signal on it most sensitive ac input range, the scope is unable to provide the dc bias needed to keep the traces aligned in the overwhelmed state
Excellent, so this won't be an issue since the drop-down circuit will be linked directly the the main board by headers.
-
Re: SOLVED: How can I reduce ADC drift
making any measurements on a dc signal other than the ac noise level using a scope that is ac coupled to the dc signal is meaningless
-
Re: SOLVED: How can I reduce ADC drift
Quote:
Originally Posted by
richard
if your scope probes are ac coupled to measure rail noise [ as they should be ] then the DC offsets visible on the scope are not coming from your circuit the scope provides them , the drift you see is random, for stability each and every scope probe gnd reference lead needs to be connected to the same point
ps warning , do not try to measure rails that don't share a common gnd reference , or exceed the scopes safe working voltage
Ok.
All rails come from the same source; 5VDC.
And they all share the ground to that circuit.
-
Re: SOLVED: How can I reduce ADC drift
Quote:
Originally Posted by
richard
raw adc readings of x + or - 1 count is as good as it ever gets
+-2 is very good +-3 is typical result for a designed system
what are your expectations ?
Coupling changed to AC.
1. Honestly I expected no jitter on the voltage-divider, thinking FVR would remove 1/2 the instability, leaving only VS as a variable source for comparison.
2. As for the pots, I had no idea what "realistic" is, they don't mention that in google tutorials.
3. I'm sure I could get something useful out of 10-bit results. Just not sure how to go about massaging the result.
4. I also would have liked to try the ADC2 feature like AVERAGE. I assume it'a a hardware equivalent of what Melanie was doing.
-
Re: SOLVED: How can I reduce ADC drift
Code:
ADCshift = NewADC0 >> 2
I shifted the results 2 bits, expecting to lose any jitter from 0 - 3, but I still get jitter.
I bet it's when a number jumps an upper bit, like 00100011 to 01000100.
I'm using 10-bit ADC, so chopping 2 bits already bring me down to 256 increments.
Bringing it down more won't solve when it's a higher jump, like 00111111 to 01000000
EDIT: Divide by 4 doesn't help either, I still get jitter, even on the voltage-divider.
-
Re: SOLVED: How can I reduce ADC drift
Quote:
Coupling changed to AC.
to measure ac noise on rail , noise hopefully in mV and not to many of them
Quote:
Coupling changed to DC.
for any dc , logic measurements
Quote:
1. Honestly I expected no jitter on the voltage-divider, thinking FVR would remove 1/2 the instability, leaving only VS as a variable source for comparison.
raw adc will never have no jitter
Quote:
2. As for the pots, I had no idea what "realistic" is, they don't mention that in google tutorials.
the word you want here is resolution, if you had a 1k pot and 10 bit adc you could resolve it to 1 ohm steps in theory
but adc is always has +- count , jitter free might get to 255 steps, you need to design for the outcome desired
Quote:
3. I'm sure I could get something useful out of 10-bit results. Just not sure how to go about massaging the result.
depending on noise and needed resolution there are ways , from simple division, averaging or oversampling
Quote:
4. I also would have liked to try the ADC2 feature like AVERAGE. I assume it'a a hardware equivalent of what Melanie was doing.
its not designed to average more than one ch and need exclusive use of the adc but have a go
-
Re: SOLVED: How can I reduce ADC drift
changing my test to rs 2 digits
jitter negligible
Code:
mean 159
readings
0000,0000,0000,0000,0000,0000,0000,0000,0000,0000 3596 0004,0000,0000,0000,0000,0000,0000,0000,0000,0000
outliers 0000
mean 159
readings
0000,0000,0000,0000,0000,0000,0000,0000,0000,0000 3600 0000,0000,0000,0000,0000,0000,0000,0000,0000,0000
outliers 0000
mean 159
readings
0000,0000,0000,0000,0000,0000,0000,0000,0000,0000 3598 0002,0000,0000,0000,0000,0000,0000,0000,0000,0000
outliers 0000
mean 159
Code:
#CONFIG __config _CONFIG1, _FEXTOSC_OFF & _RSTOSC_HFINT32 & _CLKOUTEN_OFF & _CSWEN_ON & _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_ON & _WDTCWS_WDTCWS_7 & _WDTCCS_LFINTOSC
__config _CONFIG4, _WRT_OFF & _SCANE_available & _LVP_ON
__config _CONFIG5, _CP_OFF & _CPD_OFF
#ENDCONFIG
DEFINE OSC 32
DEFINE DEBUG_REG PORTD
DEFINE DEBUG_BIT 2 ; if not used for pwr
DEFINE DEBUG_BAUD 9600
DEFINE DEBUG_MODE 0
DEFINE ADC_BITS 10 ' 10-bit Analog to digital
DEFINE ADC_SAMPLEUS 50 ' Set sampling time in uS
ANSELA = % 00000001 ' Pin A0 = ADC
TRISA = % 11101111 ' Pin A4 = LED
TRISD = % 11111011 ' DEBUG
LATD.2 = 1 ' DEBUG
clear
LED VAR LATA.4
i var byte
j var word
bucket var WORD
ADCinput var WORD
mean var WORD
buckets var word[21]
outlier var WORD
LED = 1 'Proof of Life
PAUSE 2000
DEBUG 13,10,"READY",13,10
FVRCON = % 10000011
ADCON0 = % 10010100
ADREF = % 00000000
ADPRE = 48
ADCLK = 32
ADCAP = 31
LED=0
Mainloop:
mean = 0
for i = 0 to 9
ADCIN 0, ADCinput
mean = mean + ADCinput
next
mean = mean/40 ;average divide 4
DEBUG "mean ",DEC mean,13,10
for j = 0 to 3599
ADCIN 0, ADCinput
ADCinput=ADCinput>>2
bucket = mean-ADCinput
i = bucket + 10
if i>20 then
outlier = outlier + 1
else
buckets[i]=buckets[i] + 1
endif
'DEBUG 13,10,"mean ",DEC mean," i ",dec i," read ",dec ADCinput,13,10
PAUSE 5
next
DEBUG "readings " ,13,10
DEBUG dec4 buckets[0],",", dec4 buckets[1],"," , dec4 buckets[2],",", dec4 buckets[3],"," , dec4 buckets[4],","
DEBUG dec4 buckets[5],",", dec4 buckets[6],"," , dec4 buckets[7],",", dec4 buckets[8],"," , dec4 buckets[9]," "
DEBUG dec4 buckets[10]," "
DEBUG dec4 buckets[11],",", dec4 buckets[12],"," , dec4 buckets[13],",", dec4 buckets[14],"," , dec4 buckets[15],","
DEBUG dec4 buckets[16],",", dec4 buckets[17],"," , dec4 buckets[18],",", dec4 buckets[19],"," , dec4 buckets[20],13,10
DEBUG "outliers ",dec4 outlier
DEBUG 13,10
for i = 0 to 20
buckets[i] = 0
next
outlier = 0
GOTO Mainloop
end
-
Re: SOLVED: How can I reduce ADC drift
using the fvr gets slightly better result [mine is a 3.3v system]
Code:
mean 255
readings
0000,0000,0000,0000,0000,0000,0000,0000,0000,0000 3600 0000,0000,0000,0000,0000,0000,0000,0000,0000,0000
outliers 0000
mean 255
readings
0000,0000,0000,0000,0000,0000,0000,0000,0000,0000 3600 0000,0000,0000,0000,0000,0000,0000,0000,0000,0000
outliers 0000
mean 255
readings
0000,0000,0000,0000,0000,0000,0000,0000,0000,0000 3600 0000,0000,0000,0000,0000,0000,0000,0000,0000,0000
outliers 0000
mean 255
readings
0000,0000,0000,0000,0000,0000,0000,0000,0000,0000 3600 0000,0000,0000,0000,0000,0000,0000,0000,0000,0000
outliers 0000
mean 255
readings
0000,0000,0000,0000,0000,0000,0000,0000,0000,0000 3600 0000,0000,0000,0000,0000,0000,0000,0000,0000,0000
outliers 0000
mean 255
Code:
#CONFIG __config _CONFIG1, _FEXTOSC_OFF & _RSTOSC_HFINT32 & _CLKOUTEN_OFF & _CSWEN_ON & _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_ON & _WDTCWS_WDTCWS_7 & _WDTCCS_LFINTOSC
__config _CONFIG4, _WRT_OFF & _SCANE_available & _LVP_ON
__config _CONFIG5, _CP_OFF & _CPD_OFF
#ENDCONFIG
DEFINE OSC 32
DEFINE DEBUG_REG PORTD
DEFINE DEBUG_BIT 2 ; if not used for pwr
DEFINE DEBUG_BAUD 9600
DEFINE DEBUG_MODE 0
DEFINE ADC_BITS 10 ' 10-bit Analog to digital
DEFINE ADC_SAMPLEUS 50 ' Set sampling time in uS
ANSELA = % 00000001 ' Pin A0 = ADC
TRISA = % 11101111 ' Pin A4 = LED
TRISD = % 11111011 ' DEBUG
LATD.2 = 1 ' DEBUG
clear
LED VAR LATA.4
i var byte
j var word
bucket var WORD
ADCinput var WORD
mean var WORD
buckets var word[21]
outlier var WORD
LED = 1 'Proof of Life
PAUSE 2000
DEBUG 13,10,"READY",13,10
FVRCON = % 10000010;2.048v
ADCON0 = % 10000100
ADREF = % 00000011,fvr
ADCLK = 16; faster clk
LED=0
Mainloop:
mean = 0
for i = 0 to 9
ADCIN 0, ADCinput
mean = mean + ADCinput
next
mean = mean/40
DEBUG "mean ",DEC mean,13,10
for j = 0 to 3599
ADCIN 0, ADCinput
ADCinput=ADCinput>>2
bucket = mean-ADCinput
i = bucket + 10
if i>20 then
outlier = outlier + 1
else
buckets[i]=buckets[i] + 1
endif
'DEBUG 13,10,"mean ",DEC mean," i ",dec i," read ",dec ADCinput,13,10
PAUSE 5
next
DEBUG "readings " ,13,10
DEBUG dec4 buckets[0],",", dec4 buckets[1],"," , dec4 buckets[2],",", dec4 buckets[3],"," , dec4 buckets[4],","
DEBUG dec4 buckets[5],",", dec4 buckets[6],"," , dec4 buckets[7],",", dec4 buckets[8],"," , dec4 buckets[9]," "
DEBUG dec4 buckets[10]," "
DEBUG dec4 buckets[11],",", dec4 buckets[12],"," , dec4 buckets[13],",", dec4 buckets[14],"," , dec4 buckets[15],","
DEBUG dec4 buckets[16],",", dec4 buckets[17],"," , dec4 buckets[18],",", dec4 buckets[19],"," , dec4 buckets[20],13,10
DEBUG "outliers ",dec4 outlier
DEBUG 13,10
for i = 0 to 20
buckets[i] = 0
next
outlier = 0
GOTO Mainloop
end
-
Re: SOLVED: How can I reduce ADC drift
Quote:
Originally Posted by
richard
...its not designed to average more than one ch and need exclusive use of the adc but have a go
Quote:
23.0 ANALOG-TO-DIGITAL CONVERTER WITH COMPUTATION (ADC2) MODULE
The Analog-to-Digital Converter with Computation (ADC2) allows conversion of an analog input signal to a 10-bit binary representation of that signal. This device uses analog inputs, which are multiplexed into a single sample and hold circuit.
We can't switch ADPCH manually between each Average?
About that bug to ADCIN twice:
Quote:
23.1 ADC Configuration
Note: It is recommended that when switching from an ADC channel of a higher voltage to a channel of a lower voltage, the software selects the VSS channel before switching to the channel of the lower voltage.
I'm trying to switch ADPCH to 111100 = AVSS (Analog Ground) before each ADCIN to see if that fixes the problem.
They seem to mean when you change power rail, but maybe there's a bug when "the higher voltage" is within the same rail (like changing from 1V up to 4V).
I haven't studied your code yet, this is where I am at trying to get FVR and Average:
Quote:
#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 LCD_DREG PORTB ' Set LCD data port
DEFINE LCD_DBIT 0 ' Set starting data bit
DEFINE LCD_RSREG PORTC ' Set LCD register select port
DEFINE LCD_RSBIT 4 ' Set LCD register select bit
DEFINE LCD_EREG PORTC ' Set LCD enable port
DEFINE LCD_EBIT 5 ' Set LCD enable bit
DEFINE LCD_BITS 4 ' Set LCD bus size
DEFINE LCD_LINES 4 ' Set number of lines on LCD
DEFINE LCD_COMMANDUS 1000 ' Set command delay time in microseconds
DEFINE LCD_DATAUS 50 ' Set data delay time in microseconds
FVRCON = %10000011 ' FIXED VOLTAGE REFERENCE CONTROL REGISTER
' bit 7 FVREN: Fixed Voltage Reference Enable bit
' ---> 1 = Fixed Voltage Reference is enabled
' 0 = Fixed Voltage Reference is disabled
' bit 6 FVRRDY: Fixed Voltage Reference Ready Flag bit(1)
' 1 = Fixed Voltage Reference output is ready for use
' 0 = Fixed Voltage Reference output is not ready or not enabled
' bit 5 TSEN: Temperature Indicator Enable bit(3)
' 1 = Temperature Indicator is enabled
' 0 = Temperature Indicator is disabled
' bit 4 TSRNG: Temperature Indicator Range Selection bit(3)
' 1 = VOUT = VDD - 4VT (High Range)
' 0 = VOUT = VDD - 2VT (Low Range)
' bit 3-2 CDAFVR<1:0>: Comparator FVR Buffer Gain Selection bits
' 11 = Comparator FVR Buffer Gain is 4x, (4.096V)(2)
' 10 = Comparator FVR Buffer Gain is 2x, (2.048V)(2)
' 01 = Comparator FVR Buffer Gain is 1x, (1.024V)
' 00 = Comparator FVR Buffer is off
' bit 1-0 ADFVR<1:0>: ADC FVR Buffer Gain Selection bit
' ---> 11 = ADC FVR Buffer Gain is 4x, (4.096V)(2)
' 10 = ADC FVR Buffer Gain is 2x, (2.048V)(2)
' 01 = ADC FVR Buffer Gain is 1x, (1.024V)
' 00 = ADC FVR Buffer is off
'
' Note 1: FVRRDY is always ‘1’ for PIC16F18855/75 devices only.
' 2: Fixed Voltage Reference output cannot exceed VDD.
ADCON0 = %10000100 ' ADC CONTROL REGISTER 0
' bit 7 ADON: ADC Enable bit
' ---> 1 = ADC is enabled
' 0 = ADC is disabled
' bit 6 ADCONT: ADC Continuous Operation Enable bit
' 1 = ADGO is retriggered upon completion of each conversion trigger until ADTIF is set (if ADSOI is
' set) or until ADGO is cleared (regardless of the value of ADSOI)
' ---> 0 = ADGO is cleared upon completion of each conversion trigger
' bit 5 Unimplemented: Read as ‘0’
' bit 4 ADCS: ADC Clock Selection bit
' 1 = Clock supplied from FRC dedicated oscillator
' ---> 0 = Clock supplied by FOSC, divided according to ADCLK register
' bit 3 Unimplemented: Read as ‘0’
' bit 2 ADFRM0: ADC results Format/alignment Selection
' ---> 1 = ADRES and ADPREV data are right-justified
' 0 = ADRES and ADPREV data are left-justified, zero-filled
' bit 1 Unimplemented: Read as ‘0’
' bit 0 ADGO: ADC Conversion Status bit
' 1 = ADC conversion cycle in progress. Setting this bit starts an ADC conversion cycle. The bit is
' cleared by hardware as determined by the ADCONT bit
' ---> 0 = ADC conversion completed/not in progress
ADCON2 = %00101010 ' ADC CONTROL REGISTER 2
' bit 7 ADPSIS: ADC Previous Sample Input Select bits
' 1 = ADFLTR is transferred to ADPREV at start-of-conversion
' 0 = ADRES is transferred to ADPREV at start-of-conversion
' bit 6-4 ADCRS<2:0>: ADC Accumulated Calculation Right Shift Select bits
' 111 = Reserved
' 110 = Reserved
' 101 through 000:
' If ADMD = 100:
' Low-pass filter time constant is 2ADCRS, filter gain is 1:1
' If ADMD = 001, 010 or 011:
' ---> The accumulated value is right-shifted by ADCRS (divided by 2ADCRS)(2)
' Otherwise:
' Bits are ignored
' bit 3 ADACLR: ADC Accumulator Clear Command bit
' 1 = Initial clear of ADACC, ADAOV, and the sample counter. Bit is cleared by hardware.
' 0 = Clearing action is complete (or not started)
' bit 2-0 ADMD<2:0>: ADC Operating Mode Selection bits(1)
' 111 = Reserved
' 101 = Reserved
' 100 = Low-pass Filter mode
' 011 = Burst Average mode
' ---> 010 = Average mode
' 001 = Accumulate mode
' 000 = Basic (Legacy) mode
' Note 1: See Table 23-3 for Full mode descriptions.
' 2: All results of divisions using the ADCRS bits are truncated, not rounded.
ADCNT = %00001000 ' ADC CONVERSION COUNTER REGISTER
' bit 7-0 ADRPT<7:0>: ADC Conversion Counter
' Counts the number of times that the ADC is triggered. Determines when the threshold is checked for
' the Low-Pass Filter, Burst Average, and Average Computation modes. Count saturates at 0xFF and
' does not roll-over to 0x00.
ADCLK = %00111111 ' ADC CLOCK SELECTION REGISTER
' bit 7-6 Unimplemented: Read as ‘0’
' bit 5-0 ADCCS<5:0>: ADC Conversion Clock Select bits
' ---> 111111 = FOSC/128
' 111110 = FOSC/126
' 111101 = FOSC/124
' •
' 000000 = FOSC/2
ADREF = %00000011 ' ADC REFERENCE SELECTION REGISTER
' bit 7-5 Unimplemented: Read as ‘0’
' bit 4 ADNREF: ADC Negative Voltage Reference Selection bit
' 1 = VREF- is connected to VREF- pin
' ---> 0 = VREF- is connected to AVSS
' bit 3-2 Unimplemented: Read as ‘0’
' bit 1-0 ADPREF: ADC Positive Voltage Reference Selection bits
' ---> 11 = VREF+ is connected to FVR_buffer 1
' 10 = VREF+ is connected to VREF+ pin
' 01 = Reserved
' 00 = VREF+ is connected to VDD
ADPCH = %00000000 ' ADC POSITIVE CHANNEL SELECTION REGISTER
' bit 7-6 Unimplemented: Read as ‘0’
' bit 5-0 ADPCH<5:0>: ADC Positive Input Channel Selection bits
' 111111 = Fixed Voltage Reference (FVR)
' 111110 = DAC1 output
' 111101 = Temperature Indicator
' ---> 111100 = AVSS (Analog Ground)
' 111011 = Reserved. No channel connected.
' •
' •
' •
' 100010 = ANE2 * 16F18877 only
' 100001 = ANE1 * 16F18877 only
' 100000 = ANE0 * 16F18877 only
' 011111 = AND7 * 16F18877 only
' 011110 = AND6 * 16F18877 only
' 011101 = AND5 * 16F18877 only
' 011100 = AND4 * 16F18877 only
' 011011 = AND3 * 16F18877 only
' 011010 = AND2 * 16F18877 only
' 011001 = AND1 * 16F18877 only
' 011000 = AND0 * 16F18877 only
' 010111 = ANC7
' 010110 = ANC6
' 010101 = ANC5
' 010100 = ANC4
' 010011 = ANC3
' 010010 = ANC2
' 010001 = ANC1
' 010000 = ANC0
' 001111 = ANB7
' 001110 = ANB6
' 001101 = ANB5
' 001100 = ANB4
' 001011 = ANB3
' 001010 = ANB2
' 001001 = ANB1
' 001000 = ANB0
' 000111 = ANA7
' 000110 = ANA6
' 000101 = ANA5
' 000100 = ANA4
' 000011 = ANA3
' 000010 = ANA2
' 000001 = ANA1
' 000000 = ANA0
ANSELA = %00001001 ' Pin A3 = ADC (voltage divider)
' Pin A0 = ADC (B5K)
ANSELB = %00000000
ANSELC = %00000000
TRISA = %00001001 ' Pin A3 = ADC input 3
' Pin A0 = ADC input 0
TRISB = %00000000
TRISC = %00000000
AVSS var byte
AVSS = %00111100 ' AVSS (Analog Ground)
ADCinput var WORD
OldADC0 var WORD
OldADC3 var WORD
NewADC0 var WORD
NewADC3 var WORD
ADCshift var WORD
Pause 100 ' Let PIC and LCD stabilize
ADCinput = 0
OldADC0 = 9999 : OldADC3 = 9999
NewADC0 = 0 : NewADC3 = 0
LCDOUT $FE, 1 : Pauseus 1
LCDOUT $FE, $80, " ADC test" : Pauseus 1
LCDOUT $FE, $94, "ADC0:" : Pauseus 1
LCDOUT $FE, $D4, "ADC3:" : Pauseus 1
Mainloop:
rem ADC 0
ADPCH = AVSS : adcin 0, ADCinput
NewADC0 = 1023 - ADCinput ' inverted so pot goes from 0 to 1024
if NewADC0 <> oldadc0 then
oldadc0 = NewADC0
ADCshift = NewADC0 / 4
LCDOUT $FE, $94+6, DEC4 oldadc0, " ", dec4 ADCshift : Pauseus 1
endif
rem ADC 3
ADPCH = AVSS : adcin 3, ADCinput
NewADC3 = ADCinput
if NewADC3 <> oldadc3 then
oldadc3 = NewADC3
ADCshift = NewADC3 / 4
LCDOUT $FE, $D4+6, DEC4 oldadc3, " ", dec4 ADCshift : Pauseus 1
endif
GOTO Mainloop
end
It still jitters. I'm sure I'm missing some parameters.
-
Re: SOLVED: How can I reduce ADC drift
Can't edit my post:
Quote:
(like changing from 4V down to 1V)
And of course my code alignment is totally whacked...
-
Re: SOLVED: How can I reduce ADC drift
Quote:
Originally Posted by
richard
using the fvr gets slightly better result [mine is a 3.3v system]
Code:
mean 255
readings
0000,0000,0000,0000,0000,0000,0000,0000,0000,0000 3600 0000,0000,0000,0000,0000,0000,0000,0000,0000,0000
outliers 0000
mean 255
readings
0000,0000,0000,0000,0000,0000,0000,0000,0000,0000 3600 0000,0000,0000,0000,0000,0000,0000,0000,0000,0000
outliers 0000
mean 255
readings
0000,0000,0000,0000,0000,0000,0000,0000,0000,0000 3600 0000,0000,0000,0000,0000,0000,0000,0000,0000,0000
outliers 0000
mean 255
readings
0000,0000,0000,0000,0000,0000,0000,0000,0000,0000 3600 0000,0000,0000,0000,0000,0000,0000,0000,0000,0000
outliers 0000
mean 255
readings
0000,0000,0000,0000,0000,0000,0000,0000,0000,0000 3600 0000,0000,0000,0000,0000,0000,0000,0000,0000,0000
outliers 0000
mean 255
My readings never jitter at 0000 or 1023, always rock solid.
It's when I start taking readings within the range that things go nuts.
-
Re: SOLVED: How can I reduce ADC drift
Quote:
We can't switch ADPCH manually between each Average?
not really
it needs to take the number of readings to average in an uninterrupted exclusive sequence
once the average is obtained you can set a new channel and set the device to perform a new average
or cease averaging. a sequence cannot be interrupted for an additional extra adc read
Quote:
I'm trying to switch ADPCH to 111100 = AVSS (Analog Ground) before each ADCIN to see if that fixes the problem.
or makes it worse if acquisition time is inadequate or marginal , the dummy read is most successful
not sure about this chip but when does channel change occur, a delay is probably required
i don't see any form of averaging here
Code:
ADPCH = AVSS : adcin 0, ADCinput
NewADC0 = 1023 - ADCinput ' inverted so pot goes from 0 to 1024
if NewADC0 <> oldadc0 then
oldadc0 = NewADC0
ADCshift = NewADC0 / 4
LCDOUT $FE, $94+6, DEC4 oldadc0, " ", dec4 ADCshift : Pauseus 1
endif
-
Re: SOLVED: How can I reduce ADC drift
there are heaps of other ways too
mean var word
ADCinput var word
average
Code:
mean = 0
for i = 0 to 9
ADCIN 0, ADCinput
mean = mean + ADCinput
next
mean = mean/10
DEBUG "mean ",DEC mean,",",DEC mean>>2,13,10
running average
Code:
ADCIN 0, ADCinput
mean = mean */ 200 + ADCinput */ 55
DEBUG "mean ",DEC mean,",",DEC mean>>2,13,10
-
Re: SOLVED: How can I reduce ADC drift
All your setup is on a Breadboard?
I can suspect that even low current PWM loads on a breadboard may cause such issues. The stray capacitance of these things is too mauch to have a reliable operation.
My test of ADC on a Picdem boards show rock-solid readings. But is of good design with a lot of grounds that you are missing on breadboards.
Ioannis
-
Re: SOLVED: How can I reduce ADC drift
Quote:
Originally Posted by
richard
...i don't see any form of averaging here...
There isn't. I thought it all happened in the background when you did ADCIN, the average was calculated, and results stored in output fields, like a normal ADCIN.
I guess you're telling me this is an on-going process, and ADCIN just gives you the average "at that point in time", but it keeps on going.
I thought setting this OFF meant we could disable continuous sampling:
16F18855
Quote:
23.5.8 CONTINUOUS SAMPLING MODE
Setting the ADCONT bit in the ADCON0 register automatically retriggers a new conversion cycle after updating the ADACC register.
-
Re: SOLVED: How can I reduce ADC drift
Quote:
I guess you're telling me this is an on-going process, and ADCIN just gives you the average "at that point in time", but it keeps on going.
the computational adc is more complex than that, microchip have a number of YT clips on it usages
eg
https://www.youtube.com/watch?v=NVfX22uDOF8
i have never had any reason to use it to date
-
Re: SOLVED: How can I reduce ADC drift
Ok, thanks.
I've reverted to legacy mode, still using FVR, removed all LCD components, added USART:
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 = %00001001 ' Pin A3 = ADC (voltage divider)
' Pin A0 = ADC (B5K)
ANSELB = %00000000
ANSELC = %00000000
TRISA = %00001001 ' Pin A3 = ADC input 3
' 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
ADCdiff var WORD
OldADC0 var WORD
OldADC3 var WORD
Pause 100 ' Let PIC and LCD stabilize
ADCinput = 0 : ADCdiff = 0
OldADC0 = 9999 : OldADC3 = 9999
Hserout [ "ADC TEST", _
10, _
"Initial values = 9999", 10, 10]
Mainloop:
rem ADC 0
adcin 0, ADCinput : adcin 0, ADCinput
if ADCinput < oldADC0 then
ADCdiff = oldadc0 - adcinput
else
ADCdiff = adcinput - oldadc0
endif
if ADCinput <> oldADC0 then
oldADC0 = ADCinput
Hserout [ "B5K pot = ", dec4 ADCinput," diff = ", dec4 ADCdiff, 10]
while TXSTA.1 = 0 ' Check TRMT bit
wend
endif
rem ADC 3
adcin 3, ADCinput : adcin 3, ADCinput
if ADCinput < oldADC3 then
ADCdiff = oldadc3 - adcinput
else
ADCdiff = adcinput - oldadc3
endif
if ADCinput <> oldADC3 then
oldADC3 = ADCinput
Hserout [ " ", _
"Volt/divider = ", dec4 ADCinput," diff = ", dec4 ADCdiff, 10]
while TXSTA.1 = 0 ' Check TRMT bit
wend
endif
GOTO Mainloop
end
This is what I get now, variations of 1 and 2 mostly:
Code:
ADC TEST
Initial values = 9999
B5K pot = 0680 diff = 9319
Volt/divider = 0627 diff = 9372
B5K pot = 0681 diff = 0001
Volt/divider = 0628 diff = 0001
B5K pot = 0680 diff = 0001
B5K pot = 0681 diff = 0001
B5K pot = 0679 diff = 0002
Volt/divider = 0627 diff = 0001
B5K pot = 0680 diff = 0001
Volt/divider = 0629 diff = 0002
B5K pot = 0679 diff = 0001
Volt/divider = 0630 diff = 0001
Volt/divider = 0629 diff = 0001
B5K pot = 0680 diff = 0001
Volt/divider = 0630 diff = 0001
B5K pot = 0679 diff = 0001
Volt/divider = 0629 diff = 0001
Volt/divider = 0628 diff = 0001
Volt/divider = 0629 diff = 0001
Volt/divider = 0628 diff = 0001
B5K pot = 0680 diff = 0001
B5K pot = 0679 diff = 0001
B5K pot = 0680 diff = 0001
Volt/divider = 0629 diff = 0001
B5K pot = 0679 diff = 0001
Volt/divider = 0628 diff = 0001
Volt/divider = 0629 diff = 0001
B5K pot = 0678 diff = 0001
B5K pot = 0679 diff = 0001
Volt/divider = 0628 diff = 0001
B5K pot = 0678 diff = 0001
Volt/divider = 0629 diff = 0001
B5K pot = 0680 diff = 0002
B5K pot = 0679 diff = 0001
B5K pot = 0678 diff = 0001
Volt/divider = 0630 diff = 0001
B5K pot = 0679 diff = 0001
B5K pot = 0678 diff = 0001
B5K pot = 0679 diff = 0001
B5K pot = 0678 diff = 0001
Volt/divider = 0631 diff = 0001
Volt/divider = 0632 diff = 0001
Volt/divider = 0631 diff = 0001
Volt/divider = 0632 diff = 0001
B5K pot = 0677 diff = 0001
B5K pot = 0678 diff = 0001
Volt/divider = 0631 diff = 0001
Volt/divider = 0630 diff = 0001
B5K pot = 0677 diff = 0001
B5K pot = 0679 diff = 0002
B5K pot = 0678 diff = 0001
B5K pot = 0679 diff = 0001
Volt/divider = 0629 diff = 0001
B5K pot = 0678 diff = 0001
Volt/divider = 0628 diff = 0001
Volt/divider = 0629 diff = 0001
B5K pot = 0679 diff = 0001
B5K pot = 0678 diff = 0001
B5K pot = 0679 diff = 0001
Volt/divider = 0628 diff = 0001
Volt/divider = 0629 diff = 0001
B5K pot = 0678 diff = 0001
Volt/divider = 0628 diff = 0001
Volt/divider = 0627 diff = 0001
B5K pot = 0679 diff = 0001
B5K pot = 0678 diff = 0001
Volt/divider = 0628 diff = 0001
B5K pot = 0679 diff = 0001
B5K pot = 0678 diff = 0001
B5K pot = 0679 diff = 0001
Volt/divider = 0627 diff = 0001
Volt/divider = 0628 diff = 0001
B5K pot = 0678 diff = 0001
Volt/divider = 0627 diff = 0001
B5K pot = 0679 diff = 0001
B5K pot = 0678 diff = 0001
Volt/divider = 0628 diff = 0001
Volt/divider = 0627 diff = 0001
B5K pot = 0679 diff = 0001
Volt/divider = 0626 diff = 0001
B5K pot = 0678 diff = 0001
B5K pot = 0679 diff = 0001
B5K pot = 0678 diff = 0001
B5K pot = 0679 diff = 0001
Volt/divider = 0625 diff = 0001
B5K pot = 0678 diff = 0001
Volt/divider = 0627 diff = 0002
B5K pot = 0679 diff = 0001
Volt/divider = 0626 diff = 0001
Volt/divider = 0627 diff = 0001
Volt/divider = 0626 diff = 0001
Volt/divider = 0627 diff = 0001
B5K pot = 0678 diff = 0001
Volt/divider = 0626 diff = 0001
B5K pot = 0679 diff = 0001
B5K pot = 0678 diff = 0001
B5K pot = 0679 diff = 0001
B5K pot = 0678 diff = 0001
B5K pot = 0679 diff = 0001
B5K pot = 0678 diff = 0001
B5K pot = 0679 diff = 0001
B5K pot = 0678 diff = 0001
B5K pot = 0679 diff = 0001
B5K pot = 0678 diff = 0001
B5K pot = 0679 diff = 0001
Volt/divider = 0627 diff = 0001
B5K pot = 0678 diff = 0001
B5K pot = 0679 diff = 0001
B5K pot = 0678 diff = 0001
Volt/divider = 0628 diff = 0001
B5K pot = 0679 diff = 0001
Volt/divider = 0627 diff = 0001
B5K pot = 0678 diff = 0001
Volt/divider = 0626 diff = 0001
B5K pot = 0679 diff = 0001
Volt/divider = 0627 diff = 0001
Volt/divider = 0628 diff = 0001
B5K pot = 0678 diff = 0001
Volt/divider = 0627 diff = 0001
B5K pot = 0679 diff = 0001
Volt/divider = 0626 diff = 0001
B5K pot = 0678 diff = 0001
Volt/divider = 0627 diff = 0001
B5K pot = 0679 diff = 0001
Volt/divider = 0626 diff = 0001
B5K pot = 0678 diff = 0001
Volt/divider = 0627 diff = 0001
B5K pot = 0679 diff = 0001
Volt/divider = 0626 diff = 0001
B5K pot = 0678 diff = 0001
B5K pot = 0679 diff = 0001
B5K pot = 0678 diff = 0001
Volt/divider = 0625 diff = 0001
B5K pot = 0679 diff = 0001
Volt/divider = 0626 diff = 0001
B5K pot = 0678 diff = 0001
Volt/divider = 0625 diff = 0001
B5K pot = 0679 diff = 0001
Volt/divider = 0626 diff = 0001
Volt/divider = 0625 diff = 0001
Volt/divider = 0626 diff = 0001
Volt/divider = 0625 diff = 0001
Volt/divider = 0626 diff = 0001
B5K pot = 0678 diff = 0001
Volt/divider = 0625 diff = 0001
B5K pot = 0679 diff = 0001
Volt/divider = 0626 diff = 0001
Volt/divider = 0625 diff = 0001
B5K pot = 0680 diff = 0001
Volt/divider = 0626 diff = 0001
B5K pot = 0679 diff = 0001
B5K pot = 0680 diff = 0001
Volt/divider = 0625 diff = 0001
B5K pot = 0679 diff = 0001
Volt/divider = 0624 diff = 0001
Volt/divider = 0625 diff = 0001
B5K pot = 0680 diff = 0001
Volt/divider = 0624 diff = 0001
B5K pot = 0679 diff = 0001
Volt/divider = 0625 diff = 0001
B5K pot = 0680 diff = 0001
Volt/divider = 0624 diff = 0001
Volt/divider = 0625 diff = 0001
B5K pot = 0679 diff = 0001
Volt/divider = 0624 diff = 0001
Volt/divider = 0625 diff = 0001
Volt/divider = 0624 diff = 0001
B5K pot = 0680 diff = 0001
B5K pot = 0679 diff = 0001
Volt/divider = 0625 diff = 0001
B5K pot = 0680 diff = 0001
B5K pot = 0679 diff = 0001
B5K pot = 0680 diff = 0001
B5K pot = 0679 diff = 0001
B5K pot = 0680 diff = 0001
B5K pot = 0679 diff = 0001
Volt/divider = 0624 diff = 0001
Volt/divider = 0625 diff = 0001
Volt/divider = 0624 diff = 0001
B5K pot = 0680 diff = 0001
B5K pot = 0679 diff = 0001
B5K pot = 0680 diff = 0001
Volt/divider = 0623 diff = 0001
Volt/divider = 0624 diff = 0001
B5K pot = 0679 diff = 0001
B5K pot = 0680 diff = 0001
Volt/divider = 0623 diff = 0001
B5K pot = 0679 diff = 0001
B5K pot = 0678 diff = 0001
Volt/divider = 0624 diff = 0001
B5K pot = 0679 diff = 0001
B5K pot = 0680 diff = 0001
B5K pot = 0679 diff = 0001
Volt/divider = 0625 diff = 0001
Volt/divider = 0624 diff = 0001
B5K pot = 0680 diff = 0001
B5K pot = 0679 diff = 0001
B5K pot = 0680 diff = 0001
Volt/divider = 0623 diff = 0001
Volt/divider = 0624 diff = 0001
B5K pot = 0679 diff = 0001
Volt/divider = 0623 diff = 0001
B5K pot = 0680 diff = 0001
Volt/divider = 0624 diff = 0001
B5K pot = 0681 diff = 0001
Volt/divider = 0623 diff = 0001
B5K pot = 0680 diff = 0001
Volt/divider = 0624 diff = 0001
B5K pot = 0681 diff = 0001
B5K pot = 0680 diff = 0001
Volt/divider = 0623 diff = 0001
B5K pot = 0679 diff = 0001
Volt/divider = 0624 diff = 0001
B5K pot = 0680 diff = 0001
B5K pot = 0679 diff = 0001
B5K pot = 0680 diff = 0001
B5K pot = 0679 diff = 0001
Volt/divider = 0623 diff = 0001
B5K pot = 0680 diff = 0001
Volt/divider = 0624 diff = 0001
B5K pot = 0679 diff = 0001
B5K pot = 0680 diff = 0001
Volt/divider = 0623 diff = 0001
B5K pot = 0679 diff = 0001
Volt/divider = 0624 diff = 0001
B5K pot = 0681 diff = 0002
Volt/divider = 0623 diff = 0001
B5K pot = 0680 diff = 0001
Volt/divider = 0624 diff = 0001
B5K pot = 0679 diff = 0001
Volt/divider = 0623 diff = 0001
B5K pot = 0680 diff = 0001
Volt/divider = 0624 diff = 0001
B5K pot = 0679 diff = 0001
Volt/divider = 0625 diff = 0001
Volt/divider = 0624 diff = 0001
Volt/divider = 0623 diff = 0001
B5K pot = 0680 diff = 0001
Volt/divider = 0624 diff = 0001
Volt/divider = 0623 diff = 0001
B5K pot = 0681 diff = 0001
B5K pot = 0680 diff = 0001
B5K pot = 0679 diff = 0001
Volt/divider = 0624 diff = 0001
B5K pot = 0680 diff = 0001
Volt/divider = 0623 diff = 0001
B5K pot = 0681 diff = 0001
B5K pot = 0680 diff = 0001
B5K pot = 0681 diff = 0001
B5K pot = 0680 diff = 0001
Volt/divider = 0622 diff = 0001
B5K pot = 0681 diff = 0001
B5K pot = 0680 diff = 0001
Volt/divider = 0623 diff = 0001
Volt/divider = 0622 diff = 0001
B5K pot = 0681 diff = 0001
B5K pot = 0680 diff = 0001
Volt/divider = 0623 diff = 0001
Volt/divider = 0622 diff = 0001
B5K pot = 0681 diff = 0001
B5K pot = 0680 diff = 0001
B5K pot = 0681 diff = 0001
B5K pot = 0680 diff = 0001
B5K pot = 0681 diff = 0001
B5K pot = 0680 diff = 0001
B5K pot = 0681 diff = 0001
B5K pot = 0680 diff = 0001
B5K pot = 0681 diff = 0001
Volt/divider = 0623 diff = 0001
Volt/divider = 0622 diff = 0001
B5K pot = 0680 diff = 0001
B5K pot = 0681 diff = 0001
B5K pot = 0680 diff = 0001
B5K pot = 0681 diff = 0001
B5K pot = 0680 diff = 0001
B5K pot = 0681 diff = 0001
Volt/divider = 0623 diff = 0001
Volt/divider = 0622 diff = 0001
Volt/divider = 0623 diff = 0001
B5K pot = 0680 diff = 0001
Volt/divider = 0622 diff = 0001
Volt/divider = 0623 diff = 0001
B5K pot = 0681 diff = 0001
Volt/divider = 0622 diff = 0001
B5K pot = 0680 diff = 0001
Volt/divider = 0624 diff = 0002
Volt/divider = 0623 diff = 0001
Volt/divider = 0624 diff = 0001
Volt/divider = 0623 diff = 0001
B5K pot = 0679 diff = 0001
Volt/divider = 0624 diff = 0001
B5K pot = 0680 diff = 0001
B5K pot = 0681 diff = 0001
B5K pot = 0680 diff = 0001
Volt/divider = 0623 diff = 0001
Volt/divider = 0624 diff = 0001
Volt/divider = 0623 diff = 0001
B5K pot = 0679 diff = 0001
B5K pot = 0680 diff = 0001
Volt/divider = 0624 diff = 0001
Volt/divider = 0623 diff = 0001
B5K pot = 0679 diff = 0001
Volt/divider = 0624 diff = 0001
B5K pot = 0680 diff = 0001
Volt/divider = 0623 diff = 0001
B5K pot = 0679 diff = 0001
Volt/divider = 0624 diff = 0001
B5K pot = 0680 diff = 0001
B5K pot = 0679 diff = 0001
Volt/divider = 0623 diff = 0001
Volt/divider = 0624 diff = 0001
Volt/divider = 0623 diff = 0001
Volt/divider = 0624 diff = 0001
Volt/divider = 0623 diff = 0001
B5K pot = 0680 diff = 0001
B5K pot = 0679 diff = 0001
B5K pot = 0680 diff = 0001
B5K pot = 0679 diff = 0001
Volt/divider = 0624 diff = 0001
Volt/divider = 0623 diff = 0001
B5K pot = 0680 diff = 0001
Volt/divider = 0624 diff = 0001
B5K pot = 0679 diff = 0001
Volt/divider = 0623 diff = 0001
B5K pot = 0680 diff = 0001
Volt/divider = 0624 diff = 0001
Volt/divider = 0623 diff = 0001
B5K pot = 0679 diff = 0001
B5K pot = 0680 diff = 0001
B5K pot = 0679 diff = 0001
B5K pot = 0680 diff = 0001
B5K pot = 0679 diff = 0001
B5K pot = 0680 diff = 0001
B5K pot = 0679 diff = 0001
B5K pot = 0680 diff = 0001
B5K pot = 0679 diff = 0001
B5K pot = 0680 diff = 0001
Volt/divider = 0624 diff = 0001
B5K pot = 0679 diff = 0001
B5K pot = 0680 diff = 0001
Volt/divider = 0623 diff = 0001
B5K pot = 0679 diff = 0001
Volt/divider = 0624 diff = 0001
Volt/divider = 0623 diff = 0001
B5K pot = 0680 diff = 0001
B5K pot = 0679 diff = 0001
B5K pot = 0680 diff = 0001
B5K pot = 0679 diff = 0001
Volt/divider = 0622 diff = 0001
Volt/divider = 0623 diff = 0001
B5K pot = 0680 diff = 0001
Volt/divider = 0622 diff = 0001
Volt/divider = 0623 diff = 0001
B5K pot = 0679 diff = 0001
B5K pot = 0680 diff = 0001
Volt/divider = 0622 diff = 0001
-
Re: SOLVED: How can I reduce ADC drift
With those differences, I suppose I should add a mean average and call it a day.
-
1 Attachment(s)
Re: SOLVED: How can I reduce ADC drift
Would dual TPS56637 step-down circuits help me reduce noise by PWM, LCD and other "noisy stuff"?
Attachment 9914
Would diodes help in further isolating the 2 circuits? (like blocking surges) I looking for the minimum voltage for the TPS56637 circuit now, to make sure the voltage drop from 2 diodes wouldn't interfere with 9V input.
I'd use dedicated PICs per function; 1 for input on top circuit, 1 for output on bottom circuit.
-
Re: SOLVED: How can I reduce ADC drift
I found this, that says it wouldn't hurt to put Schottkys on VDD.
Quote:
You don't need the diodes for ground, only using diodes for Vcc is sufficent....
You could use schottky diodes as the voltage drop is 0.2V, that would be easiest.
Circuit with dual power source: Replacing diodes with MOSFETs
https://electronics.stackexchange.co...s-with-mosfets
I suppose adding a bunch of filter caps downstream of the diodes would help reduce "fluctuations" before it enters the TPS56637.
-
Re: SOLVED: How can I reduce ADC drift
stick a 2200uF low esr electrolytic in every power rail on each bread-board and be done with it. if it still noisy add another set.
if that fails isolate noisy bits behind rfc's [rf chokes]. ditch the hi switching speed [noise inducing] mosfets for pwm, use bjt instead, its only a backlight
as ioannis says, breadboards and low noise are very close to mutually exclusive concepts
-
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
-
Re: SOLVED: How can I reduce ADC drift
Quote:
Originally Posted by
richard
stick a 2200uF low esr electrolytic in every power rail on each bread-board and be done with it. if it still noisy add another set....
I only have a few 1000uF electrolytics, so I put 2 on each rail, same ADC flutter of mostly 1, sometimes 2.
Quote:
Originally Posted by
richard
...if that fails isolate noisy bits behind rfc's [rf chokes]....
I only have these 2 on hand:
RL-1284 100uH, https://www.electronicsurplus.com/re...uh-irms-0-4amp
79F101K-TR-RC 100uH, https://www.mouser.com/datasheet/2/5...te-1371239.pdf
Quote:
Originally Posted by
richard
...ditch the hi switching speed [noise inducing] mosfets for pwm, use bjt instead, its only a backlight...
I was having difficulties turning the backlight all the way off using 2N2907A PNP. The BS250P P-chan worked like a charm from full OFF to full ON.
Quote:
Originally Posted by
richard
...as ioannis says, breadboards and low noise are very close to mutually exclusive concepts
Yeah, that's why I moved away from my larger main prototype board to only 2 PCB boards to get ADC working perfectly.
-
Re: SOLVED: How can I reduce ADC drift
Quote:
Originally Posted by
richard
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.
-
Re: SOLVED: How can I reduce ADC drift
Quote:
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
-
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
-
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
-
1 Attachment(s)
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.
Attachment 9915
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. :)
-
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...
-
1 Attachment(s)
Re: SOLVED: How can I reduce ADC drift
- did not touch VREFs,
What do you mean by this , you have changes pos vref to fvr buffer1- used FVR 4x with 5 VDC in,
which will turn out to be a mistake since pots use vdd as top input , by doing this you have lost 20% of their travel range
Anything over VREF+ will be interpreted as the max ADC output. Anything lower than VREF- will be interpreted as the min ADC output value.
There will be no damage if you exceed VREF+/VREF- as long as you don't exceed Vdd/Vss
- used FOSC / 128,way too slow , while not out of acceptable range fosc/32 is more reasonable
- used average of 16 ADC readings,not sure about that , its not necessary either if every thing else is ok
- 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.
it does nothing useful
my schema , added another supply rail straddling 10k pot , without series wiper resistor to an2
not no none nil caps across an inputs
Attachment 9919
typical raw readings
Code:
R 827 669
R 826 669
R 826 669
R 826 668
R 825 669
R 827 669
R 826 669
R 826 669
R 826 668
R 825 668
R 827 670
R 826 669
R 825 668
R 827 669
R 827 669
#CONFIG
__config _CONFIG1, _FEXTOSC_OFF & _RSTOSC_HFINT32 & _CLKOUTEN_OFF & _CSWEN_ON & _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_ON & _WDTCWS_WDTCWS_7 & _WDTCCS_LFINTOSC
__config _CONFIG4, _WRT_OFF & _SCANE_available & _LVP_ON
__config _CONFIG5, _CP_OFF & _CPD_OFF
#ENDCONFIG
DEFINE OSC 32
DEFINE DEBUG_REG PORTC
DEFINE DEBUG_BIT 0 ; if not used for pwr
DEFINE DEBUG_BAUD 9600
DEFINE DEBUG_MODE 0
DEFINE ADC_BITS 10 ' 10-bit Analog to digital
DEFINE ADC_SAMPLEUS 5 ' Set sampling time in uS
ANSELA = % 00000101 ' Pins A0 A2 = ADC
TRISA = % 11101111 ' Pin A4 = LED
TRISD = % 11111011 ' DEBUG
LATC.0 = 1 ' DEBUG
clear
LED VAR LATA.4
i var byte
j var word
bucket var WORD
ADCinput var WORD
mean var WORD
buckets var word[21]
outlier var WORD
LED = 1 'Proof of Life
PAUSE 2000
DEBUG 13,10,"READY",13,10
FVRCON = % 10000011
;ADCON0 = % 10000100 ;NOT USED
ADREF = % 00000000
ADCLK = 15
LED=0
Mainloop:
;NOTE an inputs sampled twice to overcome pbp poor adc ch changes
ADCIN 0, ADCinput
ADCIN 0, ADCinput
DEBUG 13,10,"R ",DEC ADCinput,9
ADCIN 2, ADCinput
ADCIN 2, ADCinput
DEBUG DEC ADCinput
PAUSE 500
GOTO Mainloop
end
i just tried it without the double adc reads on input change and it works ok , so that's not an issue anymore it seems
[i very rarely if ever use the adcin command , prefer to use asm sequences instead]
-
Re: SOLVED: How can I reduce ADC drift
Lets clarify something Robert please.
Do you expect to have an ADC reading that will be absolutely stable on every pot position? Say that a user can set 1023 positions on the pot. Do you expect to have solid 1023 readings?
This cannot be done no matter what. On an absolutely perfect circuit you will get +/- 1 digit because of the way ADC works along with every kind of noise present (wire induced, ground loops, resistors noise, shot noise, Johnson noise and so many other kinds).
The ADC steps are 5/1023= 4.8876mV. This means that if ADC input is over that step, you get a count of 1. But if one of the above noise or more than one is present, you may get 0 or even 2 as a result, if the noise adds another 4.88mv.
Hope this is clear and helps you not chasing the impossible.
Any kind of averaging helps but because of the above, it does not eliminate the small jitter that you should accept.
Averaging with Moving average routine limits the maximum number of counts. The one Richard posted on #57 goes up to 1004 after about 30 samples. Darrels Taylor Oversampling routine does also suffer of this kind of problem. Well gives from 8bit ADC a 16bit result but you have to pay in time...
Best keep a simple average of 10 samples and get done with it.
Ioannis
-
Re: SOLVED: How can I reduce ADC drift
Quote:
Originally Posted by
Ioannis
Lets clarify something Robert please.
Do you expect to have an ADC reading that will be absolutely stable on every pot position? Say that a user can set 1023 positions on the pot. Do you expect to have solid 1023 readings? ...
No, I was expecting a reading ranging between 0 and 1023, with 256 near 1/4 rotation (from available travel or course), 512 midway and 768 about 3/4 through.
-
Re: SOLVED: How can I reduce ADC drift
Yes, you can expect that, depending on the pot of course.
But the readings will have a play around the specific point, because of what I explained.
Ioannis
-
Re: SOLVED: How can I reduce ADC drift
Quote:
But the readings will have a play around the specific point
agreed , at the 1/4 turn posn the raw reading expected WHEN vref == vdd and vdd is a well filtered stable supply would be 256 + or - 1 count. if you want better than that use either a 12 bit adc or averaging or oversampling. none of which come without a cost.
This all becomes a ridiculous overkill if the "pot" for instance represents say the 'CHOKE' position when it is displayed as 0-100 in 5% steps.
i have asked several times now what are your expectations ?
-
4 Attachment(s)
Re: SOLVED: How can I reduce ADC drift
Quote:
Originally Posted by
richard
- did not touch VREFs,
What do you mean by this , you have changes pos vref to fvr buffer1- used FVR 4x with 5 VDC in,
which will turn out to be a mistake since pots use vdd as top input , by doing this you have lost 20% of their travel range...
I meant, did not touch VREF-, sorry.
If I use VREF+ = VDD, my ADC readings stop at 1000 or so.
If I use VREF+ = FVRx4, my readings reach 1023.
Weird.
Quote:
...- used FOSC / 128,way too slow , while not out of acceptable range fosc/32 is more reasonable...
I've switched to 32 as well.
Quote:
...used average of 16 ADC readings,
Quote:
not sure about that , its not necessary either if every thing else is ok ...
If I don't use averages, I jump all over like this:
Code:
OldADC1:00847 ADCin:00844 Diff:00003
OldADC1:00844 ADCin:00847 Diff:00003
OldADC1:00847 ADCin:00844 Diff:00003
OldADC1:00844 ADCin:00848 Diff:00004
OldADC1:00848 ADCin:00845 Diff:00003
OldADC1:00845 ADCin:00848 Diff:00003
OldADC1:00848 ADCin:00844 Diff:00004
Quote:
...- 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.
it does nothing useful ...
I removed them.
Quote:
...my schema , added another supply rail straddling 10k pot , without series wiper resistor to an2
not no none nil caps across an inputs
typical raw readings
Code:
R 827 669
R 826 669
R 826 669
R 826 668
R 825 669
R 827 669
R 826 669
R 826 669
R 826 668
R 825 668
R 827 670
R 826 669
R 825 668
R 827 669
R 827 669
Envious emote...
Quote:
...
DEFINE ADC_BITS 10 ' 10-bit Analog to digital
DEFINE ADC_SAMPLEUS 5 ' Set sampling time in uS...
Reduced mine from 50 down to 5 as well
I just noticed that my temps on the 16F18855 goes over 100c when ADC runs; that's insane. I have no other routines running. If I stop ADC, it comes back down to 30ies.
Attachment 9920
I took everything non-essential off the breadboard (just kept my 2 power LEDs):
Attachment 9921
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 5 ' 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
' 0 = ADC is disabled
' 1 = ADC is enabled
' bit 2 ADFRM0: ADC results Format/alignment Selection
' 1 = ADRES and ADPREV data are right-justified
' 0 = ADRES and ADPREV data are left-justified, zero-filled
ADCLK = %00001111 ' ADC CLOCK SELECTION REGISTER
' bit 5-0 ADCCS<5:0>: ADC Conversion Clock Select bits
' 001111 = FOSC/32
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
' 00 = VREF+ is connected to VDD
ANSELA = %00000010 ' Pin A1 = ADC (B5K)
ANSELB = %00000000
ANSELC = %00000000
TRISA = %00000010 ' Pin A1 = ADC input 1
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
ADCdiff var WORD
OldADC1 var WORD
Pause 500 ' Let PIC and LCD stabilize
ADCinput = 0
ADCdiff = 0
OldADC1 = 9999
Mainloop:
rem ADC1, B5K pot
adcin 1, ADCinput
ADCinput = ADCinput >> 6 ' tried left justified for fun
if ADCinput < oldADC1 then ' Calculate change in ADC
ADCdiff = oldadc1 - ADCinput
else
ADCdiff = ADCinput - oldadc1
endif
IF ADCdiff > 2 then ' Check for Diff over 2
hserout [ "OldADC1:", DEC5 oldadc1, " ", _
"ADCin:", DEC5 ADCinput, " ", _
"Diff:", DEC5 ADCdiff, 10]
while TXSTA.1 = 0 ' Check TRMT bit
wend
oldADC1 = ADCinput
else
if ADCinput <> oldadc1 then ' ADC value diff than previous
if ADCinput = 0 then ' Reached end of rotation
hserout [ "OldADC1:", DEC5 oldadc1, " ", _
"ADCin:", DEC5 ADCinput, " ", _
"Diff:", DEC5 ADCdiff, " ", 10]
while TXSTA.1 = 0 ' Check TRMT bit
wend
oldADC1 = ADCinput
else
if ADCinput = 1023 then ' Reached start of rotation
hserout [ "OldADC1:", DEC5 oldadc1, " ", _
"ADCin:", DEC5 ADCinput, " ", _
"Diff:", DEC5 ADCdiff, 10]
while TXSTA.1 = 0 ' Check TRMT bit
wend
oldADC1 = ADCinput
endif
endif
endif
endif
GOTO Mainloop
end
I know I can join those Ifs to check for end of rotation, I just wanted to keep code simple to make sure everything was getting picked up.
Averages was why sometimes it would not reach 0 or 1023.
It works, but it has jumps of 3 now. Gonna see if more caps can reduce that.
No clue why ADC is running so hot, specs say 85c is normal operating temp.
The mounting holes are "slightly" warm, never noticed that before.
Attachment 9922 Attachment 9923
-
Re: SOLVED: How can I reduce ADC drift
Quote:
Originally Posted by
Demon
I just checked the mounting holes on my test LCD, the holes do the same thing and the LCD hasn't been connected in days.
Copper/bare metal is at a different temp than the rest so the scanner detects it.