View Full Version : SOLVED: How can I reduce ADC jitter
Demon
- 31st October 2024, 02:34
SOLVED: Noisy VDD/VSS using DC-DC converter. ADC stopped bouncing after using a 7805.
https://picbasic.co.uk/forum/showthread.php/26820-How-can-I-reduce-ADC-drift?p=156527#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:
Low=00498 High=00509
Is there anything in the registers that I can "tune" for the ADC?
#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.
richard
- 31st October 2024, 03:12
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
Demon
- 31st October 2024, 03:36
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.
richard
- 31st October 2024, 04:30
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
Ioannis
- 31st October 2024, 09:50
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.
Ioannis
- 31st October 2024, 09:56
The Vdd that resistors are connected to, is the exact same point that PIC Vdd pin is connected also?
Ioannis
Demon
- 31st October 2024, 23:02
The Vdd that resistors are connected to, is the exact same point that PIC Vdd pin is connected also?
Ioannis
Yes, it is.
Ioannis
- 1st November 2024, 07:16
Temperature (heating or cooling PIC) has any effect on the drift?
Ioannis
Demon
- 1st November 2024, 16:40
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...?
Ioannis
- 1st November 2024, 18:28
If the ADC result has no or minimal effect because of temp then we have to look elsewhere for the drift.
Ioannis
Aussie Barry
- 1st November 2024, 21:33
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
Demon
- 1st November 2024, 22:08
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.
richard
- 1st November 2024, 22:40
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
Aussie Barry
- 1st November 2024, 23:58
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/aemDocuments/documents/MCU08/ProductDocuments/Errata/PIC16%28L%29F18857-18877-Silicon-Errata-and-Data-Sheet-Clarification-80000702J.pdf
Cheers
Barry
Aussie Barry
- 2nd November 2024, 00:09
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?
Aussie Barry
- 2nd November 2024, 00:19
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
richard
- 2nd November 2024, 01:18
What happens if the wiper voltage exceeds the FVR voltage?
Ain specs from datasheet
9803
at best the top range of the pot would be useless
Ioannis
- 2nd November 2024, 14:54
Using FVR will make things worse...
Ioannis
Demon
- 2nd November 2024, 18:26
I thought I'd step back and check VDD and VSS using my SDS1104 scope.
This is at 50mV:
98049805
Is it realistic to expect no drift on ADC with this much noise on my lines?
:D
Demon
- 2nd November 2024, 19:28
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.
Demon
- 2nd November 2024, 19:34
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.
Ioannis
- 2nd November 2024, 21:02
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
Demon
- 22nd February 2025, 05:28
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.
#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
Demon
- 22nd February 2025, 05:38
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/aemDocuments/documents/MCU08/ProductDocuments/Errata/PIC16%28L%29F18857-18877-Silicon-Errata-and-Data-Sheet-Clarification-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.
9912
Ioannis
- 22nd February 2025, 14:49
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
Demon
- 22nd February 2025, 18:42
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.
1. Can you test with increased conversion time as the Errata says?
I could try that.
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.
Demon
- 22nd February 2025, 18:50
Can't edit post 23:
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.
Ioannis
- 22nd February 2025, 18:50
Is it possible to just feed a clean 5V to this chip, just to test the ADC?
Ioannis
Demon
- 22nd February 2025, 18:52
Have to go to restaurant for wife's birthday. Gonna try 2 bench power supplies later.
Ioannis
- 22nd February 2025, 20:34
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
richard
- 23rd February 2025, 01:31
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
#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
Demon
- 23rd February 2025, 10:35
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.
Demon
- 24th February 2025, 03:57
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.
Demon
- 24th February 2025, 04:18
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.
richard
- 24th February 2025, 04:37
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 ?
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 ?
Demon
- 24th February 2025, 05:01
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.
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.
...i assume that's now one resistor per each backlight...
I use only 1 LCD for this
...what is the volts across the backlight resistor ?...
1.83V, but I think you wanted voltage divider voltages, no?
...did you ever measure backlight current @ 5v ?
with 270R = 6.7mA
direct 5V = 32mA
richard
- 24th February 2025, 05:21
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.
Demon
- 24th February 2025, 05:27
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.
#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.
Demon
- 24th February 2025, 06:04
This is what it looks like.
https://youtu.be/P24631hpoeE
(I don't talk loud cause wife is sleeping)
richard
- 24th February 2025, 06:08
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
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
richard
- 24th February 2025, 06:24
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
richard
- 24th February 2025, 06:34
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 ?
Demon
- 24th February 2025, 06:36
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
richard
- 24th February 2025, 06:49
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
Demon
- 24th February 2025, 06:55
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.
richard
- 24th February 2025, 06:55
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
Demon
- 24th February 2025, 06:56
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.
Demon
- 24th February 2025, 07:02
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.
Demon
- 24th February 2025, 07:20
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.
richard
- 24th February 2025, 07:26
Coupling changed to AC.
to measure ac noise on rail , noise hopefully in mV and not to many of them
Coupling changed to DC.
for any dc , logic measurements
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
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
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
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
richard
- 24th February 2025, 07:37
changing my test to rs 2 digits
jitter negligible
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
#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
richard
- 24th February 2025, 07:56
using the fvr gets slightly better result [mine is a 3.3v system]
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
#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
Demon
- 24th February 2025, 08:42
...its not designed to average more than one ch and need exclusive use of the adc but have a go
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:
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:
#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.
Demon
- 24th February 2025, 08:44
Can't edit my post:
(like changing from 4V down to 1V)
And of course my code alignment is totally whacked...
Demon
- 24th February 2025, 08:54
using the fvr gets slightly better result [mine is a 3.3v system]
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.
richard
- 24th February 2025, 10:13
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
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
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
richard
- 24th February 2025, 10:26
there are heaps of other ways too
mean var word
ADCinput var word
average
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
ADCIN 0, ADCinput
mean = mean */ 200 + ADCinput */ 55
DEBUG "mean ",DEC mean,",",DEC mean>>2,13,10
Ioannis
- 24th February 2025, 11:39
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
Demon
- 24th February 2025, 21:54
...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
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.
richard
- 24th February 2025, 22:50
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
Demon
- 24th February 2025, 23:36
Ok, thanks.
I've reverted to legacy mode, still using FVR, removed all LCD components, added USART:
#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:
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
Demon
- 24th February 2025, 23:41
With those differences, I suppose I should add a mean average and call it a day.
Demon
- 25th February 2025, 00:20
Would dual TPS56637 step-down circuits help me reduce noise by PWM, LCD and other "noisy stuff"?
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.
Demon
- 25th February 2025, 00:46
I found this, that says it wouldn't hurt to put Schottkys on VDD.
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.com/questions/374512/circuit-with-dual-power-source-replacing-diodes-with-mosfets
I suppose adding a bunch of filter caps downstream of the diodes would help reduce "fluctuations" before it enters the TPS56637.
richard
- 25th February 2025, 03:31
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
richard
- 25th February 2025, 03:40
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
Demon
- 25th February 2025, 04:05
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.
...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/renco-rl-1284-330-inductor-choke-330uh-irms-0-4amp
79F101K-TR-RC 100uH, https://www.mouser.com/datasheet/2/54/79F_series_obsolete-1371239.pdf
...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.
...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.
Demon
- 25th February 2025, 04:08
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.
richard
- 25th February 2025, 04:53
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
richard
- 25th February 2025, 05:08
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
Ioannis
- 25th February 2025, 13:48
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
Demon
- 26th February 2025, 19:57
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.
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. :)
Demon
- 3rd March 2025, 03:04
I've gone back to getting a "basic" ADC routine working for 1 voltage-divider and 2 pots (for a better sampling).
#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...
richard
- 3rd March 2025, 04:46
- 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
9919
typical raw readings
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]
Ioannis
- 3rd March 2025, 14:45
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
Demon
- 3rd March 2025, 23:46
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.
Ioannis
- 4th March 2025, 00:04
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
richard
- 4th March 2025, 01:29
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 ?
Demon
- 4th March 2025, 03:25
- 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.
...- used FOSC / 128,way too slow , while not out of acceptable range fosc/32 is more reasonable...
I've switched to 32 as well.
...used average of 16 ADC readings,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:
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
...- 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.
...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
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...
...
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.
9920
I took everything non-essential off the breadboard (just kept my 2 power LEDs):
9921
#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.
9922 9923
Demon
- 4th March 2025, 03:47
...The mounting holes are "slightly" warm, never noticed that before.
9922 9923
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.
Demon
- 4th March 2025, 03:52
Either my PIC is damaged, or something is whacked inside the breadboard.
105c and wasn't stopping.
#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 4
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
Pause 500 ' Let PIC and LCD stabilize
ADCinput = 0
Mainloop:
adcinput = 1023
end
richard
- 4th March 2025, 04:02
i simply hate this , all these pins made into outputs , shorted to gnd , no attempt to set them low
at power up are they low? before you short it all out
worst idea ever for breadboarding , i leave all pins as inputs unless they need to be an output
all this care re floating inputs is complete bull shit. for a battery operated device it will save a few microwatts that's it.
for the finished manufactured product sure do it , for bread boarding its dangerous nonsense where every mistake will be a bad one
TRISA = %00000010 ' Pin A1 = ADC input 1
TRISB = %00000000 ' Pin B7 = ...not available, ICSPDAT
' Pin B6 = ...not available, ICSPCLK
TRISC = %11000000
I took everything non-essential off the breadboard (just kept my 2 power LEDs):
and all the dangerous grounds
Demon
- 4th March 2025, 04:16
I realized something was seriously wrong when that nothing circuit was taking 670mA. I added:
PORTA = %00000000
PORTB = %00000000
PORTC = %00000000
Before the ANSELx and TRISx and it's taking 20mA now, 33c with no ADC, just ADCinput set at 1023 and the HSEROUT loop.
Demon
- 4th March 2025, 04:22
... i leave all pins as inputs unless they need to be an output
all this care re floating inputs is complete bull shit....
I try to keep my development code as close to final as possible, cause I know I'll forget to change stuff back. At least this way I can fire and forget the pin initialization.
But yeah, major bonehead move on my part. I put the old PIC back in and it runs at 20mA too. Gonna leave that 1st PIC in, just in case I do some other numbnut thing. :D
Thanks mucho Richard.
EDIT: Now this warning will follow my code for the rest of the development.
PORTA = %00000000 '-------------------------------------------'
PORTB = %00000000 ' ALWAYS SET PINS LOW FIRST '
PORTC = %00000000 '-------------------------------------------'
richard
- 4th March 2025, 04:36
I try to keep my development code as close to final as possible, cause I know I'll forget to change stuff back. At least this way I can fire and forget the pin initialization.
grounding unused pins and setting them as outputs is pointless , useless and potentially catastrophic
just leaving them as analog is ten times easier and can never do any harm, setting them as input with wpu on is also ok and can never do any harm
if the device is not battery powered its not worth any sort of effort
Demon
- 4th March 2025, 21:50
- digital input,
- weak pull-up ON,
- pin not connected.
I try to stay away from analog settings; no idea why. Maybe cause I started using only digital way back when.
https://skills.microchip.com/introduction-to-the-pic16f1-enhanced-mcu-architecture/691929
Unit will always be powered by wall adapter, or possibly USB; but never battery..
Demon
- 4th March 2025, 22:26
According to this:
https://skills.microchip.com/introduction-to-the-pic16f1-enhanced-mcu-architecture/691929
The pull-up is disabled automatically when either TRIS is set to an output or the pin is set as an analog input. These changes to TRIS and ANSEL will override WPU settings.
I can just set all pull-ups ON, leave the unused pins unconnected and forget about them. Then use the others as I wish in ANSEL and TRIS.
The only times I need to be concerned with WPU is on pins that must not be disturbed for whatever special reason.
WPUA = %11111111 '----------------------------------------------------------------'
WPUB = %11111111 ' ALWAYS SET WEAK PULL-UPS ON ALL PINS FIRST '
WPUC = %11111111 '----------------------------------------------------------------'
' CHANGES TO ANSEL AND TRIS WILL OVERRIDE AS REQUIRED '
'----------------------------------------------------------------'
ANSELA = %00000010 ' Pin A3 = SW input not implemented yet
' Pin A2 = ADC (B5K) not implemented yet
' Pin A1 = ADC (B5K)
' Pin A0 = ADC (voltage divider) not implemented yet
ANSELB = %00000000
ANSELC = %00000000
TRISA = %00000010 ' Pin A3 = SW input not implemented yet
' Pin A2 = ADC input 2 not implemented yet
' Pin A1 = ADC input 1
' Pin A0 = ADC input 0 not implemented yet
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 ***
EDIT: I can even leave PORT at the top in case a pin is left as analog output.
PORTA = %00000000 '-------------------------------------------'
PORTB = %00000000 ' ALWAYS SET PINS LOW FIRST '
PORTC = %00000000 '-------------------------------------------'
Or did I miss something important...? :(
richard
- 4th March 2025, 23:44
it looks to me that you are creating problems and complications trying to solve a problem that does not exist.
generic pin control solutions will never work for all chips, there are too many chip variations.
pic pins to date always default to inputs, analog if possible. leave them that way unless you need one to be different.
each and every pin you employ needs to configured to suit its usage
mcc makes it easy
9924
Demon
- 5th March 2025, 00:20
it looks to me that you are creating problems and complications...
My memory is getting worse by the year. That's why I try ways to set my code so it's easy to copy and modify for future modules. Of course it rarely works.
Having WPUA.1 = 1 caused leakage to VSS; it wasn't completely 0; varying in the 1.1mV range. My ADC reading never reached 0.
I took out the Port = 0 settings, set WPU properly instead of leaving ANSEL/TRIS override it, and now my ADC reading varies from 0 to 1.
WPUA = %11111101 '----------------------------------------------------------------'
WPUB = %11111111 ' ALWAYS SET WEAK PULL-UPS ON ALL PINS FIRST '
WPUC = %11111111 '----------------------------------------------------------------'
' CHANGES TO ANSEL AND TRIS WILL OVERRIDE AS REQUIRED '
'----------------------------------------------------------------'
ANSELA = %00000010 ' Pin A3 = SW input not implemented yet
' Pin A2 = ADC (B5K) not implemented yet
' Pin A1 = ADC (B5K)
' Pin A0 = ADC (voltage divider) not implemented yet
ANSELB = %00000000
ANSELC = %00000000
TRISA = %00000010 ' Pin A3 = SW input not implemented yet
' Pin A2 = ADC input 2 not implemented yet
' Pin A1 = ADC input 1
' Pin A0 = ADC input 0 not implemented yet
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 ***
Demon
- 5th March 2025, 00:41
Yeah, FVR gave me a dead spot at the high end. These pots already have a slight deadzone at both ends, so FVR made it much more apparent.
adcin 1, ADCreading
ADCinput = ADCreading >> 1
Has light jitter with this pot.
adcin 1, ADCreading
ADCinput = ADCreading >> 2
Works, but if I get a pot that's slightly "less good", I'll get jitters.
I can work with >> 3, that still gives me 128 positions. That<S plenty of increments for a manual control, and I can always multiply by 4 when the flight sim absolutely wants 1024.
richard
- 5th March 2025, 01:17
Having WPUA.1 = 1 caused leakage to VSS; it wasn't completely 0; varying in the 1.1mV range. My ADC reading never reached 0.
makes little sense , the wpu is approx 47k its impact on a 5k pot should not be noticeable , this may be indicative of a different problem
I took out the Port = 0 settings, set WPU properly instead of leaving ANSEL/TRIS override it, and now my ADC reading varies from 0 to 1.
ansel does not override wpu , what you claim makes zero sense
Has light jitter with this pot.
your power supply must be very noisy or the pots are complete crap [possibly microphonic] to get such poor results
richard
- 5th March 2025, 01:32
My memory is getting worse by the year. That's why I try ways to set my code so it's easy to copy and modify for future modules. Of course it rarely works.
it happens to us all , especially if you don't use the knowledge regularly. that why i participate in the forum to keep my "practice" hours up.
the problem here is copying errors forward and propagating ancient pic myths. setting each pin as you employ it to make it work as you want it to is not difficult. imo it is actually easier and less prone to error.
using mcc documents it all for you and consolidates all pin setting into one file, it could not be easier
Demon
- 5th March 2025, 07:52
...ansel does not override wpu , what you claim makes zero sense ...s
Got that info here, at the bottom:
https://developerhelp.microchip.com/xwiki/bin/view/products/mcu-mpu/8bit-pic/enhanced-family/digital-io/
The pull-up will be disabled automatically when either TRIS is set to an output or the pin is set as an analog input. These changes to TRIS and ANSEL will override WPU settings
Anyways, I'm setting the WPU only for the unused pins now (even analog), playing it safe despite that quote above.
...your power supply must be very noisy or the pots are complete crap [possibly microphonic] to get such poor results
The TPS56637 seems very stable, especially since I have nothing on that one. The LCD and LED strip are on a separate TPS56637.
What do you mean by microphonic? Are you talking about the taper? Mine are linear, like Bourns B:
9925
richard
- 5th March 2025, 11:29
What do you mean by microphonic?
like a microphone in that the slightest vibration causes the resistance to vary
The TPS56637 seems very stable
it might be stable but it can till be noisy , use your scope AC coupled X1 probe on say 5mV range 5mS/div, measure peak to peak noise
Ioannis
- 5th March 2025, 18:32
and to be sure, use a resistor divider with cap of 1uF to ground from the tap point to ADC, instead of POT. If your results are stable then you can replace with a pot and see if the problem is the pot itself.
Ioannis
p.s. corrected the drift to jitter on the Thread title
Demon
- 16th March 2025, 00:57
Oh I still get jitter at 1023 or ">> 1". I'm running at ">> 2" and had to use Vref- (3R/1K) cause I was having some instability at the 0 end of scale. The pots already have a slight deadzone under 5% and above 95% (look at the chart above - that was from manuf spec sheet).
I only have a resolution of 256, with a maximum of 88 detents because I TX with changes in ADC larger than 2. But I'm still happy because this is good enough for my application (so far).
https://youtu.be/t96JQeyqYL4
TX:
#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
;--- Interrupts ----------------------------------------------------------------
include "I:\Project_v2\PBP\PBP_Includes\DT_INTS-14_16F1885x-7x.bas"
include "I:\Project_v2\PBP\PBP_Includes\ReEnterPBP.bas"
ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler RX_INT, _RXInterrupt, PBP, no
endm
INT_CREATE ; Creates the interrupt processor
ENDASM
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
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
DEFINE CCP5_BIT 0
;--- Setup registers -----------------------------------------------------------
BAUDCON.3 = 1 ' Enable 16 bit baudrate generator
INTCON = %11000000 ' INTERRUPT CONTROL REGISTER
' bit 7 GIE: Global Interrupt Enable bit
' 1 = Enables all active interrupts
' 0 = Disables all interrupts
' bit 6 PEIE: Peripheral Interrupt Enable bit
' 1 = Enables all active peripheral interrupts
' 0 = Disables all peripheral interrupts
PIE3 = %00100000 ' PERIPHERAL INTERRUPT ENABLE REGISTER 3
' bit 5 RCIE: USART Receive Interrupt Enable bit
' 1 = Enables the USART receive interrupt
' 0 = Enables the USART receive interrupt
PIR3 = %00000000 ' PERIPHERAL INTERRUPT REQUEST REGISTER 3
' bit 5 RCIF: EUSART Receive Interrupt Flag (read-only) bit (1)
' 1 = The EUSART receive buffer is not empty (contains at least one byte)
' 0 = The EUSART receive buffer is empty
FVRCON = %0000000 ' 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 = %00001111 ' ADC CLOCK SELECTION REGISTER
' bit 5-0 ADCCS<5:0>: ADC Conversion Clock Select bits
' 1111 = FOSC/32
ADREF = %00010000 ' ADC REFERENCE SELECTION REGISTER
' bit 4 ADNREF: ADC Negative Voltage Reference Selection bit
' 1 = VREF- is connected to VREF- pin
' 0 = VREF- is connected to AVSS
' 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
' 00 = VREF+ is connected to VDD
ADPCH = %00000000 ' ADC POSITIVE CHANNEL SELECTION REGISTER
' 000000 = ANA0
WPUA = %01100000 ' Pin A7 = ADC-A0 debug
' Pin A4 = ADC-A4 (B10K)
' Pin A3 = SW external pull-down
' Pin A2 = Vref-
' Pin A1 = ADC-A1 (B5K w/SW)
' Pin A0 = ADC-A0 (B5K)
WPUB = %11111111
WPUC = %00100111 ' Pin C7 = RX
' Pin C6 = TX
' Pin C4 = ADC-C4 (B10K)
' Pin C3 = ADC-C3 (B10K)
ANSELA = %00010011 ' Pin A4 = ADC-A4 (B10K)
' Pin A1 = ADC-A1 (B5K w/SW)
' Pin A0 = ADC-A0 (B5K)
ANSELB = %00000000
ANSELC = %00011000 ' Pin C7 = RX
' Pin C6 = TX
' Pin C4 = ADC-C4 (B10K)
' Pin C3 = ADC-C3 (B10K)
TRISA = %00011011 ' Pin A7 = ADC-A0 debug
' Pin A4 = ADC-A4 (B10K)
' Pin A3 = SW
' Pin A1 = ADC-A1 (B5K w/SW)
' Pin A0 = ADC-A0 (B5K)
TRISB = %00000000 ' Pin B7 = ...not available, ICSPDAT
' Pin B6 = ...not available, ICSPCLK
TRISC = %11011000 ' Pin C7 = RX *** Datasheet requirement, INPUT ***
' Pin C6 = TX *** Datasheet requirement, INPUT ***
' Pin C4 = ADC-C4 (B10K)
' Pin C3 = ADC-C3 (B10K)
A0debug var LATA.7
SW var PORTA.3
MsgData var byte[3]
MsgCode VAR BYTE
ADCinput var WORD
ADCcalc var WORD
ADCdiff var WORD
ADCchange var byte
ShiftRight var byte
OldADC var WORD
OldADC_A0 var WORD
OldADC_A1 var WORD
OldADC_A4 var WORD
OldADC_C3 var WORD
OldADC_C4 var WORD
OldSW var BYTE
RXoccurred var BYTE
A0debug = 0
RXoccurred = 0 ' Clear RX flag
@ INT_ENABLE RX_INT ; Enable USART Receive interrupts
Pause 1500 ' Let PIC and LCD stabilize
goto Start
;--- Interrupts ----------------------------------------------------------------
RXInterrupt:
hserin [ STR MsgData\3 ]
while BAUDCON1.6 = 0 ' Check RCIDL bit
wend
RXoccurred = 1 ' Set flag
@ INT_RETURN
;--- Subroutines ---------------------------------------------------------------
SendData:
hserout [ MsgData[0], MsgData[1], MsgData[2] ]
while TX1STA.1 = 0 ' Check TRMT bit
wend
while RXoccurred = 0 ' Check for interrupt
wend
RXoccurred = 0 ' Set flag
ADCchange = 1
RETURN
ProcessADC:
ADCchange = 0
if ADCcalc < oldADC then
ADCdiff = oldADC - ADCcalc
else
ADCdiff = ADCcalc - oldADC
endif
IF ADCdiff > 2 then ' Check for Diff over 2
MsgData[0] = MsgCode
if ADCcalc <> oldADC then ' ADC value changed
MsgData[1] = ADCcalc.byte1 : MsgData[2] = ADCcalc.byte0
GOSUB SendData
endif
ELSE
IF ADCdiff > 0 then ' Check for Diff over 0
if ADCcalc = 0 then ' Reached end of rotation
MsgData[1] = ADCcalc.byte1 : MsgData[2] = ADCcalc.byte0
GOSUB SendData
ELSE
if ADCcalc = 255 then ' Reached end of rotation
MsgData[1] = ADCcalc.byte1 : MsgData[2] = ADCcalc.byte0
GOSUB SendData
endif
endif
endif
endif
RETURN
Start:
ADCinput = 0 : ADCdiff = 0 : ADCcalc = 0
OldADC_A0 = 9999 : OldADC_A1 = 9999 : OldADC_A4 = 9999 : OldADC_C3 = 9999 : OldADC_C4 = 9999
OldSW = 9
ShiftRight = 2
Mainloop:
rem ADC A0 test
MsgCode = 0
adcin 0, ADCinput
ADCcalc = ADCinput >> ShiftRight
oldADC = OldADC_A0
gosub ProcessADC
if ADCchange = 1 then
A0debug = 1
OldADC_A0 = ADCcalc
A0debug = 0
endif
rem ADC A1 test
MsgCode = 1
adcin 1, ADCinput
ADCcalc = ADCinput >> ShiftRight
oldADC = OldADC_A1
gosub ProcessADC
if ADCchange = 1 then
OldADC_A1 = ADCcalc
endif
rem SW A3
MsgCode = 3
if SW <> oldSW then
oldSW = SW
MsgData[0] = MsgCode : MsgData[1] = oldSW :MsgData[2] = " "
GOSUB SendData
endif
rem ADC A4 test
MsgCode = 4
adcin 4, ADCinput
ADCcalc = ADCinput >> ShiftRight
oldADC = OldADC_A4
gosub ProcessADC
if ADCchange = 1 then
OldADC_A4 = ADCcalc
endif
rem ADC C3 test
MsgCode = 5
adcin 19, ADCinput
ADCcalc = ADCinput >> ShiftRight
oldADC = OldADC_C3
gosub ProcessADC
if ADCchange = 1 then
OldADC_C3 = ADCcalc
endif
rem ADC C4 test
MsgCode = 6
adcin 20, ADCinput
ADCcalc = ADCinput >> ShiftRight
oldADC = OldADC_C4
gosub ProcessADC
if ADCchange = 1 then
OldADC_C4 = ADCcalc
endif
GOTO Mainloop
end
RX:
#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
;--- Interrupts ----------------------------------------------------------------
include "I:\Project_v2\PBP\PBP_Includes\DT_INTS-14_16F1885x-7x.bas"
include "I:\Project_v2\PBP\PBP_Includes\ReEnterPBP.bas"
ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler RX_INT, _RXInterrupt, PBP, no
endm
INT_CREATE ; Creates the interrupt processor
ENDASM
DEFINE OSC 32
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 PORTA ' PWM Pulse out to LED strips
DEFINE CCP5_BIT 4
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
INTCON = %11000000 ' INTERRUPT CONTROL REGISTER
' bit 7 GIE: Global Interrupt Enable bit
' 1 = Enables all active interrupts
' 0 = Disables all interrupts
' bit 6 PEIE: Peripheral Interrupt Enable bit
' 1 = Enables all active peripheral interrupts
' 0 = Disables all peripheral interrupts
PIE3 = %00100000 ' PERIPHERAL INTERRUPT ENABLE REGISTER 3
' bit 5 RCIE: USART Receive Interrupt Enable bit
' 1 = Enables the USART receive interrupt
' 0 = Enables the USART receive interrupt
PIR3 = %00000000 ' PERIPHERAL INTERRUPT REQUEST REGISTER 3
' bit 5 RCIF: EUSART Receive Interrupt Flag (read-only) bit (1)
' 1 = The EUSART receive buffer is not empty (contains at least one byte)
' 0 = The EUSART receive buffer is empty
CCP3CON = %10001111 ' CCP3 CONTROL REGISTER
' bit 7 EN: CCPx Module Enable bit
' 1 = CCPx is enabled
' bit 4 FMT: CCPW (Pulse Width) Alignment bit
' MODE = PWM mode
' 0 = Right-aligned format
' bit 3-0 MODE<3:0>: CCPx Mode Select bits(1)
' 1111 = PWM mode
CCP5CON = %10001111 ' CCP5 CONTROL REGISTER
' bit 7 EN: CCPx Module Enable bit
' 1 = CCPx is enabled
' bit 4 FMT: CCPW (Pulse Width) Alignment bit
' MODE = PWM mode
' 0 = Right-aligned format
' bit 3-0 MODE<3:0>: CCPx Mode Select bits(1)
' 1111 = PWM mode
ADCON0 = %00000000 ' ADC CONTROL REGISTER 0
WPUA = %11101111 ' Pin A7 = ADC-A0 debug
WPUB = %11011111
WPUC = %00111111
ANSELA = %00000000
ANSELB = %00000000
ANSELC = %00000000
TRISA = %00000000 ' Pin A7 = ADC-A0 debug
' Pin A4 = PWM to LED strips
TRISB = %00000000 ' Pin B7 = ...not available, ICSPDAT
' Pin B6 = ...not available, ICSPCLK
' Pin B5 = PWM to LCD backlight
TRISC = %11000000 ' Pin C7 = RX *** Datasheet requirement, INPUT ***
' Pin C6 = TX *** Datasheet requirement, INPUT ***
A0debug var LATA.7
MsgData var byte[3]
MsgCode VAR BYTE
MsgADC_A0 VAR WORD
MsgADC_A1 VAR WORD
MsgADC_A4 VAR WORD
MsgADC_C3 VAR WORD
MsgADC_C4 VAR WORD
MsgSW VAR BYTE
SWtext VAR BYTE[2]
HPWMlcdBL var BYTE
HPWMledstripe var BYTE
DefaultLcdBL var BYTE
DefaultLedstripe var BYTE
RXoccurred var BYTE
A0debug = 0
HPWMlcdBL = 255 ' OFF
HPWMledstripe = 0 ' OFF
HPWM 3, HPWMlcdBL, 1953
HPWM 5, HPWMledstripe, 1953
RXoccurred = 0 ' Clear RX flag
Pause 200 ' Let PIC and LCD stabilize
goto Start ' Jump over sub-routines
;--- Interrupts ----------------------------------------------------------------
RXInterrupt:
hserin [ STR MsgData\3 ]
' while BAUDCON1.6 = 0 ' Check RCIDL bit
' wend
RXoccurred = 1 ' Set flag
@ INT_RETURN
;--- Subroutines ---------------------------------------------------------------
SendConfirmation:
hserout [ MsgData[0], MsgData[1], MsgData[2] ]
' while TX1STA.1 = 0 ' Check TRMT bit
' wend
RETURN
ProcessADC_A0:
A0debug = 1
MsgADC_A0.byte1 = MsgData[1] : MsgADC_A0.byte0 = MsgData[2]
LCDOUT $FE, $C0+3, DEC4 MsgADC_A0
RXoccurred = 0 ' Clear RX flag
HPWMlcdBL = MsgADC_A0
HPWM 3, HPWMlcdBL, 1953
MsgData[0] = MsgCode : MsgData[1] = "O" : MsgData[2] = "K"
gosub SendConfirmation
LCDOUT $FE, $C0+8, "x" : LCDOUT $FE, $C0+19, " "
LCDOUT $FE, $94+8, " " : LCDOUT $FE, $94+19, " "
LCDOUT $FE, $D4+8, " " : LCDOUT $FE, $D4+19, " "
A0debug = 0
RETURN
ProcessADC_A1:
MsgADC_A1.byte1 = MsgData[1] : MsgADC_A1.byte0 = MsgData[2]
LCDOUT $FE, $94+3, DEC4 MsgADC_A1
RXoccurred = 0 ' Clear RX flag
HPWMledstripe = 255 - MsgADC_A1 ' Invert value
HPWM 5, HPWMledstripe, 1953
MsgData[0] = MsgCode : MsgData[1] = "O" : MsgData[2] = "K"
gosub SendConfirmation
LCDOUT $FE, $C0+8, " " : LCDOUT $FE, $C0+19, " "
LCDOUT $FE, $94+8, "x" : LCDOUT $FE, $94+19, " "
LCDOUT $FE, $D4+8, " " : LCDOUT $FE, $D4+19, " "
RETURN
ProcessSW3:
if MsgData[1] = 0 then
SWtext[0] = "O" : SWtext[1] = "f" : SWtext[2] = "f"
ELSE
SWtext[0] = "O" : SWtext[1] = "n" : SWtext[2] = " "
ENDIF
LCDOUT $FE, $D4+3, SWtext[0], SWtext[1], SWtext[2], " "
RXoccurred = 0 ' Clear RX flag
MsgData[0] = MsgCode : MsgData[1] = "O" : MsgData[2] = "K"
gosub SendConfirmation
LCDOUT $FE, $C0+8, " " : LCDOUT $FE, $C0+19, " "
LCDOUT $FE, $94+8, " " : LCDOUT $FE, $94+19, " "
LCDOUT $FE, $D4+8, "x" : LCDOUT $FE, $D4+19, " "
RETURN
ProcessADC_A4:
MsgADC_A4.byte1 = MsgData[1] : MsgADC_A4.byte0 = MsgData[2]
RXoccurred = 0 ' Clear RX flag
LCDOUT $FE, $C0+14, DEC4 MsgADC_A4
MsgData[0] = MsgCode : MsgData[1] = "O" : MsgData[2] = "K"
gosub SendConfirmation
LCDOUT $FE, $C0+8, " " : LCDOUT $FE, $C0+19, "x"
LCDOUT $FE, $94+8, " " : LCDOUT $FE, $94+19, " "
LCDOUT $FE, $D4+8, " " : LCDOUT $FE, $D4+19, " "
RETURN
ProcessADC_C3:
MsgADC_C3.byte1 = MsgData[1] : MsgADC_C3.byte0 = MsgData[2]
RXoccurred = 0 ' Clear RX flag
LCDOUT $FE, $94+14, DEC4 MsgADC_C3
MsgData[0] = MsgCode : MsgData[1] = "O" : MsgData[2] = "K"
gosub SendConfirmation
LCDOUT $FE, $C0+8, " " : LCDOUT $FE, $C0+19, " "
LCDOUT $FE, $94+8, " " : LCDOUT $FE, $94+19, "x"
LCDOUT $FE, $D4+8, " " : LCDOUT $FE, $D4+19, " "
RETURN
ProcessADC_C4:
MsgADC_C4.byte1 = MsgData[1] : MsgADC_C4.byte0 = MsgData[2]
RXoccurred = 0 ' Clear RX flag
LCDOUT $FE, $D4+14, DEC4 MsgADC_C4
MsgData[0] = MsgCode : MsgData[1] = "O" : MsgData[2] = "K"
gosub SendConfirmation
LCDOUT $FE, $C0+9, " " : LCDOUT $FE, $C0+19, " "
LCDOUT $FE, $94+9, " " : LCDOUT $FE, $94+19, " "
LCDOUT $FE, $D4+9, " " : LCDOUT $FE, $D4+19, "x"
RETURN
Start:
HPWMlcdBL = 150
HPWMledstripe = 150
MsgADC_A0 = 0
MsgADC_A1 = 0
MsgADC_A4 = 0
MsgADC_C3 = 0
MsgADC_C4 = 0
MsgSW = 0
HPWM 3, HPWMlcdBL, 1953
HPWM 5, HPWMledstripe, 1953
LCDOUT $FE, 1
LCDOUT $FE, $80, " ADC TEST with SW "
LCDOUT $FE, $C0, "A0:____ _ A4:____ _"
LCDOUT $FE, $94, "A1:____ _ C3:____ _"
LCDOUT $FE, $D4, "SW:____ _ C4:____ _"
@ INT_ENABLE RX_INT ; Enable USART Receive interrupts
Mainloop:
while RXoccurred = 0 ' Check for interrupt
wend
MsgCode = MsgData[0]
if MsgCode = 0 then
gosub ProcessADC_A0
else
if MsgCode = 1 then
gosub ProcessADC_A1
else
if MsgCode = 3 then
gosub ProcessSW3
else
if MsgCode = 4 then
gosub ProcessADC_A4
else
if MsgCode = 5 then
gosub ProcessADC_C3
else
if MsgCode = 6 then
gosub ProcessADC_C4
endif
endif
endif
endif
endif
endif
GOTO Mainloop
end
Powered by vBulletin® Version 4.1.7 Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.