+ Reply to Thread
Results 1 to 17 of 17
  1. #1

    Default help setting up 16F886 for ADC

    I'm trying to use adcin to read two different pots to get 8 bit results and I'm having trouble. I'm using the internal oscillator (there is no external oscillator). The pots are connected to AN0 and AN1

    ' Define ADCIN parameters ********************************
    Define ADC_BITS 8 ' Set number of bits in result
    Define ADC_SAMPLEUS 50 ' Set sampling time in uS
    'Define ADC_CLOCK 3 ' This define is inoperative on 16F88x
    ADCON0 = %11000000 ' Set ADC_CLOCK to RC (DEFINE ACD_CLOCK inoperative on the 16F88x)
    ADCON1 = %00000000 ' Left-Justify result in ADRESH:ADRESL registers
    ANSEL = %00000011 ' Set AN0, AN1 to analog, others digital
    ANSELH = %00000000 ' Set AN8 and higher channels to digital operation
    '************************************************* *********

    I just copied the code from the LAB-X1 "adcin3x" sample program for the 16F887. I figured it would work the same for the 16F886 since it's basically a 28 pin version of the 16F887, but it doesn't seem to be working. I figured the problem was that the LAB-X1 uses a 4MHz external oscillator, but I've tried different setting on ADCON0 and it doesn't seem to change anything.
    Last edited by keithv; - 11th July 2016 at 20:40.

  2. #2

    Default Re: help setting up 16F886 for ADC

    I think that the code "adcin3x" is for the old pic16F877, not a pic16f887. The adc in the newer chips have more registers. I have found the adcin command does not always work. So I use a manual set and read routine. Below is an example for 10bit, I think the 8bit result will be in the ADC_AN0.HIGHBYTE when the adc is set to left shift?

    Code:
    ADC_AN0 var WORD '10bit result 
    ADC_AN1 var WORD '10bit result
    
    'Read AN0
    '--------------------------------------------------------------------------
    ADCON0 = %11000011   'Set adc channel = AN0
    
    WHILE ADCON0.1 = 1  'WAIT FOR CONVERSION
    
        WEND
         ADC_AN0.HIGHBYTE = ADRESH
         ADC_AN0.LOWBYTE  = ADRESL
    
    'Read AN1
    '--------------------------------------------------------------------------
    
    ADCON0 = %11000111   'Set adc channel = AN1
    
    While ADCON0.1 = 1  'WAIT FOR CONVERSION
    
         WEND
    
    
         ADC_AN1.HIGHBYTE = ADRESH
         ADC_AN1.LOWBYTE  = ADRESL
    '---------------------------------------------------------------------------
    Last edited by mark_s; - 11th July 2016 at 23:35.

  3. #3
    Join Date
    Jan 2014
    Posts
    78

    Default Re: help setting up 16F886 for ADC

    Hi to all,

    I have troubles with reading 10 bit on AN0 , too .
    Can somebody give me some ideas, please ?

    Code:
    '****************************************************************
    '*  Name    : UNTITLED.BAS                                      *
    '*  Author  : [select VIEW...EDITOR OPTIONS]                    *
    '*  Notice  : Copyright (c) 2014 [select VIEW...EDITOR OPTIONS] *
    '*          : All Rights Reserved                               *
    '*  Date    : 10/2/2018                                          *
    '*  Version : 1.0                                               *
    '*  Notes   :                                                   *
    '*          :                                                   *
    '****************************************************************
    'PIC16F886
       #config
       __CONFIG    _CONFIG1, _LVP_OFF & _FCMEN_OFF & _IESO_OFF & _BOR_OFF & _CPD_OFF & _CP_ON & _MCLRE_OFF & _PWRTE_ON & _WDT_OFF & _INTRC_OSC_NOCLKOUT 
       __CONFIG    _CONFIG2, _WRT_OFF & _BOR21V
       #endconfig
        
    define osc 4
    include "lcd886.bas"
    CM1CON0 = 0 			'Comparator Off
    CM2CON0 = 0 			'Comparator Off
       	
    Define ADC_BITS 10 		'Set number of bits in result (10)
    Define ADC_CLOCK 3 		'Set clock source (3=rc)
    Define ADC_SAMPLEUS 50 	'Set sampling time in microseconds (50us)
    
    TRISA = %00000001       'Set PORTA.0 as input
    TRISB = %00000000       'Set PORTB as outputs
    TRISC = %00000000       'Set PORTC as outputs
    
    ANSEL  = %00000001      'Set PORTA.0 as analog
    ANSELH = %00000000      'The rest ports are digital
    'ADCON0 = %11000011      'Set adc channel = AN0
    'ADCON1 = %10000000  'SETUP ADC RIGHT JUSTIFY SET REFV to VDD & VSS		        
    	
    PORTA = 0
    PORTB = 0
    PORTC = 0
    
    light  var PORTA.3
    tc     var word
    
    '--------light is ON and initialize the LCD ---------
    pause  300
    high   light
    gosub  lcdrst
    lcdout $fe, $80,"TEST"
    gosub  lcdrst
    
    '---------------------PROGRAM------------------------
    MAIN:
    ADCON0 = %11000011
    gosub read_tc
    
    lcdout $fe, $80, #tc
    pause 200
    goto main
    end
    
    '---------------------Read AN0------------------------
    read_tc:
    WHILE ADCON0.1 = 1:WEND  'WAIT FOR CONVERSION
         tc.HIGHBYTE = ADRESH
         tc.LOWBYTE  = ADRESL
    return
    '--------------------lcd reset------------------------
    lcdrst:
    lcdout, $fe, 1
    pause 10
    return

  4. #4
    Join Date
    Nov 2003
    Location
    Greece
    Posts
    2,691

    Default Re: help setting up 16F886 for ADC

    Is it on a F886?

    You MUST NOT set the GO/DONE bit at the same time you enable the ADC converter (Data Sheet page 106, Note in the box).

    Also you do not setup the ADCON1. It is commented.

    Try this:

    Code:
            '****************************************************************
            '*  Name    : UNTITLED.BAS                                      *
            '*  Author  : [select VIEW...EDITOR OPTIONS]                    *
            '*  Notice  : Copyright (c) 2014 [select VIEW...EDITOR OPTIONS] *
            '*          : All Rights Reserved                               *
            '*  Date    : 10/2/2018                                          *
            '*  Version : 1.0                                               *
            '*  Notes   :                                                   *
            '*          :                                                   *
            '****************************************************************
            'PIC16F886
               #config
               __CONFIG    _CONFIG1, _LVP_OFF & _FCMEN_OFF & _IESO_OFF & _BOR_OFF & _CPD_OFF & _CP_ON & _MCLRE_OFF & _PWRTE_ON & _WDT_OFF & _INTRC_OSC_NOCLKOUT 
               __CONFIG    _CONFIG2, _WRT_OFF & _BOR21V
               #endconfig
                
            define osc 4
            include "lcd886.bas"
            CM1CON0 = 0 			'Comparator Off
            CM2CON0 = 0 			'Comparator Off
               	
            Define ADC_BITS 10 		'Set number of bits in result (10)
            Define ADC_CLOCK 3 		'Set clock source (3=rc)
            Define ADC_SAMPLEUS 50 	'Set sampling time in microseconds (50us)
    
            TRISA = %00000001       'Set PORTA.0 as input
            TRISB = %00000000       'Set PORTB as outputs
            TRISC = %00000000       'Set PORTC as outputs
    
            ANSEL  = %00000001      'Set PORTA.0 as analog
            ANSELH = %00000000      'The rest ports are digital
            ADCON0 = %11000001      'Set adc channel = AN0
            ADCON1 = %10000000  'SETUP ADC RIGHT JUSTIFY SET REFV to VDD & VSS		        
            	
            PORTA = 0
            PORTB = 0
            PORTC = 0
    
            light  var PORTA.3
            tc     var word
    
            '--------light is ON and initialize the LCD ---------
            pause  300
            high   light
            gosub  lcdrst
            lcdout $fe, $80,"TEST"
            gosub  lcdrst
    
            '---------------------PROGRAM------------------------
            MAIN:
            ADCON0.1=1
            gosub read_tc
    
            lcdout $fe, $80, #tc,"       " ' I put some space here when you go from large result to 1 digit result.
            pause 200
            goto main
            end
    
            '---------------------Read AN0------------------------
            read_tc:
            WHILE ADCON0.1 = 1:WEND  'WAIT FOR CONVERSION
                 tc.HIGHBYTE = ADRESH
                 tc.LOWBYTE  = ADRESL
            return
            '--------------------lcd reset------------------------
            lcdrst:
            lcdout, $fe, 1
            pause 10
            return
    Ioannis

  5. #5
    Join Date
    Jan 2014
    Posts
    78

    Default Re: help setting up 16F886 for ADC

    Thank you for your fast reply !

    I tried your version, but don't work. The readed adc values oscilating from 10x to 22x.....

  6. #6
    Join Date
    Jan 2014
    Posts
    78

    Default Re: help setting up 16F886 for ADC

    Now I readed the some value on AN2 with succes, but AN0 is the same.

  7. #7
    Join Date
    Nov 2003
    Location
    Greece
    Posts
    2,691

    Default Re: help setting up 16F886 for ADC

    If you read on AN2 then we are getting somewhere.

    Did you remember to change the channel to 0 after testing on AN2?

    Does AN0 work on ADCIN 0,tc ?

    Ioannis

  8. #8
    Join Date
    Jan 2014
    Posts
    78

    Default Re: help setting up 16F886 for ADC

    Thank you Ioannis for your effort ! .. you spend a time for me. The problem is solved, I don't understand what happened really.

    So, on AN0 I had a TC1047 ( analog temperature sensor ) with a 100nF capacitor to ground. The voltage measured on AN0 was 726 mV , also I verified with a osciloscop and I had a "clean" voltage. After I removed the capacitor, AN0 work well .
    Attached Images Attached Images  

  9. #9
    Join Date
    Nov 2003
    Location
    Greece
    Posts
    2,691

    Default Re: help setting up 16F886 for ADC

    this may lead you to these two things:

    1. Your cap is shorted, or

    2. if you use breadboard, it is faulty.

    Ioannis

  10. #10
    Join Date
    Jan 2014
    Posts
    78

    Default Re: help setting 10 bit for ADC and conversion

    I work on proffesional PCB, I changed the capacitor, but the same problem. So, nevermind, without 100nF capacitance the AN0 is ok. Anyway is strange whats what happen there.

    On AN0 I read the voltage from a linear sensor temperature (TC1047). The temperature slope is fixed at 10 mV/C and the output voltage at 0C is 500 mV (according with page4 from datasheet).
    My ideea to extract the C isn't ok because the maximum reading read on the input is 1024 ((1024-500) / 10 = 52.4 degrees) and the number of read bits is read in step 5, so only 256 bits.

    The problem with me is that I do not read correctly the milivolts on 10 bit. Any ideea is apreciated, thank you !

    Code:
            '---------------------PROGRAM------------------------
            MAIN:
            gosub read_tc               'read analog value
            gosub calc_voltage          'calculate the mVolts
            gosub conv_temp             'conversion to degrees
            
            lcdout $fe, $80, #tc        'displat TC and mVolt only for info
            lcdout $fe, $C0, #mvolt , "   Temp= " , #grd
            pause 100
            
            goto main
            end
    
            '---------------------Read AN0------------------------
            read_tc:
            z=0
            for i = 1 to 100  ' average to 100 reads
                ADCON0.1=1
                WHILE ADCON0.1 = 1:pause1:WEND  'WAIT FOR CONVERSION
                 tc.HIGHBYTE = ADRESH
                 tc.LOWBYTE  = ADRESL
                 z = tc + z
            next i
            tc = z/100
            return
            '--------------------Calc Voltage----------------------
            calc_voltage:
                mvolt   = (tc * 5//1024)
            return
            '-------------------Convert Temp----------------------
            conv_temp:
            grd = (mvolt - 500)/10     'readed mVolt value - 500 (according with TC1047 datasheet)
             lcdout $fe, $C0+4, " Temp= " , #grd
            return
            '--------------------lcd reset------------------------
            lcdrst:
            lcdout, $fe, 1
            pause 10
            return
    21498D.pdf

  11. #11
    Join Date
    May 2013
    Location
    australia
    Posts
    1,344

    Default Re: help setting up 16F886 for ADC

    mvolt = (tc * 5//1024)
    really

    try

    mvolt = (tc * 5/1024)
    This is more entertaining than Free to Air TV

  12. #12
    Join Date
    May 2013
    Location
    australia
    Posts
    1,344

    Default Re: help setting up 16F886 for ADC

    also 100 iterations of this has every chance of overflowing a word var
    z = tc + z
    ie 100*921 = 92100 , word max val 65535



    every count of tc = 5000/1024 mv


    40 deg = 4500 mv would be a 921 count


    the most accurate calc for pbp

    would be mvolt = tc */ 1249

    result for 921 = 4493



    ps I assume ADFM set correctly
    This is more entertaining than Free to Air TV

  13. #13
    Join Date
    Jan 2014
    Posts
    78

    Default Re: help setting up 16F886 for ADC

    Thank you very much Richard !

    Now I see that 100 iterations overflowing a word var, so I'll use 10 iteration or DT Average routine, but nevermind right now.

    I know it's unpleasant to ask beginners an advanced but you can explain me how its made middle 16 bits of multiplication calculation, please ? ( mvolt = tc */ 1249 )

    Also I'm confused about "40 deg = 4500 mv would be a 921 count" , the maximum scale what I need is 1750 mV, 40 deg = 900mv ( 40 deg = 400mV + 500mV = 900mV) .

    Please do not mind that I ask so many aberrations, but for me there are things I could not understand ...I'm old man and also beginner in programming.

  14. #14
    Join Date
    May 2013
    Location
    australia
    Posts
    1,344

    Default Re: help setting up 16F886 for ADC

    Also I'm confused about "40 deg = 4500 mv would be a 921 count" , the maximum scale what I need is 1750 mV, 40 deg = 900mv ( 40 deg = 400mV + 500mV = 900mV)
    I must have up past my bedtime , managed to multiply 40 * 10 mv and got 4000


    (
    Code:
      mvolt = tc */ 1249  )
    @5v vcc each adc count is 4.88 mV
    4.88*256=1249
    pbp divides/multiplies have internal 32 bit results there are various commands the allow convenient
    access to this result in useful ways

    @40 deg tc would be about 184 counts


    so our calc is (184*4.88*256)/256
    since pbp can't do real numbers

    we do the 4.88*256 =1249

    and 184*/1249 does the rest ie 184*1249/256
    This is more entertaining than Free to Air TV

  15. #15
    Join Date
    Jan 2014
    Posts
    78

    Default Re: help setting up 16F886 for ADC

    Now its clear for me.

    Thank you very much for your patience and explanation !!

  16. #16
    Join Date
    May 2013
    Location
    australia
    Posts
    1,344

    Default Re: help setting up 16F886 for ADC

    This is more entertaining than Free to Air TV

  17. #17
    Join Date
    Jan 2014
    Posts
    78

    Default Re: help setting up 16F886 for ADC

    Sometimes I read this topic but when I needed it I did not find it ...I dug after him a few hours, so thousands thanks to all for help !

Similar Threads

  1. 16f886
    By Larry in forum mel PIC BASIC Pro
    Replies: 4
    Last Post: - 4th November 2008, 16:57
  2. 16f886
    By hvacrtech in forum mel PIC BASIC Pro
    Replies: 12
    Last Post: - 27th May 2008, 05:06
  3. Setting Address via ADC
    By breesy in forum mel PIC BASIC Pro
    Replies: 2
    Last Post: - 14th October 2007, 14:33
  4. Setting up ADC....
    By robertmark68 in forum General
    Replies: 1
    Last Post: - 11th August 2006, 18:08
  5. Setting Up Adc Ports
    By GEEZER in forum mel PIC BASIC Pro
    Replies: 4
    Last Post: - 22nd August 2005, 03:04

Members who have read this thread : 20

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