Scaling ADC Result to a Set Range


Results 1 to 40 of 45

Threaded View

  1. #36
    Join Date
    May 2013
    Location
    australia
    Posts
    2,698


    Did you find this post helpful? Yes | No

    Default Re: Scaling ADC Result to a Set Range

    I 'm using a pickit2 to power this test so an 0,1 are unavailable (used by pickit) so I changed code to use an3
    and debug via serout . needless to say it works just fine.

    you may need an oscilloscope to look at your an input and power supply for noise (dvm's won't do it)
    have you installed bypass caps on the regulator input/output and the pic vdd pin ?
    a bit of c across the pot wiper to gnd won't hurt either


    Code:
    ' ****************************************************************
    ' PIC16F1825
    ' ****************************************************************
    ;#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
    ' ***************************************************************
    ' 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
    ' ***************************************************************
    #CONFIG
       __config _CONFIG1, _FOSC_INTOSC & _WDTE_ON & _PWRTE_ON & _MCLRE_ON & _CP_OFF & _CPD_OFF
       __config _CONFIG2, _PLLEN_OFF & _STVREN_ON & _BORV_LO & _LVP_OFF
    #ENDCONFIG
    ' ***************************************************************
    ' Initialization
    ' ***************************************************************
    OSCCON    = %01111000       ; 16MHz internal osc
    pause 100
    APFCON0.2 = 0               ; Tx on RC4 for LCD display
    APFCON0.7 = 0               ; Rx on RC5
    ' 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
    ' *****************************************************************
    ANSELC    = 0               ; Digital only for all PortC pins
    TRISC     = 0               ; Make all PORTC pins output
    ANSELA    = %00001000        ; Analog on PORTA.4(AN3) only
    ADCON1    = %10100000        ; Right-justified results in 10-bits; Fosc/32 as timer;
                                 ; VREF is connected to VDD
    TRISA     = %111110      ' Make all pins output except for RA1 (trim pot input)
    FVRCON    = 0               ; Fixed Voltage Reference is disabled
    ;  ADCON0    = %00000101       ; ADC enabled on AN1 (RA1) only; ADC conversion enabled
    PAUSEUS 20                  ; wait for the analog switch 'glitch' to die down
    ADCON1    = %10010000       ; Right-justified results in 10-bits; Fosc/8 as timer
    #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
    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
     
    #IFDEF USE_LCD_FOR_DEBUG
        HSEROUT [LCD_INST, LCD_CLR]
        pause 5
        HSEROUT ["ADCInVal=",DEC ADCInVal,"  "]
        pause 500
    #ENDIF
    
     lata.0=1
     pause 2000
     serout2 PORTA.0,84, ["ready",13,10 ] 
                                                              
    Main:
        gosub Do_ADC
        pause 100
        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
            
            #IFDEF USE_LCD_FOR_DEBUG
                HSEROUT [LCD_INST, LCD_CLR]
                pause 5
                HSEROUT ["new ADCInVal", LCD_INST, LCD_L2, DEC ADCInVal, "  "]
            #ENDIF
            
            
        endif
     
    GOTO Main
    Do_ADC:
        ADCON0    = %00001101 ' Select Channel 3, Turn-On A/D
        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
        
         serout2 PORTA.0,84, ["adc ",#ADCInVal,13,10 ]
        
    return
    Last edited by richard; - 19th February 2016 at 01:01. Reason: typo

Similar Threads

  1. Replies: 4
    Last Post: - 27th January 2015, 16:34
  2. Replies: 4
    Last Post: - 30th May 2012, 09:28
  3. Converting 10bit ADC result to 8 bit
    By jmgelba in forum mel PIC BASIC Pro
    Replies: 9
    Last Post: - 5th March 2012, 21:38
  4. strange A2D 5V scaling result - 16F819
    By Max Power in forum mel PIC BASIC Pro
    Replies: 3
    Last Post: - 8th April 2010, 03:28
  5. Scaling ADC values
    By purkolator in forum mel PIC BASIC Pro
    Replies: 4
    Last Post: - 29th November 2007, 06: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