A to D on the PIC16F687


Closed Thread
Results 1 to 16 of 16
  1. #1
    Join Date
    May 2006
    Posts
    36

    Default A to D on the PIC16F687

    Hello, I am trying to just make a demo program so I can view the Ato D value on my LCD. I am not having good luck. I looked at another post that discussed problems with A to D on the 16F876. I was using this as a guide but something is not right.

    I am trying to read a pot on RA4/AN3. I am reading a value but as I adjust my pot the numbers do not count up in a linear fashion. It will count from 0 to 1 to 2 for 7/8 of the single turn pot and then the numbers jump to 255 very quickly. This is linear pot and I should be gettng a linear increase or decrease.

    Here is my code and the settings that I believe are relavant. The code is supposed to read the voltage from the pot and update a LCD to tell me the output. Thanks for any help.
    ----------------------------------------
    AD_AN3 VAR PORTA.4
    AD_AN3_VALUE VAR byte
    DEFINE ADC_BITS 8 ' set number of bits in result
    DEFINE ADC_CLOCK 3 ' set clock source
    DEFINE ADC_SAMPLEUS 50 ' set sampling time for microseconds

    MENU:
    LCDOUT $FE, 1 ' Clear LCD screen
    A_D_AN3:
    ADCON0 = %00001101
    PAUSEUS 50 ' wait 50 microsec
    ' ADCON0.2 = 1 'start conversion(bit 2= 1)
    ' WHILE ADCON0.2 = 1
    ' WEND ' wait for conversion
    ADCIN 3, AD_AN3_VALUE ' read channel 3 to AD_AN3_VALUE
    LCDOUT $FE, 1 ' Clear LCD screen
    LCDOUT "A to D Value"
    LCDOUT $FE, $C0, #AD_AN3_VALUE
    PAUSe 100
    BUTTON FUNCTION_BUTTON, 1, 255, 0, C2, 1, ON_TIME_FUNC
    GOTO A_D_AN3

  2. #2
    Join Date
    Apr 2006
    Location
    Michigan
    Posts
    70


    Did you find this post helpful? Yes | No

    Default

    where to begin. First you need to make port a an input. Second there are two AD registers 1 and 2. Third I would put the register setup before your main program. you only need to do it once. Try this.

    DEFINE ADC_BITS 8 ' set number of bits in result
    DEFINE ADC_CLOCK 3 ' set clock source
    DEFINE ADC_SAMPLEUS 50 ' set sampling time for microseconds
    ADCON0 = %10000000 'I think this formats the result
    ADCON1 = %00000000 'I think this defines if ports are A or D. The first 0 may need to be a 1
    trisa = %11111111 'Port A is input
    AD_AN3 VAR PORTA.4
    AD_AN3_VALUE VAR byte

    pause 500 'LCD's need to initialise before sending data
    LCDOUT $FE, 1 ' Clear LCD screen

    A_D_AN3:
    PAUSEUS 50 ' wait 50 microsec
    ADCIN 3, AD_AN3_VALUE ' read channel 3 to AD_AN3_VALUE
    LCDOUT $FE, 1 ' Clear LCD screen
    LCDOUT "A to D Value"
    LCDOUT $FE, $C0, #AD_AN3_VALUE
    PAUSe 100
    BUTTON FUNCTION_BUTTON, 1, 255, 0, C2, 1, ON_TIME_FUNC
    GOTO A_D_AN3

    If it still doesn't work its all about setting the bits in ADCON0 and 1 correctly. See the datasheet

  3. #3
    Join Date
    Sep 2004
    Location
    montreal, canada
    Posts
    6,898


    Did you find this post helpful? Yes | No

    Default

    be sure your pot impedance meet the maximum impedance stated in the datasheet too.

    ADCON1.7=1 ' Right justified results..

    Also depending of your OSC speed, you may need to increase your sampling time, and you may want to add a tiny 0.01-0.1 uF capacitor at the PIC input to smooth the results.
    Last edited by mister_e; - 1st July 2006 at 09:33.
    Steve

    It's not a bug, it's a random feature.
    There's no problem, only learning opportunities.

  4. #4
    Join Date
    Apr 2006
    Location
    Michigan
    Posts
    70


    Did you find this post helpful? Yes | No

    Default

    I just realized a mistake I told you. You may want to move your LCD off of port A since you are using that for your A to D. I don't know if it will work after making in input and analog. The book tells how to change it.

  5. #5
    Join Date
    Jun 2005
    Location
    Mumbai,India
    Posts
    43


    Did you find this post helpful? Yes | No

    Exclamation Is it ADC or POT

    Hi,
    have U checked with multimeter that U are getting proper voltage on
    wiper of POT? Unless that is confirmed then no use of banging head like
    Mister_E on program and PIC. ;-)
    It is possible that pot has mechanical problems at ground end and
    after wiper moves few turns the ground end opens and U get full voltage
    on wiper!!
    As U are getting upto say number 10 then this is a probability.

  6. #6
    Join Date
    May 2004
    Location
    NW France
    Posts
    3,615


    Did you find this post helpful? Yes | No

    Default Missing ...

    4 Errors found before compiling : ( between star lines ...)



    DEFINE ADC_BITS 8 ' set number of bits in result
    DEFINE ADC_CLOCK 3 ' set clock source
    DEFINE ADC_SAMPLEUS 50 ' set sampling time for microseconds
    ADCON0 = %10000000 'I think this formats the result
    ADCON1 = %00000000 'I think this defines if ports are A or D. The first 0 may need to be a 1
    trisa = %11111111 'Port A is input
    AD_AN3 VAR PORTA.4
    '************************************************* *********************
    FUNCTION_BUTTON VAR PORTB.X ' TO BE DECLARED AS YOUR REQUIREMENTS !!!
    '************************************************* ********************
    AD_AN3_VALUE VAR byte
    '************************************************* *********************
    C2 VAR Byte 'TO BE DECLARED "
    '************************************************* *********************
    pause 500 'LCD's need to initialise before sending data
    LCDOUT $FE, 1 ' Clear LCD screen

    A_D_AN3:
    PAUSEUS 50 ' wait 50 microsec
    ADCIN 3, AD_AN3_VALUE ' read channel 3 to AD_AN3_VALUE
    LCDOUT $FE, 1 ' Clear LCD screen
    LCDOUT "A to D Value"
    LCDOUT $FE, $C0, #AD_AN3_VALUE
    PAUSe 100
    '************************************************* ********************
    C2 = 0 ' TO BE INITIALISED HERE !!!
    '************************************************* ********************
    BUTTON FUNCTION_BUTTON, 1, 255, 0, C2, 1, ON_TIME_FUNC
    GOTO A_D_AN3

    '************************************************* ********************
    ON_TIME_FUNC: ' TO BE SOMEWHERE to be called !!!

    ' What is it supposed to do ???????????????????
    '************************************************* *********************

    END




    NOW still hardware mix ... We continue : your LCD is "standard connected" ... so you MUST pass its RS pin to PORTB ( see defines list) to get RA4 free, as you want it an analog input. You also must declare ALL other PORTA pins as DIGITAL ( see ADCON bytes)

    Sorry, I did not verify if defaults LCD connexions are the same for F687 or F84 ... but there's no reason for a difference in the pin names !!!


    Now ... we will know if real ADC problems still exist ...

    Alain
    Last edited by Acetronics2; - 2nd July 2006 at 16:46.
    ************************************************** ***********************
    Why insist on using 32 Bits when you're not even able to deal with the first 8 ones ??? ehhhhhh ...
    ************************************************** ***********************
    IF there is the word "Problem" in your question ...
    certainly the answer is " RTFM " or " RTFDataSheet " !!!
    *****************************************

  7. #7
    Join Date
    May 2006
    Posts
    36


    Did you find this post helpful? Yes | No

    Default

    I should have stated that I have no problems with getting the LCD to work. I wanted to post only the information that I felt was relative to the what I was trying to accomplish. I also have decided to go about programming the PIC the way I wanted and have deviated from setup in the manual. I do not understand what it is saying that I need to setup all of PortA as inputs. Why would I want to do that if I only wanted to do an A to D on one channel? I want to do A to D on AN3, or PortA.4.

    I have worked with A to D in the past on this model (PIC16F687) and had no problems with programming in Assembly. I am new to PICBASIC and am just tryign to figure out how it functions.

    I decided to take a look at the pot with a voltmeter and see if I could make sense of what was happening. I read the voltage and it stays low and then jumps to 5V. Once the pot is disconnected from the PIC, the voltage range is linear from 0 to 5V. I must have something configured wrong with the A to D. I will check it out and see what I can find. The pot is a 10K which is what I have used in the past. I will update once I figure it out or repost with more questions.

  8. #8
    Join Date
    May 2004
    Location
    NW France
    Posts
    3,615


    Did you find this post helpful? Yes | No

    Unhappy Still Hadware problem ...

    As I told you ...

    the default settings of the LCD USE Porta.4 ... and make it AUTOMATICALLY an OUTPUT to drive the RS LCD pin.
    So, you MUST free up Porta.4 and then re-assign RS Drive.

    YES, your LCD will work ... but not the ADC input !!!

    so, otherwise you had not told us everything, or the Pic ref is not 687, you have your pot wiper AND the RS pin tied together ... not that good.

    No use to set ALL Porta to input : the LCDout statement will make the to-LCD pins as outputs, each time LCDout command is used.

    But, I think a little scheme of yours could really help !!! ... cause you're not so explicit ...

    Alain
    ************************************************** ***********************
    Why insist on using 32 Bits when you're not even able to deal with the first 8 ones ??? ehhhhhh ...
    ************************************************** ***********************
    IF there is the word "Problem" in your question ...
    certainly the answer is " RTFM " or " RTFDataSheet " !!!
    *****************************************

  9. #9
    Join Date
    May 2006
    Posts
    36


    Did you find this post helpful? Yes | No

    Default

    Ok, I don't understand why and I hope someone can enlighten me. All I did was change all of my pins on the PortA to inputs. Previously TRISA =%00001000 - my program did not work. I changed TRISA = %0011111 and then the A to D function works fine and my LCD displays a linear value from 0 to 255 for as I turn my pot. I can also read the voltage on the pin and it is linear.

    I checked my code and I think must have just had the wrong pin selected as an input. I changed TRISA to TRISA = %00010000 and everything works fine now. Thanks to all of those that posted.

    Now that I have gotten that the A to D to work, I have switched to a 10 bit result to get greater resolution.
    Does anyone have suggestions as to how to make change the value that I am displaying from 0 to 1024 into a voltage? I guess it would be to take 5 and divided by 1024, so 5/1024 = 0.00488 and use this to multiply the result to come up with a voltage. So say the voltage is 3.5, I would need a reading of 716 multiplied by 0.488 to come up with 3.5V.

    Does anyone have a better idea than this to use to display the voltage from a pot? Thanks.

  10. #10
    Join Date
    May 2006
    Posts
    36


    Did you find this post helpful? Yes | No

    Default

    Well I did some experimenting and here is what I found and it seems to work.

    I created a new variable. AD_AN3_VALUE
    I am taking the A to D value and changing into a value which gives me an idea as to what voltage I am putting into the pin. The only thing that I am not sure about is to make it display the value with a decimal point. My LCD just displays 1635 for a voltage which is 1.635VDC.

    ADCIN 3, AD_AN3_VALUE ' read channel 3 to AD_AN3_VALUE
    AD_AN3_Volt = AD_AN3_VALUE * (5 //1023)
    LCDOUT $FE, 1 ' Clear LCD screen
    LCDOUT "A to D Value"
    LCDOUT $FE, $C0, #AD_AN3_Volt, "VDC"

    Does anyone have a better idea how to display the voltage? My code seems to be growing quite large and I am not doing a lot of different operations. The PIC16F687 has a memory size of 2048 and it says I am using 884 words to accomplish what I am doing. All that I am doing is making a demo program that allows me to scroll through a menu and change the variables up and and down and then I am going to work on sending them to another micro that will store the variables in its EEPROM.

    I know there are ways to minimize the size of my code but I have only been working with PICBASIC for about a week and trying to think of ways that like assembly but better suited for PICBASIC.

  11. #11
    Join Date
    May 2004
    Location
    NW France
    Posts
    3,615


    Did you find this post helpful? Yes | No

    Default

    Hehe ... good !!!

    Just think PbP works with integers ... so multiply the result by 5 and only after that, divide by 1024 !

    to enhance precision ... you could multiply by 50 ... and keep the 1/10 th !!!

    could also use the DIV 32 function :

    if your ref voltage was, say 4.955v ... instead of 5.000 ... you could multiply by the real ref voltage in millivolts and , as soon as, divide by 1024 ( see DIV32 chapter for that ) to get maximum precision ...
    a small comma shift will do the rest !!! ( see DIG function ... I remember threads about that on the Forum = a little search !!! )

    but remember pot linearity is not so good ( very linear pots exist ... special price too !!! ) ... so position or angle to voltage won't be very accurate !!!

    Alain
    Last edited by Acetronics2; - 3rd July 2006 at 15:43.
    ************************************************** ***********************
    Why insist on using 32 Bits when you're not even able to deal with the first 8 ones ??? ehhhhhh ...
    ************************************************** ***********************
    IF there is the word "Problem" in your question ...
    certainly the answer is " RTFM " or " RTFDataSheet " !!!
    *****************************************

  12. #12
    Join Date
    May 2006
    Posts
    36


    Did you find this post helpful? Yes | No

    Default

    All that I am doing with the pot is dmeonstrating that can read an input voltage on a pin. I have a project where I will have to be reading a voltage that will be coming from another input and I just wanted to verify this with a pot. Do you have any suggestions how to convert 1635 to 1.635 ? I can just shift it because if I had 735 that would be equal to 0.735 and wouldn't want to look at it as 7.35.
    Thanks
    Josh

  13. #13
    Join Date
    May 2004
    Location
    NW France
    Posts
    3,615


    Did you find this post helpful? Yes | No

    Wink Rtfm

    You could also open the manual ...

    Section 4.17.2 ( page 33 ) ...

    as a miracle, the example is just that you should use ...

    ON your LCD , just place the comma between W1 and W2 of the example !!! Should I say W0 is supposed to be the result of the DIV32 operation ???

    Alain
    Last edited by Acetronics2; - 4th July 2006 at 08:54.
    ************************************************** ***********************
    Why insist on using 32 Bits when you're not even able to deal with the first 8 ones ??? ehhhhhh ...
    ************************************************** ***********************
    IF there is the word "Problem" in your question ...
    certainly the answer is " RTFM " or " RTFDataSheet " !!!
    *****************************************

  14. #14
    Join Date
    May 2006
    Posts
    36


    Did you find this post helpful? Yes | No

    Default

    This somewhat works but I need to work through a way that it will display the value, 2.004 instead of 2.4 because the way I did it is with W0 = 5*AD_Value (AD_Value could be 0 to 1023). Then I did:
    AD_VALUE_HIGH = W0 / 1023
    AD_VALUE_LOW = W0 / 1023

    THEN LCDOUT, $FE, $C0, #AD_VALUE_HIGH, ".",#AD_VALUE_LOW, "VDC"

    I am not sure what you meant by using the DIV32 command. Can you please explain more? Thanks.

    Josh
    Last edited by jblackann; - 5th July 2006 at 14:48.

  15. #15
    Join Date
    Jun 2005
    Location
    Mumbai,India
    Posts
    43


    Did you find this post helpful? Yes | No

    Wink DIV32 Is this place on moon or timbaktoo?

    Hey ! all the time I thought I was most dumbo person for Basic espeacilly for
    pretty type.
    Now Im relieved that there is atleast one more and may be many thousands!
    I hope Josh takes some troubles with searching on forum.
    I don't have experience with PIC or other Basic but in assembly there is
    DIV32 routine - sort of macro - for dividing 32bit version.
    wish U best!

  16. #16
    Join Date
    May 2004
    Location
    NW France
    Posts
    3,615


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by jblackann

    I am not sure what you meant by using the DIV32 command. Can you please explain more? Thanks.

    Josh
    That's a simple function of PbP :

    PBp does internally the 16x16 multiplication ...

    then the result is internally stored into 2 separate WORDS ...but you can't ( normally !!! ) access them nor make another thing without tearing them !!!

    A function was implemented, DIV32, that can divide those 2x16 bits by another 16 bits max value

    so, first, you do the mult.:
    WWRes = W1*W2
    and the very next line MUST be
    Wres = DIV32 W3

    This realizes the Word1*Word2/Word3 operation, despite PbP do not work with more than 16 bits !!!

    Just need to use for WWRes an already declared WORD.

    For details see $ 4.17.8 page 35 ...

    Alain
    ************************************************** ***********************
    Why insist on using 32 Bits when you're not even able to deal with the first 8 ones ??? ehhhhhh ...
    ************************************************** ***********************
    IF there is the word "Problem" in your question ...
    certainly the answer is " RTFM " or " RTFDataSheet " !!!
    *****************************************

Similar Threads

  1. LCD with PIC16F687
    By jblackann in forum mel PIC BASIC Pro
    Replies: 5
    Last Post: - 26th June 2006, 23:16
  2. PIC16F687 - supported?
    By badcock in forum mel PIC BASIC Pro
    Replies: 2
    Last Post: - 6th August 2005, 10:33

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