Scaling ADC Result to a Set Range


Closed Thread
Results 1 to 40 of 45

Hybrid View

  1. #1


    Did you find this post helpful? Yes | No

    Default Re: Scaling ADC Result to a Set Range

    the voltage to the pot is probably fluxuating small amount....... add a good size cap to wiper arm (1 microfarad +-) to smooth voltage.

  2. #2


    Did you find this post helpful? Yes | No

    Default Re: Scaling ADC Result to a Set Range

    Quote Originally Posted by amgen View Post
    the voltage to the pot is probably fluxuating small amount....... add a good size cap to wiper arm (1 microfarad +-) to smooth voltage.
    I added a 1uF, 63V electrolytic cap between the middle wiper arm input to the PIC and GND, but no change. I measured the voltage on the middle wiper arm of the pot and with a reading of '255' I see 4.99V and with '1' I see 0.00V.

    Am I doing something wrong with using ADRESH in 8-bit mode?

  3. #3


    Did you find this post helpful? Yes | No

    Default Re: Scaling ADC Result to a Set Range

    Interestingly, if I switch to 10-bit resolution on ADC I get values from 5-1023. I think there must be something wrong with my config or code:

    Code:
    #DEFINE USE_LCD_FOR_DEBUG   ; comment out for non-debug use
    
    ' Vdd      -> pin 1         -> +5V   
    ' RC5/Rx   -> pin 5         -> EUSART receive
    ' RC4/Tx   -> pin 6         -> EUSART transmit (LCD)
    ' RA1      -> pin 12        -> trim pot input (1 uF electrolytic cap?)
    ' Vss      -> pin 14        -> GND
       
    DEFINE OSC 16               ; Set oscillator 16Mhz
    
    DEFINE ADC_BITS      10     ; Set number of bits in result
    DEFINE ADC_SAMPLEUS  50     ; Set sampling time in uS (was 5)
    DEFINE ADC_CLOCK     3      ; Set clock source (3=rc)
    
    DEFINE HSER_TXSTA   20h     ; Set transmit status and control register
    DEFINE HSER_BAUD    2400    ; Set baud rate
    
                                   
    ' ***************************************************************
    ' Device Fuses
    ' ***************************************************************
    
    #CONFIG
       __config _CONFIG1, _FOSC_INTOSC & _WDTE_ON & _PWRTE_ON & _MCLRE_OFF & _CP_OFF & _CPD_OFF
       __config _CONFIG2, _PLLEN_OFF & _STVREN_ON & _BORV_LO & _LVP_OFF
    #ENDCONFIG
    
    ' ***************************************************************
    ' Initialization
    ' ***************************************************************
    
    OSCCON    = %01111000       ; 16MHz internal osc
    
    APFCON0.2 = 0               ; Tx on RC4 for LCD display
    APFCON0.7 = 0               ; Rx on RC5
    
    BAUDCON.4 = 1               ; Transmit inverted data to the Tx pin
    
    ANSELC    = 0               ; Digital only for all PortC pins
    TRISC     = 0               ; Make all PORTC pins output
    
    TRISA     = %00000010	    ; Make all pins output except for RA1 (trim pot input)
    ANSELA    = %00000010       ; Analog on PORTA.1 (AN1) only
    
    FVRCON    = 0               ; Fixed Voltage Reference is disabled
    ADCON0    = %00000101       ; ADC (analog-to-digital) is enabled on AN1 (RA1) only
    PAUSEUS 20                  ; wait for the analog switch 'glitch' to die down
    ADCON1.7  = 1               ; Right-justified results in 10-bits
    
    #IFDEF USE_LCD_FOR_DEBUG
        LCD_INST   CON 254       ' instruction
        LCD_CLR    CON 1         ' Clear screen
        LCD_L1     CON 128       ' LCD line 1
        LCD_L2     CON 192       ' LCD line 2
    #ENDIF
    
    ADCInVal       VAR WORD      ; stores ADCIN result read from trim pot
    compVal        VAR WORD      ; stores last-changed ADC value
    
    GOSUB Do_ADC
    compVal = ADCInVal           ; set initial compare value
                                                               
    Main:
        gosub Do_ADC
        pause 100
        #IFDEF USE_LCD_FOR_DEBUG
            If (compVal > (ADCInVal + 1)) or (compVal < (ADCInVal - 1)) THEn
                ' If this method of reading ADC is as rock-solid as it appears.
                ' then I can remove the +/- 1 before doing anything; it would be
                ' IF ADCInVal <> compVal
                
                ' DO SOMETHING HERE        
                compVal = ADCInVal
            endif
            HSEROUT [LCD_INST, LCD_CLR]
            pause 5
            HSEROUT ["ADC val=", DEC ADCInVal, "       ", 13, 10] ; Send text followed by carriage return and linefeed
        #ENDIF
     
    GOTO Main
    
    Do_ADC:
        PAUSEUS 50              ' Wait for A/D channel acquisition time
                                ' (does this need to be the same as ADC_SAMPLEUS?)
        ADCON0.1 = 1            ' Start conversion
        
        WHILE ADCON0.1          ' Wait for it to complete
        WEND
    
        ADCInVal.HighBYTE = ADRESH
        ADCInVal.LOWBYTE = ADRESL
    return

  4. #4


    Did you find this post helpful? Yes | No

    Default Re: Scaling ADC Result to a Set Range

    If I remove the DEFINEs usually associated with the ADCIN function:

    Code:
    'DEFINE ADC_BITS      10     ; Set number of bits in result
    'DEFINE ADC_SAMPLEUS  50     ; Set sampling time in uS (was 5)
    'DEFINE ADC_CLOCK     3      ; Set clock source (3=rc)
    and use Fosc/8 as the timer:

    Code:
    ADCON1    = %00010000       ; Left-justified results in 8-bits; Fosc/8 as timer
    Then I get 0-255. If I do the same for 10-bit resolution, though, I now get 1-1023.

  5. #5


    Did you find this post helpful? Yes | No

    Default Re: Scaling ADC Result to a Set Range

    that's cool...... 1 count in 1023 is small..small error..... that error with 0 volts could be where pic ground is in relation to pot low end...... ground pot low end close to pic ground.....
    what about the fluxuating readings ?

  6. #6


    Did you find this post helpful? Yes | No

    Default Re: Scaling ADC Result to a Set Range

    Quote Originally Posted by amgen View Post
    that's cool...... 1 count in 1023 is small..small error..... that error with 0 volts could be where pic ground is in relation to pot low end...... ground pot low end close to pic ground.....
    what about the fluxuating readings ?
    Now that I'm not using PBP's ADCIN the readings are rock solid.

  7. #7


    Did you find this post helpful? Yes | No

    Default Re: Scaling ADC Result to a Set Range

    I found the math behind the Arduino map function and have replicated it in a subroutine in PBP:

    Code:
    PR2     = 62                ; For 16Mhz OSC the desired output freq of 15,873Hz is
                                ; achieved with this PR2 value (8-bit resolution
                                ; with 1:4 prescaler)
                                
                                ; PWM freq must be ~ 16-20kHz to reduce noise
    MinDuty     CON 100         ; Minimum speed to rotate motor for this application
    MaxDuty     VAR WORD        ; According to Darrel:
                                ;   MaxDuty = (PR2 + 1) * 4
    
    MaxDuty = (PR2 + 1) * 4     ; 252 but with prescaler resolution it's actually 250
    MotorDuty   VAR WORD        ; Actual duty cycle for motor
    MaxADCVal   CON 255         ; 255 for 8-bit; 1023 for 10-bit
    ADCInVal    VAR BYTE        ; stores ADCIN result read from trim pot
    compVal     VAR BYTE        ; stores last-changed ADC value
    
    Main:
        gosub Do_ADC
        pause 100
    
        If ADCInVal <> compVal Then
            #IFDEF USE_LCD_FOR_DEBUG
                HSEROUT [LCD_INST, LCD_CLR]
                pause 5
                HSEROUT ["new ADCInVal=", DEC ADCInVal, "       ", 13, 10] ; Send text followed by carriage return and linefeed
            #ENDIF
            
            GOSUB Map_ADC_Val_to_PWM_Duty
            gosub ChngMotorHPWM
            compVal = ADCInVal
        endif
    
     
    GOTO Main
    
    Do_ADC:
        PAUSEUS 50              ' Wait for A/D channel acquisition time
        ADCON0.1 = 1            ' Start conversion
        
        WHILE ADCON0.1 = 1      ' Wait for it to complete
        WEND
    
        ADCInVal = ADRESH
    
        return
    
    Map_ADC_Val_to_PWM_Duty:
    '   Arduino Map function to emulate:
    '   ===============================
    '   map(value, fromLow, fromHigh, toLow, toHigh)
    
    '   long map(long x, long in_min, long in_max, long out_min, long out_max)
    '   {
    '     return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
    '   }
    
        MotorDuty = (ADCInVal - 0) * (MaxDuty - MinDuty)/(MaxADCVal - 0) + MinDuty
    
        #IFDEF USE_LCD_FOR_DEBUG
            HSEROUT [LCD_INST, LCD_CLR]
            pause 5
            HSEROUT ["MotorDuty=", DEC MotorDuty, "       ", 13, 10] ; Send text followed by carriage return and linefeed
            pause 1500
            HSEROUT [LCD_INST, LCD_CLR]
        #ENDIF
    
        RETURN
    It doesn't look like this is working as expected - any ideas?

  8. #8
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,612


    Did you find this post helpful? Yes | No

    Default Re: Scaling ADC Result to a Set Range

    Hi,
    I don't know exactly how you expect it to work but if Iäm not mistaken your formula, when re-written looks like:
    Code:
    MotorDuty = ADCInVAL * 252 / 255 + 100
    When ADCInVal = 1 Motor Duty will be 100
    When ADCInVAL = 255 MotorDuty will be 352

    Is that what you're seeing?

    /Henrik.

  9. #9


    Did you find this post helpful? Yes | No

    Default Re: Scaling ADC Result to a Set Range

    Quote Originally Posted by RossWaddell View Post
    Now that I'm not using PBP's ADCIN the readings are rock solid.
    Well, they were rock solid. Now the readings are varying quite a lot and even with Melanie's 'averaging' code to pick the middle 8 values from 16 it's still jumping around a lot (and still doesn't read 0 when the trim pot wiper is at the GND end). If I measure the voltage reaching pin 6 (AN1) with a voltmeter it seems accurate and steady, varying from +5V to 0. What am I doing wrong now?

    Code:
    '****************************************************************
    '*  Name    : Nacelle_Steady-On_Lights_12F1840_16Mhz_Int.pbp    *
    '*  Author  : Ross A. Waddell                                   *
    '*  Notice  : Copyright (c) 2016                                *
    '*          : All Rights Reserved                               *
    '*  Date    : 02/02/2016                                        *
    '*  Version : 1.0                                               *
    '*  Notes   : Steady-on nacelle engine lights (TOS Enterprise)  *
    '*          :                                                   *
    '****************************************************************
    
    
    ' TODO:
    ' Add gamma correction
    ' Increase ADC resolution to 1024
    ' Update PWM frequency/prescaler to use higher resolution
    
    
    
    ' The PWM/fade works perfectly when **not** connected to a FET
    '   - if using a FET, the LEDs 'pulse' and blink but don't fade in/out
    '   - use a 2N2222A transistor
    
    
    DEFINE OSC 16                ' Set oscillator 16Mhz
    
    ' For production version of this code, comment out the line below re:
    ' LCD debugging and also update config fuses to have code protect on
    #DEFINE USE_LCD_FOR_DEBUG     ; comment out for non-debug use
    
    ' ***************************************************************
    ' Pin Connections
    ' ***************************************************************
    
    ' VDD    -> pin 1            -> +5V
    ' RA5/Rc -> pin 2            -> EUSART receive
    ' RA2    -> pin 5            -> 1kohm -> 2N2222A transistor -> LEDs
    ' RA1    -> pin 6            -> Trim pot input
    ' RA0/Tx -> pin 7            -> EUSART transmit (LCD)
    ' VSS    -> pin 8            -> GND
    
    ' ***************************************************************
    ' EUSART Settings for Tx/Rc (e.g. LCD)
    ' ***************************************************************
    
    ' > use Mister E PIC Multi-Calc application to get register/DEFINE settings
    ' > as the values are dependent on the OSC and desired baud rate
    
    DEFINE HSER_RCSTA 90h ' Enable serial port & continuous receive
    DEFINE HSER_TXSTA 24h ' Enable transmit, BRGH = 1
    DEFINE HSER_CLROERR 1 ' Clear overflow automatically
    DEFINE HSER_SPBRG 160 ' 9600 Baud @ 16MHz, -0.08%
    
    ' ***************************************************************
    ' Device Fuses
    ' ***************************************************************
    ' PIC chip data sheets can be found here: C:\Program Files\Microchip\MPASM Suite
    
    #CONFIG
       __config _CONFIG1, _FOSC_INTOSC & _WDTE_ON & _PWRTE_ON & _MCLRE_OFF & _CP_OFF & _CPD_OFF
       __config _CONFIG2, _PLLEN_OFF & _STVREN_ON & _BORV_LO & _LVP_OFF
    #ENDCONFIG
    
    ' ***************************************************************
    ' Initialization
    ' ***************************************************************
    
    OSCCON    = %01111000        ' 16MHz internal osc
    pause 100                    ' for EEPROM issue
    
    APFCON.2 = 0                 ; Tx on RA0 for LCD display
    APFCON.7 = 1                 ; Rc on RA5
    APFCON.0 = 0                 ; CCP1 on RA2
    
    ' Some LCD serial modules need inverted data, some do not
    ' Enable the line below if needed, but for SparkFun SerLCD it should be
    ' commented out
    
    'BAUDCON.4 = 1               ; Transmit inverted data to the Tx pin  
    
    ' From Mister E's Multi-Calc (EUSART):
    ' *****************************************************************
    SPBRGH    = 1
    BAUDCON.3 = 1                ' Enable 16 bit baudrate generator
    
    ' *****************************************************************
    
    FVRCON    = 0                ' Fixed Voltage Reference is disabled
    ANSELA    = %00000010        ; Analog on PORTA.1 (AN1) only
    'ADCON0    = %00000101        ' ADC (analog-to-digital) is enabled on AN1 (RA1) only
    'PAUSEUS 20                   ; wait for the analog switch 'glitch' to die down
    ADCON1    = %10010000        ; Right-justified results in 10-bits; Fosc/8 as timer;
                                 ; VREF is connected to VDD
    
    TRISA     = %00100010	     ' Make all pins output except for RA1 (trim pot input)
                                 ' and RA5 (EUSART Rc)
    
    ADCInVal       VAR WORD      ; stores ADCIN result read from trim pot
    LEDBrVal       VAR WORD
    FadeInPause    CON 25        ; Pause during LED fade in
    
    i              VAR WORD
    
    ' ***************************************************************
    ' Set up PWM on CCP1
    ' ***************************************************************
    
    CCP1CON = %00001100          ; Use CCP1 in PWM mode
    
    ' Set duty cycle registers initially to 0
    CCP1CON.4 = 0
    CCP1CON.5 = 0
    CCPR1L    = 0
    
    ' Use Mister E's PICMultiCalc_1.3.1.exe application (Windows only)   
    ' to determine prescaler and PR2 values for given OSC frequency (e.g. 16Mhz)
    ' and duty cycle (use 100% to see highest actual value)
    
    ' ************************
    ' CCP1 uses TMR2
    ' ************************
                           
    T2CON   = %00000110         ; Timer2 on with 1:16 prescaler
    PR2     = 255               ; For 16Mhz OSC the desired output freq of 976.563Hz
                                ; is achieved with this PR2 value (10-bit resolution
                                ; with 1:16 prescaler)
                                
    MaxDuty       VAR WORD      ; According to Darrel:
                                ;   MaxDuty = (PR2 + 1) * 4
    
    MaxDuty = (PR2 + 1) * 4     ; 1024
    MinDuty       CON 0         ; Minimum brightness for this application
    MaxADCVal     CON 1023      ; 255 for 8-bit; 1023 for 10-bit
    compVal       VAR WORD      ; stores last-changed ADC value
    
    
    CounterA      var BYTE		' Just a BYTE Temporary working variable
    DataW         var WORD		' Just a WORD Temporary working variable
    RawData       var WORD [16]	' Array holding ADC Result
    
    
    #IFDEF USE_LCD_FOR_DEBUG
    '   Display control codes for SerLCD serial LCD (SparkFun part #LCD-09395)
    '   (see 'Dropbox\PBP Projects\PIC Datasheets\SerLCD_V2_5 Datasheet.pdf' 
    '   for list of control codes)
        LCD_INST   CON 254       ' instruction
        LCD_CLR    CON 1         ' Clear screen
        LCD_L1     CON 128       ' LCD line 1
        LCD_L2     CON 192       ' LCD line 2
        LCD_BR_CMD CON 124       ' command character for adjusting backlight brightness
        LCD_BR_LVL CON 140       ' 140==40%
    #ENDIF
    
    ' Should only need to do this one time to adjust backlight brightness
    '#IFDEF USE_LCD_FOR_DEBUG
    '    HSEROUT [LCD_BR_CMD, LCD_BR_LVL]
    '    PAUSE 5
    '#ENDIF
    
    #IFDEF USE_LCD_FOR_DEBUG
        pause 1000
        HSEROUT [LCD_INST, LCD_CLR, "LCD Init"]
        pause 5
        HSEROUT [LCD_INST, LCD_L2, "SerLCD_V2_5"]
        pause 500
    #ENDIF
    
    GOSUB DO_ADCIN_Chk
    LEDBrVal = ADCInVal
    compVal = LEDBrVal
    'compVal = ADCInVal
    'GOSUB Map_VrefInVal_to_PWM_Duty
    
    #IFDEF USE_LCD_FOR_DEBUG
        HSEROUT [LCD_INST, LCD_CLR]
        pause 5
        HSEROUT ["LEDBrVal=",DEC LEDBrVal,"  "]
        pause 500
    #ENDIF
    
    ' Fade in LED to final brightness
    FOR i = 0 to LEDBrVal
        CCP1CON.4 = i.0
        CCP1CON.5 = i.1
        CCPR1L    = i >> 2 
                
        pause FadeInPause
    
        #IFDEF USE_LCD_FOR_DEBUG
            HSEROUT [LCD_INST, LCD_CLR]
            pause 5
            HSEROUT ["i=",DEC i,"  "]
        #ENDIF
    NEXT i
    
    
    Main:
        GOSUB DO_ADCIN_Chk
        PAUSE 100
    
        IF ADCInVal <> compVal THEN
            #IFDEF USE_LCD_FOR_DEBUG
                HSEROUT [LCD_INST, LCD_CLR]
                pause 5
                HSEROUT ["new ADCInVal", LCD_INST, LCD_L2, DEC ADCInVal, "  "]
            #ENDIF
    
            LEDBrVal = ADCInVal
            compVal = LEDBrVal
            gosub ChngLEDBrightness
        ENDIF
    GOTO Main
    
    '*********** Read ADC or USART Rc inputs *******************************
    Do_ADCIN_Chk:
    '	Stuff 16 Element WORD Array full of ADC values
    '	----------------------------------------------
    	For CounterA=0 to 15
            ADCON0    = %00000101 ' Select Channel, Turn-On A/D
    						      '	7=0 Unused
    						      '	6=0 Unused
    						      '	5=0 )
    						      '	4=0 )
    						      '	3=0 ) selects AN1
    						      '	2=0 )
    						      '	1=0 Go-done Bit
    						      '	0=1 switch-On ADC Module
    		Pauseus 50			     ' Wait for channel to setup
            ADCON0.1 = 1			 ' Start conversion
    		While ADCON0.1=1:Wend	 ' Wait for conversion
    		DataW.HighByte=ADRESH	 ' Read variable from ADC and save
    		DataW.LowByte=ADRESL
    		RawData(CounterA)=DataW
    	Next CounterA
    
    '	Sort ADC Input
    '	--------------
    	CounterA=0
        GetADCSortLoop:
    	If RawData(CounterA+1) < RawData(CounterA) then
    		DataW=RawData(CounterA)
    		RawData(CounterA)=RawData(CounterA+1)
    		RawData(CounterA+1)=DataW
    		If CounterA>0 then CounterA=CounterA-2
    	endif
    	CounterA=CounterA+1
    	If CounterA < 15 then goto GetADCSortLoop
    
    '	Quanticise, discarding top and bottom FOUR elements
    '	----------------------------------------------------
    	DataW=0
    	For CounterA=4 to 11
    		DataW=DataW+RawData(CounterA)
    	Next CounterA
    	ADCInVal=DataW>>3			' Divide Result by EIGHT
    
        ' Read trim pot Vref to set LED brightness
    '    PAUSEUS 50              ' Wait for A/D channel acquisition time
    '    ADCON0.1 = 1            ' Start conversion
        
    '    WHILE ADCON0.1 = 1      ' Wait for it to complete
    '    WEND
    '    ADCInVal.HighBYTE = ADRESH
    '    ADCInVal.LOWBYTE = ADRESL
    
    return
    
    '*********** Set duty registers ****************************************
    ChngLEDBrightness:
        CCP1CON.4 = LEDBrVal.0
        CCP1CON.5 = LEDBrVal.1
        CCPR1L    = LEDBrVal >> 2
        
    RETURN

  10. #10
    Join Date
    May 2013
    Location
    australia
    Posts
    2,644


    Did you find this post helpful? Yes | No

    Default Re: Scaling ADC Result to a Set Range

    after setting adc input you need to Wait A/D channel acquisition time before you Start conversion

  11. #11


    Did you find this post helpful? Yes | No

    Default Re: Scaling ADC Result to a Set Range

    I removed the CCP stuff to leave just the ADC and still the value jumps around by +- 6 or more:

    Code:
    DEFINE OSC 16                ' Set oscillator 16Mhz
    
    ' For production version of this code, comment out the line below re:
    ' LCD debugging and also update config fuses to have code protect on
    #DEFINE USE_LCD_FOR_DEBUG     ; comment out for non-debug use
    
    ' ***************************************************************
    ' Pin Connections
    ' ***************************************************************
    
    ' VDD    -> pin 1            -> +5V
    ' RA5/Rc -> pin 2            -> EUSART receive
    ' RA2    -> pin 5            -> 1kohm -> 2N2222A transistor -> LEDs
    ' RA1    -> pin 6            -> Trim pot input
    ' RA0/Tx -> pin 7            -> EUSART transmit (LCD)
    ' VSS    -> pin 8            -> GND
    
    ' ***************************************************************
    ' EUSART Settings for Tx/Rc (e.g. LCD)
    ' ***************************************************************
    
    ' > use Mister E PIC Multi-Calc application to get register/DEFINE settings
    ' > as the values are dependent on the OSC and desired baud rate
    
    DEFINE HSER_RCSTA 90h ' Enable serial port & continuous receive
    DEFINE HSER_TXSTA 24h ' Enable transmit, BRGH = 1
    DEFINE HSER_CLROERR 1 ' Clear overflow automatically
    DEFINE HSER_SPBRG 160 ' 9600 Baud @ 16MHz, -0.08%
    
    ' ***************************************************************
    ' Device Fuses
    ' ***************************************************************
    ' PIC chip data sheets can be found here: C:\Program Files\Microchip\MPASM Suite
    
    #CONFIG
       __config _CONFIG1, _FOSC_INTOSC & _WDTE_ON & _PWRTE_ON & _MCLRE_OFF & _CP_OFF & _CPD_OFF
       __config _CONFIG2, _PLLEN_OFF & _STVREN_ON & _BORV_LO & _LVP_OFF
    #ENDCONFIG
    
    ' ***************************************************************
    ' Initialization
    ' ***************************************************************
    
    OSCCON    = %01111000        ' 16MHz internal osc
    pause 100                    ' for EEPROM issue
    
    APFCON.2 = 0                 ; Tx on RA0 for LCD display
    APFCON.7 = 1                 ; Rc on RA5
    APFCON.0 = 0                 ; CCP1 on RA2
    
    ' Some LCD serial modules need inverted data, some do not
    ' Enable the line below if needed, but for SparkFun SerLCD it should be
    ' commented out
    
    'BAUDCON.4 = 1               ; Transmit inverted data to the Tx pin  
    
    ' From Mister E's Multi-Calc (EUSART):
    ' *****************************************************************
    SPBRGH    = 1
    BAUDCON.3 = 1                ' Enable 16 bit baudrate generator
    
    ' *****************************************************************
    
    FVRCON    = 0                ' Fixed Voltage Reference is disabled
    ANSELA    = %00000010        ; Analog on PORTA.1 (AN1) only
    ADCON0    = %00000101        ' ADC (analog-to-digital) is enabled on AN1 (RA1) only
    PAUSEUS 20                   ; wait for the analog switch 'glitch' to die down
    ADCON1    = %10010000        ; Right-justified results in 10-bits; Fosc/8 as timer;
                                 ; VREF is connected to VDD
    
    TRISA     = %00100010	     ' Make all pins output except for RA1 (trim pot input)
                                 ' and RA5 (EUSART Rc)
    
    ADCInVal       VAR WORD      ; stores ADCIN result read from trim pot
    compVal        VAR WORD
    
    #IFDEF USE_LCD_FOR_DEBUG
    '   Display control codes for SerLCD serial LCD (SparkFun part #LCD-09395)
    '   (see 'Dropbox\PBP Projects\PIC Datasheets\SerLCD_V2_5 Datasheet.pdf' 
    '   for list of control codes)
        LCD_INST   CON 254       ' instruction
        LCD_CLR    CON 1         ' Clear screen
        LCD_L1     CON 128       ' LCD line 1
        LCD_L2     CON 192       ' LCD line 2
        LCD_BR_CMD CON 124       ' command character for adjusting backlight brightness
        LCD_BR_LVL CON 140       ' 140==40%
    #ENDIF
    
    ' Should only need to do this one time to adjust backlight brightness
    '#IFDEF USE_LCD_FOR_DEBUG
    '    HSEROUT [LCD_BR_CMD, LCD_BR_LVL]
    '    PAUSE 5
    '#ENDIF
    
    #IFDEF USE_LCD_FOR_DEBUG
        pause 1000
        HSEROUT [LCD_INST, LCD_CLR, "LCD Init"]
        pause 5
        HSEROUT [LCD_INST, LCD_L2, "SerLCD_V2_5"]
        pause 500
    #ENDIF
    
    GOSUB DO_ADCIN_Chk
    compVal = ADCInVal
    
    #IFDEF USE_LCD_FOR_DEBUG
        HSEROUT [LCD_INST, LCD_CLR]
        pause 5
        HSEROUT ["ADCInVal=",DEC ADCInVal,"  "]
        pause 500
    #ENDIF
    
    Main:
        GOSUB DO_ADCIN_Chk
        PAUSE 100
    
        IF ADCInVal <> compVal THEN
            #IFDEF USE_LCD_FOR_DEBUG
                HSEROUT [LCD_INST, LCD_CLR]
                pause 5
                HSEROUT ["new ADCInVal", LCD_INST, LCD_L2, DEC ADCInVal, "  "]
            #ENDIF
            compVal = ADCInVal
        ENDIF
    GOTO Main
    
    '*********** Read ADC or USART Rc inputs *******************************
    Do_ADCIN_Chk:
        ' Read trim pot Vref to set LED brightness
        PAUSEUS 50              ' Wait for A/D channel acquisition time
        ADCON0.1 = 1            ' Start conversion
        
        WHILE ADCON0.1 = 1      ' Wait for it to complete
        WEND
        ADCInVal.HighBYTE = ADRESH
        ADCInVal.LOWBYTE = ADRESL
    
    return

Similar Threads

  1. Replies: 4
    Last Post: - 27th January 2015, 15:34
  2. Replies: 4
    Last Post: - 30th May 2012, 08:28
  3. Converting 10bit ADC result to 8 bit
    By jmgelba in forum mel PIC BASIC Pro
    Replies: 9
    Last Post: - 5th March 2012, 20:38
  4. strange A2D 5V scaling result - 16F819
    By Max Power in forum mel PIC BASIC Pro
    Replies: 3
    Last Post: - 8th April 2010, 02:28
  5. Scaling ADC values
    By purkolator in forum mel PIC BASIC Pro
    Replies: 4
    Last Post: - 29th November 2007, 05:14

Members who have read this thread : 0

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

Posting Permissions

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