-
SOLVED: How can I reduce ADC jitter
SOLVED: Noisy VDD/VSS using DC-DC converter. ADC stopped bouncing after using a 7805.
https://picbasic.co.uk/forum/showthr...527#post156527
--------------------------------------------------------------------
16F18877
- Using fixed input on ADC pin (1K to VDD, 1K to VSS - simulating pot at 50%)
- The ADC will drift from 498 to 509.
HSEROUTs on Serial Communicator:
Quote:
Low=00498 High=00509
Is there anything in the registers that I can "tune" for the ADC?
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 CCP1_REG 0 ' Must clear unused CCP pins or else unpredictable results
DEFINE CCP1_BIT 0
define CCP2_REG 0
DEFINE CCP2_BIT 0
DEFINE CCP3_REG 0
DEFINE CCP3_BIT 0
define CCP4_REG 0
DEFINE CCP4_BIT 0
define CCP5_REG 0 ' Must clear unused CCP pins or else unpredictable results
DEFINE CCP5_BIT 0
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
BAUDCON.3 = 1 ' Enable 16 bit baudrate generator
RA4PPS = 0 ' Disable CCP5
RB0PPS = 0 ' Disable CCP4
RB5PPS = 0 ' Disable CCP3
RC1PPS = 0 ' Disable CCP2
RC2PPS = 0 ' Disable CCP1
IOCAP = %00000000 'IOC Positive Edge, low-to-high
IOCAN = %00000000 'IOC Negative Edge, from high-to-low
IOCBP = %00000000 'IOC Positive Edge, low-to-high
IOCBN = %00000000 'IOC Negative Edge, from high-to-low
IOCCP = %00000000 'IOC Positive Edge, low-to-high
IOCCN = %00000000 'IOC Negative Edge, from high-to-low
'IOCDP = %00000000 '...not available
'IOCDN = %00000000 '...not available
'IOCEP = %00000000 '...not available
'IOCEN = %00000000 '...not available
WPUA = %00000000 ' Pull-up resistors
WPUB = %00000000
WPUC = %00000000
WPUD = %00000000
WPUE = %00000000
INLVLA = %00000000 ' TTL input level
INLVLB = %00000000
INLVLC = %00000000
INLVLD = %00000000
'INLVLE = %00000000 ' ...only available on E3 / MCLR pin
ADCON0 = %10000100 ' ADC CONTROL REGISTER 0
ADCLK = %00111111 ' ADC CLOCK SELECTION REGISTER
'ADPCH = %00011010 ' Channel 26 - D2
ANSELA = %00000000
ANSELB = %00000000
ANSELC = %00000000
ANSELD = %00000110 ' Pin D2 = ADC input, NavCom
' Pin D1 = ADC input, Glareshield
ANSELE = %00000000
TRISA = %00000000
TRISB = %00000000
TRISC = %00000000
TRISD = %00000110
TRISE = %00000000
include "I:\Project_v2\PBP\PBP_Includes\USART.bas"
ADCInput var word
LowADC var word
HighADC var word
Pause 1 ' Let PIC stabilize
LowADC = 1023
HighADC = 0
AdcInput = 0
Mainloop:
adcin 26, AdcInput
if AdcInput < LowADC then LowADc = AdcInput
if AdcInput > HighADC then HighADC = AdcInput
hserout [ "Low=", dec5 LowADC, " High=", DEC5 HighADC, 10 ]
goto mainloop
end
I was getting desperate with the drift on the pots, so I thought I'd do a control run using resistors.
I expected it to remain the same or very close, but I'm still getting drift.
-
Re: How can I reduce ADC drift
50mV of noise on the power supply would do that.
using FVR as adc ref might help a little and or a better regulator for the pots
-
Re: How can I reduce ADC drift
I use a DC-DC converter to lower 12V down to 5V for the entire circuit.
Would a dedicated 7805 for the pots be a "meaningful" improvement?
I'll have up to 10 pots in the final circuit. Right now I'm trying to get 1 ADC working well.
-
Re: How can I reduce ADC drift
Quote:
Would a dedicated 7805 for the pots be a "meaningful" improvement?
the first step is to measure the noise on the power rail and then to determine if that's an issue, there is no point adding a regulator for the pots if the adc pos reference is noisy
-
Re: How can I reduce ADC drift
Based on the fact that you are using Power Supply as a reference voltage for the ADC:
1. the Power Supply noise is random and in the length of time it would have very minimal effect on the adc average value.
2. you are feeding the ADC input from a resistor divider that is connected to the Vdd, where also the reference voltage is connected to. It is called ratiometric and should zero the effect of regulator voltage drift. If the voltage of the Resistor divider changes by x % then the reference voltage will change by x % too. So eventually no drift should happen.
What you experience is strange and should not happen.
Needs more investigation.
If you heat or cool the PIC chip, is there any change?
Ioannis
P.S. If you finally use external Voltage reference, that is reasonably stable, I feel that the results will be even worse, because then the Vdd change will have maximum effect on the voltage sample.
-
Re: How can I reduce ADC drift
The Vdd that resistors are connected to, is the exact same point that PIC Vdd pin is connected also?
Ioannis
-
Re: How can I reduce ADC drift
Quote:
Originally Posted by
Ioannis
The Vdd that resistors are connected to, is the exact same point that PIC Vdd pin is connected also?
Ioannis
Yes, it is.
-
Re: How can I reduce ADC drift
Temperature (heating or cooling PIC) has any effect on the drift?
Ioannis
-
Re: How can I reduce ADC drift
Quote:
Originally Posted by
Ioannis
Temperature (heating or cooling PIC) has any effect on the drift?
Ioannis
I'm curious how can this help me?
It is room temperature, just like target customer environment (gaming).
It's not like I'm overclocking the PIC like a PC CPU...?
-
Re: How can I reduce ADC drift
If the ADC result has no or minimal effect because of temp then we have to look elsewhere for the drift.
Ioannis
-
Re: How can I reduce ADC drift
I would try the following:
1/. Use the Fixed Voltage Reference (FVR) instead of Vdd as your ADC reference voltage.
2/. Add some capacitance - say 100nF - between the pot wiper and ground.
Cheers
Barry
VK2XBP
-
Re: How can I reduce ADC drift
Quote:
Originally Posted by
Aussie Barry
I would try the following:
1/. Use the Fixed Voltage Reference (FVR) instead of Vdd as your ADC reference voltage.
2/. Add some capacitance - say 100nF - between the pot wiper and ground.
Cheers
Barry
VK2XBP
1. Yeah, FVR is on my TO-DO list (Richard mentioned it up there).
2. Does it matter if the cap is at the switch or up against PIC (like decoupler caps).
3. Temp is also on my TO-DO list.
-
Re: How can I reduce ADC drift
also try using the fastest conversion clock that does not go Outside the recommended TAD time.
you are using the slowest possible clock
if you use the fvr don't let the wiper volts exceed the fvr output volts
-
Re: How can I reduce ADC drift
It shouldn't really matter if the cap is at the PIC end or the Pot end, as long as the distance between both is not too great.
Note the silicon errata document (Item 1.3) regarding the use of FVR as ADC reference voltage:
https://ww1.microchip.com/downloads/...-80000702J.pdf
Cheers
Barry
-
Re: How can I reduce ADC drift
Quote:
Originally Posted by
richard
if you use the fvr don't let the wiper volts exceed the fvr output volts
What happens if the wiper voltage exceeds the FVR voltage?
-
Re: How can I reduce ADC drift
Quote:
Originally Posted by
Demon
16F18877
Is there anything in the registers that I can "tune" for the ADC?
The PIC16F18877 has an Analog-to-Digital converter with Computation
These post-processing functions are applied to the ADC conversion result and include averaging and low-pass filtering.
Cheers
Barry
-
1 Attachment(s)
Re: How can I reduce ADC drift
Quote:
What happens if the wiper voltage exceeds the FVR voltage?
Ain specs from datasheet
Attachment 9803
at best the top range of the pot would be useless
-
Re: How can I reduce ADC drift
Using FVR will make things worse...
Ioannis
-
2 Attachment(s)
Re: How can I reduce ADC drift
I thought I'd step back and check VDD and VSS using my SDS1104 scope.
This is at 50mV:
Attachment 9804Attachment 9805
Is it realistic to expect no drift on ADC with this much noise on my lines?
:D
-
Re: How can I reduce ADC drift
CONFIRMED: Noisy power definitely messes up everything when the PIC tries to compare the "wiper" reading with VDD/VSS, even using two 1K resistors to simulate 50% pot.
I switched to a 7805 supply and put back my "supposedly dirty" potentiometer. ADC low/high was back to a steady reading no matter where I turned the pot.
I had code prepared using the techniques discussed in Melanie's ADC thread (or was it SORT, I don't remember). I got lost looking at the computational feature of the ADC in the 16F18877; that could have replaced my averaging routine and most likely reduced time.
At worse if I get a dirty pot, I can drop the 1-2 lower bits from the 10-bit reading and still get 512-256 resolution out of a maximum 1024.
-
Re: How can I reduce ADC drift
I did an extra test to confirm it wasn't another component on my main test board that was "messing up" the power.
I powered my isolated PIC with that DC-DC converter and sure enough ADC was jumping between 546 and 569 using my pot.
So now i have to find a 7805 variant that can supply 700mA without breaking a sweat.
-
Re: How can I reduce ADC drift
Drift is tottaly different than jumping numbers...
When you said drift I assumed that you started with say 512 as a 50% of FSD and then it went up or down after some time, like 511, 510, 509 etc.
Having random numbers sure can be due to crappy and noisy Voltage on Vdd.
Ioannis
-
Re: How can I reduce ADC drift
Quote:
Originally Posted by
Aussie Barry
I would try the following:
1/. Use the Fixed Voltage Reference (FVR) instead of Vdd as your ADC reference voltage.
2/. Add some capacitance - say 100nF - between the pot wiper and ground.
Cheers
Barry
VK2XBP
Ok, finally got back to working on my ADC jitters:
- FOSC/128, 111111, 4.0 uS at 32 MHz
- using FVR x 4
- added 0.1uF at ADC pin
No change, still jitters. I took at the manual averaging routine; it doesn't go to the extreme ends (rarely get completely to 0 or 1024 because of jittter).
I'd like to try one of those COMPUTATION FEATURES, but I'm not sure which is better for me, nor what I need to properly set in the registers:
- Basic: essentially what I'm doing now.
- Accumulate,
- Average,
- Burst Average,
- Low-Pass Filter.
I'm testing 2 pots on this board; 1 regular, 1 with switch.
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 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
define CCP1_REG 0 ' Must clear unused CCP pins or else unpredictable results
DEFINE CCP1_BIT 0
define CCP2_REG 0
DEFINE CCP2_BIT 0
define CCP3_REG PORTB ' PWM Pulse out to LCD backlight
DEFINE CCP3_BIT 5
define CCP4_REG 0 ' Must clear unused CCP pins or else unpredictable results
DEFINE CCP4_BIT 0
define CCP5_REG 0
DEFINE CCP5_BIT 0
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.
CCP3CON = %10001111 ' CCP3 CONTROL REGISTER
' bit 7 EN: CCPx Module Enable bit
' 1 = CCPx is enabled
' 0 = CCPx is disabled
' bit 6 Unimplemented: Read as ‘0’
' bit 5 OUT: CCP3 Output Data bit (read-only)
' bit 4 FMT: CCPW (Pulse Width) Alignment bit
' MODE = Capture mode
' Unused
' MODE = Compare mode
' Unused
' MODE = PWM mode
' 1 = Left-aligned format
' 0 = Right-aligned format
' bit 3-0 MODE<3:0>: CCPx Mode Select bits(1)
' ---> 1111 = PWM mode
' 1110 = Reserved
' 1101 = Reserved
' 1100 = Reserved
' 1011 = Compare mode: output will pulse 0-1-0; Clears TMR1
' 1010 = Compare mode: output will pulse 0-1-0
' 1001 = Compare mode: clear output on compare match
' 1000 = Compare mode: set output on compare match
' 0111 = Capture mode: every 16th rising edge of CCPx input
' 0110 = Capture mode: every 4th rising edge of CCPx input
' 0101 = Capture mode: every rising edge of CCPx input
' 0100 = Capture mode: every falling edge of CCPx input
' 0011 = Capture mode: every edge of CCPx input
' 0010 = Compare mode: toggle output on match
' 0001 = Compare mode: toggle output on match; clear TMR1
' 0000 = Capture/Compare/PWM off (resets CCPx module)
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
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
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 = %00000011 ' Pin A1 = ADC
' Pin A0 = ADC
ANSELB = %00000000
ANSELC = %00000000
TRISA = %00000111 ' Pin A2 = SW input 1
' Pin A1 = ADC input 1
' Pin A0 = ADC input 0
TRISB = %00000000
TRISC = %00000000
SW1 var PORTA.2
ADCinput var WORD
OldADC0 var WORD
OldADC1 var WORD
OldSW1 var BYTE
NewADC0 var WORD
NewADC1 var WORD
HPWMbacklight var BYTE
' Pause 200 ' Let PIC and LCD stabilize
ADCinput = 0
OldADC0 = 9999
OldADC1 = 9999
OldSW1 = 9
NewADC0 = 0
NewADC1 = 0
HPWMbacklight = 150
HPWM 3,HPWMbacklight,1953
LCDOUT $FE, 1 : Pauseus 1
LCDOUT $FE, $80, " ADC test" : Pauseus 1
LCDOUT $FE, $94, "ADC 0:" : Pauseus 1
LCDOUT $FE, $D4, "ADC 1: SW:" : Pauseus 1
Mainloop:
rem ADC 0
ADPCH = %00000000
adcin 0, ADCinput
NewADC0 = 1023 - ADCinput
if NewADC0 <> oldadc0 then
oldadc0 = NewADC0
LCDOUT $FE, $94+7, DEC4 oldadc0 : Pauseus 1
endif
rem ADC 1
ADPCH = %00000001
adcin 1, ADCinput
NewADC1 = 1023 - ADCinput
if NewADC1 <> oldadc1 then
oldadc1 = NewADC1
LCDOUT $FE, $D4+7, DEC4 oldadc1 : Pauseus 1
endif
rem SW 1
if SW1 <> oldSW1 then
oldSW1 = SW1
IF OldSW1 = 0 THEN
LCDOUT $FE, $D4+17, "Off" : Pauseus 1
else
LCDOUT $FE, $D4+17, "On " : Pauseus 1
endif
endif
HPWMbacklight = 255 - (NewADC0 / 4)
HPWM 3,HPWMbacklight,1953
GOTO Mainloop
end
-
1 Attachment(s)
Re: How can I reduce ADC drift
Quote:
Originally Posted by
Aussie Barry
It shouldn't really matter if the cap is at the PIC end or the Pot end, as long as the distance between both is not too great.
Note the silicon errata document (Item 1.3) regarding the use of FVR as ADC reference voltage:
https://ww1.microchip.com/downloads/...-80000702J.pdf
Cheers
Barry
Right now I'm testing on 16F18855, but I'll face the same problem on final version with 16F18877.
I'm still trying to figure out how to see the Revision using MeLabs USB programmer. This is the most I can see.
Attachment 9912
-
Re: SOLVED: How can I reduce ADC drift
I do not think you can see the Revision of your chip with Melabs USB programer. Only with Microchips IDE and a Pickit or ICD programers.
1. Can you test with increased conversion time as the Errata says?
2. Can you test with Vdd reference instead of FVR to be sure of the cause of this jitter? In this case use a linear 5V regulator to have the cleanest Vdd power supply.
Ioannis
-
Re: SOLVED: How can I reduce ADC drift
Quote:
Originally Posted by
Ioannis
I do not think you can see the Revision of your chip with Melabs USB programer. Only with Microchips IDE and a Pickit or ICD programers.
That's what I'm afraid of. I never got my PK4 to work right.
Quote:
Originally Posted by
Ioannis
1. Can you test with increased conversion time as the Errata says?
I could try that.
Quote:
Originally Posted by
Ioannis
2. Can you test with Vdd reference instead of FVR to be sure of the cause of this jitter? In this case use a linear 5V regulator to have the cleanest Vdd power supply.
Ioannis
I was using VDD before, jittery. I'm using FVR x 4 right now, still jittery.
And 7805 can't handle 3A anyways. That's why I switched to TPS56637 design.
-
Re: SOLVED: How can I reduce ADC drift
Can't edit post 23:
Quote:
I took OUT the manual averaging routine; it doesn't go to the extreme ends (rarely get completely to 0 or 1024 because of jittter).
I'd like to try the ADC² average a try. Hardware should be faster than anything I can write in PBP.
-
Re: SOLVED: How can I reduce ADC drift
Is it possible to just feed a clean 5V to this chip, just to test the ADC?
Ioannis
-
Re: SOLVED: How can I reduce ADC drift
Have to go to restaurant for wife's birthday. Gonna try 2 bench power supplies later.
-
Re: SOLVED: How can I reduce ADC drift
Absolutely, wife is coming first!
So you will have a peacefull rest of the day!
When you will test it, please try also instead of a pot, just a voltage divider, say two 1K resistor in series to feed half of the supply to the adc. Maybe it is a pot problem.
Ioannis
-
Re: SOLVED: How can I reduce ADC drift
i have a 16f18875 , on a microchip HPC curiosity board, the adc is quite stable.
reading the onboard pot has a statistical result from over 3600 readings like this below. for 99.8% of reads its within 3 counts.
there is no adc problem to find.
0000,0000,0000,0000,0000,0000,0002,0001,0108,1754 1731 0003,0001,0000,0000,0000,0000,0000,0000,0000,0000
1731 reads are at the mean , 1754 are 1 count down 108 are 2 down 3 are 1 up ...etc
max variance is -4 to + 2 counts , the two extremes coincide with my air conditioner compressor cycling
until you figure what you are doing wrong to cause so much noise on your power rails you are just painting over the real problem
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
ADCLK = 32
LED=0
Mainloop:
mean = 0
for i = 0 to 9
ADCIN 0, ADCinput
mean = mean + ADCinput
next
mean = mean/10
DEBUG "mean ",DEC mean,13,10
for j = 0 to 3599
ADCIN 0, ADCinput
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
Yeah, i'll check if desktop power supplies are more stable, but I doubt it.
Then I'll gut my circuit; remove pwm and lcd logic and send adc to pc via usart.
If it doesn't work smooth with just a pot running, I've got other problems.
And that voltage divider test too.
-
Re: SOLVED: How can I reduce ADC drift
1st test: Voltage divider 4K7-4K7 using TPS56637 5V 5A drop-down circuit.
ADC readings for voltage-divider:
9VDC wall adapter, 63-66
XP-581 set at 9VDC, 61-64
XP-605 set at 9VDC, 62-64
(Elenco desktop power supplies)
Naturally the pots jitter a bit more than the fixed divider.
Game plan:
1. remove the PWM and use a fix resistor for backlight.
2. feed the TPS56637 using a 9-12V battery.
3. try using 2 separate TPS56637 circuits:
- 1 for ADC (all inputs).
- 1 for PWM and LCD (all outputs).
The one for inputs "might' be replaced with an ordinary 7805 later. I don't need a lot of current to read pots, switches and encoders.
-
Re: SOLVED: How can I reduce ADC drift
Quote:
Originally Posted by
Demon
1. remove the PWM and use a fix resistor for backlight.
Used 270R resistor for backlight, disabled all PWM/HPWM functionality on code:
- ADC reading jumped to 430, no longer in the 60ies.
- ADC reading for pots also jumped up near 400, which is what I expected for pots near 50%.
(pot reading still went from 0 to 1024 before, so don't know what happened).
ADC reading on V/D still jumps from 428-430, turned power OFF and back ON, now it's 444-447, slowly creeping up as I type, now seeing 450 blink.
-
Re: SOLVED: How can I reduce ADC drift
Quote:
1st test: Voltage divider 4K7-4K7 using TPS56637 5V 5A drop-down circuit.
ADC readings for voltage-divider:
9VDC wall adapter, 63-66
XP-581 set at 9VDC, 61-64
XP-605 set at 9VDC, 62-64
what any of that actually means needs way more explanation
more importantly what does the power rail look like noise wise ?
Quote:
Used 270R resistor for backlight, disabled all PWM/HPWM functionality on code:
i assume that's now one resistor per each backlight
what is the volts across the backlight resistor ?
did you ever measure backlight current @ 5v ?
-
Re: SOLVED: How can I reduce ADC drift
Quote:
Originally Posted by
richard
what any of that actually means needs way more explanation...
It's just the ADC readings I display on the LCD to check for jitter.
Quote:
Originally Posted by
richard
more importantly what does the power rail look like noise wise ?...
I'm reconnecting the scope to see if it changed now that there's no PWM.
Quote:
Originally Posted by
richard
...i assume that's now one resistor per each backlight...
I use only 1 LCD for this
Quote:
Originally Posted by
richard
...what is the volts across the backlight resistor ?...
1.83V, but I think you wanted voltage divider voltages, no?
Quote:
Originally Posted by
richard
...did you ever measure backlight current @ 5v ?
with 270R = 6.7mA
direct 5V = 32mA
-
Re: SOLVED: How can I reduce ADC drift
i was just curious about the backlight's current for potential noise generation, it seemed the most likely candidate to generate that much noise via pwm control. but even at max I of 32mA it should not cause that much noise, so that's my idea's blown out of the water.
-
Re: SOLVED: How can I reduce ADC drift
This is my gutted code, only 1 pot and 1 voltage divider, with LCD (no PWM):
I'm trying to use FVR, no idea if I got all settings for that feature.
Voltage at rail directly over V-D = 4.62V
Voltage on 4K7 ADC to VDD = 2.30V
Voltage on 4K7 ADC to VSS = 2.30V
But I noticed the voltages fluctuate by 0.02V easily while taking readings.
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 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
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
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
ADCinput var WORD
OldADC0 var WORD
OldADC3 var WORD
NewADC0 var WORD
NewADC3 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: B5K" : Pauseus 1
LCDOUT $FE, $D4, "ADC3: Volt-Div" : Pauseus 1
Mainloop:
rem ADC 0
adcin 0, ADCinput
NewADC0 = 1023 - ADCinput ' inverted so pot goes from 0 to 1024
if NewADC0 <> oldadc0 then
oldadc0 = NewADC0
LCDOUT $FE, $94+6, DEC4 oldadc0 : Pauseus 1
endif
rem ADC 3
adcin 3, ADCinput
NewADC3 = ADCinput
if NewADC3 <> oldadc3 then
oldadc3 = NewADC3
LCDOUT $FE, $D4+6, DEC4 oldadc3 : Pauseus 1
endif
GOTO Mainloop
end
I'm setting up my scope to read both rails used by the pot and voltage divider.
-
Re: SOLVED: How can I reduce ADC drift
This is what it looks like.
https://youtu.be/P24631hpoeE
(I don't talk loud cause wife is sleeping)
-
Re: SOLVED: How can I reduce ADC drift
the first thing i notice is you have not set a sample time , not sure if or what the defa may be
try this
DEFINE ADC_SAMPLEUS 50 ' Set sampling time in uS
secondly the adcin command has often been accused of wonky readings when the channel is changed
try this known work around of dual reads after a ch change
Code:
Mainloop:
rem ADC 0
adcin 0, ADCinput
adcin 0, ADCinput
NewADC0 = 1023 - ADCinput ' inverted so pot goes from 0 to 1024
if NewADC0 <> oldadc0 then
oldadc0 = NewADC0
LCDOUT $FE, $94+6, DEC4 oldadc0 : Pauseus 1
endif
rem ADC 3
adcin 3, ADCinput
adcin 3, ADCinput
NewADC3 = ADCinput
if NewADC3 <> oldadc3 then
oldadc3 = NewADC3
LCDOUT $FE, $D4+6, DEC4 oldadc3 : Pauseus 1
endif
GOTO Mainloop
end