16F18855 with 5K pot


So I have 2 rotary pots that refuse to go down to ADC=0. So I thought it was a perfect occasion to practice using Vref-.

I've gutted my code so there's only 1 pot being scanned:

Code:
#CONFIG
    __config _CONFIG1, _FEXTOSC_OFF & _RSTOSC_HFINT32 & _CLKOUTEN_OFF & _CSWEN_OFF & _FCMEN_ON
    __config _CONFIG2, _MCLRE_ON & _PWRTE_OFF & _LPBOREN_OFF & _BOREN_ON & _BORV_LO & _ZCD_OFF & _PPS1WAY_OFF & _STVREN_ON & _DEBUG_OFF
    __config _CONFIG3, _WDTCPS_WDTCPS_11 & _WDTE_OFF & _WDTCWS_WDTCWS_7 & _WDTCCS_LFINTOSC
    __config _CONFIG4, _WRT_OFF & _SCANE_available & _LVP_OFF
    __config _CONFIG5, _CP_OFF & _CPD_OFF
#ENDCONFIG

DEFINE OSC 32

DEFINE  ADC_BITS 10                 ' 10-bit Analog to digital
DEFINE  ADC_SAMPLEUS 5              ' Set sampling time in uS

DEFINE  HSER_RXREG PORTC
DEFINE  HSER_RXBIT 7
DEFINE  HSER_TXREG PORTC
DEFINE  HSER_TXBIT 6

DEFINE  HSER_RCSTA 90h              ' Enable serial port & continuous receive
DEFINE  HSER_TXSTA 24h              ' Enable transmit, BRGH = 1
Define  HSER_BAUD 115200
DEFINE  HSER_CLROERR 1              ' Clear overflow automatically
DEFINE  HSER_SPBRGH  0
DEFINE  HSER_SPBRG  68

;--- Setup registers -----------------------------------------------------------

BAUDCON.3 = 1                       ' Enable 16 bit baudrate generator
FVRCON = %0000000                  ' FIXED VOLTAGE REFERENCE CONTROL REGISTER
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
WPUA = %11110011
WPUB = %11111111
WPUC = %00111111
ANSELA = %00010111                      ' Pin A4 = ADC (B10K)  ...  not implemented
                                        ' Pin A3 = SW input 3
                                        ' Pin A2 = Vref-
                                        ' Pin A1 = ADC (B5K w/SW)
                                        ' Pin A0 = ADC (B5K)
ANSELB = %00000000
ANSELC = %00000000
TRISA = %00011111                       ' Pin A4 = ...  not implemented
                                        ' Pin A3 = ...  not implemented
                                        ' Pin A2 = Vref-
                                        ' 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 ***
SW                  var PORTA.3         '  ...  not implemented

MsgData             var byte[3]
MsgCode             VAR BYTE

ADCinput            var WORD
ADCcalc             var WORD
ADCdiff             var WORD

OldADC              var WORD
OldADC0             var WORD
OldADC1             var WORD

    Pause 1500                           ' Let PIC and LCD stabilize

    OldADC0 = 9999

    goto Mainloop
    
;--- Subroutines ---------------------------------------------------------------

SendData:
    MsgData[0] = MsgCode   :   MsgData[1] = ADCcalc.byte1   :   MsgData[2] = ADCcalc.byte0
    hserout [   MsgData[0],    MsgData[1],  MsgData[2]   ]                             
    while TX1STA.1 = 0                                          ' Check TRMT bit
    wend

    oldADC0 = ADCcalc   
RETURN
    
Mainloop:
    
rem                             ADC A0 test
    MsgCode = 0                                                 ' Record type

    adcin 0, ADCinput
    ADCcalc = ADCinput >> 2
    
    if ADCcalc < oldADC0 then
        ADCdiff = oldADC0 - ADCcalc
    else
        ADCdiff =  ADCcalc - oldADC0
    endif

    IF  ADCdiff > 2 then                                        ' Check for Diff over 2
        if ADCcalc <> oldADC0 then                               ' ADC value changed
            GOSUB SendData                             
        endif
    ELSE
        IF  ADCdiff > 0 then                                    ' Check for Diff over 0
            if ADCcalc = 0 then                                 ' Reached end of rotation
                GOSUB SendData                             
            ELSE
                if ADCcalc = 255 then                           ' Reached end of rotation
                    GOSUB SendData                             
                endif
            endif
        endif
    endif

  GOTO Mainloop
end

I've added banks of caps on the wiper-to-VSS, as well as just before the VDD pin to the pot (0.1uF, 0.01uF and 0.001uF).

I shift right only 2 digits and that seems to have stabilized things quite a lot; no noticeable jitter so far tonight. 256 seems like a workable range for me so far.

The pot has a reading of 2.0mV when full right:

Name:  1 Pot pin 0.jpg
Views: 6549
Size:  177.3 KB


The Vref- pin reads at 15.7mV (used voltage divider 1K (0.985R really) / 3R:

Name:  2 Vref-.jpg
Views: 6587
Size:  147.4 KB


Pot 0 does not go below ADC=12,and is transmitted on the Saleae probe:

Name:  3 Signals on Saleae probe.png
Views: 6535
Size:  12.4 KB


And shows up nicely on LCD on 2nd PIC:

Name:  4 Results on LCD.jpg
Views: 6518
Size:  31.5 KB


I don't get it. I thought setting Vref- at 15.7mV meant that anything reading below that would read as 0...? I thought I was essentially raising the VSS lower range for ADC.

Code:
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

I'm obviously missing something stupid again, but I don't see what. Or I totally misunderstood what Vref- does in life.