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

    Hi,

    You can try this idea. It will never go under 50% using 125 as a constant. Then divide your adcin by 2 this variable will be 0 to 127

    Duty = 125 + adcin/2
    Last edited by mark_s; - 25th October 2015 at 23:39.

  2. #2


    Did you find this post helpful? Yes | No

    Default Re: Scaling ADC Result to a Set Range

    Quote Originally Posted by mark_s View Post
    Hi,

    You can try this idea. It will never go under 50% using 125 as a constant. Then divide your adcin by 2 this variable will be 0 to 127

    Duty = 125 + adcin/2
    Thanks Mark. Did you choose 125 because it's half of the max duty value with the prescaler and PR2 I have above?

  3. #3


    Did you find this post helpful? Yes | No

    Default Re: Scaling ADC Result to a Set Range

    Yes, because you said you were using 8 bit pwm. You can change that to fit your needs.

  4. #4


    Did you find this post helpful? Yes | No

    Default Re: Scaling ADC Result to a Set Range

    On another note, I observed that with ADCIN the readings fluctuate quite a lot and I only want to change the motor speed if the value has 'really' changed (i.e. by me). I tried this code and while it yields a rock-solid value, it doesn't go to 0: the readings go from 1-255. Any ideas why?

    Code:
    ' PIC 16F1825 with a 10k pot attached to AN1 (the data sheet says this is the maximum impedance allowed)
    
    #DEFINE USE_LCD_FOR_DEBUG   ; comment out for non-debug use
    
    ' Vdd      -> pin 1         -> +5V   
    ' RC4/Tx   -> pin 6         -> EUSART transmit (LCD)
    ' RA1      -> pin 12        -> trim pot input
    ' Vss      -> pin 14        -> GND
       
    DEFINE OSC 16               ; Set oscillator 16Mhz
    
    DEFINE ADC_BITS      8      ; 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  = 0               ; Left-justified results in 8-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 BYTE      ; stores ADCIN result read from trim pot
                                                               
    Main:
        gosub Do_ADC
        pause 100
        #IFDEF USE_LCD_FOR_DEBUG
            ' DO SOMETHING HERE
            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
        ADCON0.1 = 1            ' Start conversion
        
        WHILE ADCON0.1          ' Wait for it to complete
        WEND
    
        ADCInVal = ADRESH
    return

  5. #5


    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.

  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
    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?

  7. #7


    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

  8. #8


    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.

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