A/d 16f88


Closed Thread
Results 1 to 6 of 6

Thread: A/d 16f88

  1. #1
    Join Date
    May 2009
    Posts
    7

    Default A/d 16f88

    Hi, I am very new to all of this, hope someone can set me straight. I started a project with a 16F628 and was goin OK but decided I needed to read a battery voltage and swapped to a 16F88. To test the A/D conversion I used the following code.
    I am using PBP V2.45 but have just ordered upgrade.

    INCLUDE "modedefs.bas" ' Include serial modes

    ' port A used for LCD
    Define LCD_DREG PORTA ' RA0 to RA3 is data pin for LCD
    Define LCD_DBIT 0
    Define LCD_RSREG PORTA ' RA6
    Define LCD_RSBIT 6
    Define LCD_EREG PORTA ' RA4
    Define LCD_EBIT 4
    Define LCD_BITS 4
    DEFINE OSC 4
    'define A/D setup
    Define ADC_BITS 8
    define ADC_SAMPLEUS 100

    @ DEVICE pic16F88, INTRC_OSC_NOCLKOUT ' system clock options

    Ai var PORTB.6 'input to chanel 6 A/D
    bat var word 'battery voltage off load
    bat1 var word 'battery voltage on load
    led var PORTB.0 'speaker/led output

    OSCCON = %01101110 'internal clock, is primary clk @ 4 Mhz
    CMCON =7 ' Comparator off
    TRISA = 0 ' Port A all outputs
    TRISB = %11111110 'Port B all inputs 0
    ANSEL = %01100000 'all digital except chanel 5&6 which are inputs (analog)
    ADCON0 = %00101001 'Frc internal clock, chanel 5 is A/D (RB6/AN5)
    ADCON1 = %01000000 'left justify,divide clk by 2, Vref is VDD and VSS

    low led 'turn off led
    ' Allow time for LCD startup
    pause 2000

    start:
    LCDOut $FE,1 ' Clear LCD screen
    LCDOut "Goto Bat_Volts" ' See where we are
    pause 1000
    'test that we loop
    toggle led
    pause 250
    toggle led
    pause 250
    'Start program ***************************************8
    goto Bat_Volts
    'check battery off load
    Bat_Volts:
    LCDOut $FE,1 ' Clear LCD screen
    LCDOut "ADCON0 = "
    LCDOut $FE,$C0
    lcdout #ADCON0 'Display ADCON0
    pause 2000
    LCDOut $FE,1 ' Clear LCD screen
    LCDOut "Before ADC" 'Check where we are
    pause 1000
    ADCIN Ai, bat 'read A/D chanel 6 and store value to bat
    while ADCON0.1=1:WEND ' Check to make sure ADC conversion finished..
    LCDOut $FE,1 ' Clear LCD screen
    LCDOut "After ADC" 'Check where we are
    pause 1000
    LCDOut $FE,1 ' Clear LCD screen
    LCDOut "ADCON0 = "
    LCDOut $FE,$C0
    lcdout #ADCON0 'Display ADCON0
    pause 2000
    LCDOut $FE,1 ' Clear LCD screen
    LCDOut "Battery = ",#bat ' Display Voltage
    LCDOut $FE,$C0
    lcdout "Volts"
    pause 2000
    goto start

    end 'End of program

    When I run it I only read 255 whether inputing VDD or VSS, and ADCON0 is 41 before the ADCIN command and 193 after.
    Have been thru the data sheet and thought I had all registers set up correctly but maybe not.
    This is a lot of fun but I don't get much sleep these days.Thanks for any help.
    Steve

  2. #2
    Join Date
    Aug 2006
    Location
    SWITZERLAND (french speaking)
    Posts
    891


    Did you find this post helpful? Yes | No

    Default

    Hi Steve,

    Don't use a VAR to define the A/D channel. Use the channel's number instead:
    Code:
    ADCIN 5, bat
    You can test your project with your code I trimmed to minimum:
    Code:
    INCLUDE "modedefs.bas"
    
    Define LCD_DREG PORTA
    Define LCD_DBIT 0
    Define LCD_RSREG PORTA
    Define LCD_RSBIT 6
    Define LCD_EREG PORTA
    Define LCD_EBIT 4
    Define LCD_BITS 4
    
    bat  var byte
    
    OSCCON = %01100000
    ANSEL  = %00100000
    
    Bat_Volts:
       ADCIN 5, bat
       LCDOut $FE, 1, "Battery = ",DEC bat, "V"
       PAUSE 2000
       goto Bat_Volts:
    end
    BTW, PORTB.6 is ADC Channel 5
    <img src="http://www.picbasic.co.uk/forum/attachment.php?attachmentid=3431&stc=1&d=124367750 7">
    Attached Images Attached Images  
    Roger

  3. #3
    Join Date
    Sep 2007
    Location
    USA, CA
    Posts
    271


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by flotulopex View Post
    Don't use a VAR to define the A/D channel. Use the channel's number instead:
    Code:
    ADCIN 5, bat
    I strongly disagree with this. First, in this particular example, he's using Ai as a constant, not a changing variable. That allows you to change PICs (or PIC pins), and just change the setup constant, without searching for all of the references to the pin.

    Second, there is nothing wrong with using a variable variable to read adcin.

    What you did do wrong, however, is you referenced the AN# with a PORT#. You don't do that. You should only use the ANx number; in this case, assuming your comments are your target, 6, NOT Portb.7.

    Correct:
    adcin 6, bat
    NOT Correct:
    adcin portb.7, bat

    Correct:
    Ai var 6 'Notice we use "x" of ANx.
    adcin Ai, bat

    NOT Correct:
    Ai var portb.7 'Do NOT use the Port pin the ANx is on.
    adcin Ai, bat

  4. #4
    Join Date
    Aug 2006
    Location
    SWITZERLAND (french speaking)
    Posts
    891


    Did you find this post helpful? Yes | No

    Default Use CON or VAR

    hum...
    Correct:
    Ai var 6 'Notice we use "x" of ANx.
    adcin Ai, bat
    Doesn't work for me.

    It will work like this:
    Code:
    Ai CON 6
    ADCIN Ai, bat
    ... or:
    Code:
    Ai VAR BYTE
    Ai = 6
    ADCIN Ai, bat
    Or do I miss something?

    NB: addressing PORTs via variable/constant is a best practice not a must.
    Last edited by flotulopex; - 30th May 2009 at 15:57.
    Roger

  5. #5
    Join Date
    Sep 2007
    Location
    USA, CA
    Posts
    271


    Did you find this post helpful? Yes | No

    Default

    Yes, you are right... in my haste I edited it incorrectly.

    I believe using a number is the worst way to do it, because it has no description behind it.

    A constant is just as tight as far as compiling goes, and a variable is the way to go if you need to change which port you are reading within the loop. Both of these have the advantage that you can change all of your constants up at their definitions on the top, and you can change them easily when you move things around, like to a different PIC or pin. Also, compare these two, which do the exact same thing:

    adcin 6
    vs.
    adcin BatteryVoltagePin

    Which is easier to understand? Obviously the second. And if you use three a/d ports, with the constants all defined in a row and then you need to move things, it's one edit at the top for each... no searching and replacing multiple lines.

  6. #6
    Join Date
    May 2009
    Posts
    7


    Did you find this post helpful? Yes | No

    Default A/d 16f88

    Thanks to you both. Roger your code works fine. I'll read thru your comments and revisit the data sheet for a better grasp of it all.

Similar Threads

  1. 12f675 A/d Miseries
    By MARAD75 in forum mel PIC BASIC Pro
    Replies: 13
    Last Post: - 16th December 2008, 02:16
  2. 12F675 A/D and GPIO sleep interrupt
    By macinug in forum mel PIC BASIC Pro
    Replies: 10
    Last Post: - 8th September 2008, 14:39
  3. Need advice on A/D
    By james in forum mel PIC BASIC Pro
    Replies: 9
    Last Post: - 24th August 2007, 19:30
  4. A/D converter fails?
    By egberttheone in forum mel PIC BASIC Pro
    Replies: 14
    Last Post: - 13th February 2006, 18:57
  5. 18F2525 A/D, Comparator and Vref modules
    By fbraun in forum mel PIC BASIC Pro
    Replies: 2
    Last Post: - 20th May 2005, 23:17

Members who have read this thread : 1

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