Strange ADC behaviour


Closed Thread
Results 1 to 29 of 29
  1. #1

    Default Strange ADC behaviour

    Hi guys,

    i've made a simple circuit to measure the ad value from 2 channel of my 16F88 pic out to a LCD.

    The strange thing is that porta.1 's values are conditioned by the results in porta.0 !

    For example... this is what i get on my LCD...


    Porta.1 = 5.00v lcd = 5.0
    porta.0 = 5.00v lcd = 5.0

    Porta.1 = 0.17v lcd = 0.17
    Porta.0 = 5.00v lcd = 4.17

    porta.1 = 2.54v lcd = 2.54
    porta.0 = 5.00v lcd = 4.54

    porta.1 = 5.00v lcd = 5.00
    porta.0 = 4.58v lcd = 5.00

    Here's the code:

    output portb.7
    low portb.7

    Define osc 4

    ' Define LCD pins
    Define LCD_DREG PORTB
    Define LCD_DBIT 0
    Define LCD_RSREG PORTB
    Define LCD_RSBIT 4
    Define LCD_EREG PORTB
    Define LCD_EBIT 5
    Define LCD_BITS 4

    'variables
    va1 var word
    va2 var word
    temp var word
    volt var word

    pause 200 'init LCD
    lcdout $fe,1 'clear LCD

    'Define ADCIN parameters
    Define ADC_BITS 10 ' Set number of bits in result ( 8 or 10 bits )
    Define ADC_CLOCK 3 ' Set clock source (3=rc)
    Define ADC_SAMPLEUS 50 ' Set sampling time in uS

    input porta.0
    input porta.1

    ADCON1 = %10000011 ' set porta analog and right justify result

    loop:

    ADCIN 0, va1
    ADCIN 1, va2

    temp = (va1 */ 500 ) >> 2
    volt = (va2 */500) >>2

    high portb.7

    lcdout $fe,2,"VOLTAGE..",dec (volt/100),",",dec2 volt,"V"
    lcdout $fe,$c0,"TEMP.....",dec (temp/100),",",dec2 volt,"V"

    pause 250

    Goto loop

    End

    Thanks

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


    Did you find this post helpful? Yes | No

    Default

    In theory the comparator should already be off at POR, but for safety sake, add this line at the top of your code

    CMCON=7

    This kind of weirdness is usually caused by a too high external analog impedance, AND/OR a too short sampling time, or combination of. Make sure your external source is bellow the maximum recommended (<10K if my memory serves me well for this device).

    You could still add some PAUSE/PAUSEUS between each ADCIN to see if it's better or worst.

    I'll suggest to properly set the ANSEL register and set to digital all unused i/o as well.

    BUT the main problem is in red
    Code:
    lcdout $fe,2,"VOLTAGE..",dec (volt/100),",",dec2 volt,"V"
    lcdout $fe,$c0,"TEMP.....",dec (temp/100),",",dec2 volt,"V"
    have a look at DIG modifier as well.
    Steve

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

  3. #3


    Did you find this post helpful? Yes | No

    Default

    Thanks mister_e

    I guess i need glasses on this one...

    lcdout $fe,2,"VOLTAGE..",dec (volt/100),",",dec2 volt,"V"
    lcdout $fe,$c0,"TEMP.....",dec (temp/100),",",dec2 volt,"V"

    Corrected that but still some strange behaviour...

    With
    porta.1 = 0.16v lcd 0.16 and porta.0=5v lcd 5

    but

    with porta.1 = 0.16v AND porta.0 = 0.16v lcd 0.00v on both

    I'm guessing some comparator issue here...

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


    Did you find this post helpful? Yes | No

    Default

    ah come on let's see what happen if i put some explanation 'round.

    Code:
    lcdout $fe,2,"VOLTAGE..",dec (volt/100),",",dec2 volt,"V"
    GOOD! you want to display voltage, that's what you do in both DEC and DEC2 modifier.

    NOW

    Code:
    lcdout $fe,$c0,"TEMP.....",dec (temp/100),",",dec2 volt,"V"
    '
    '
    '
    Why are you mixing temp AND VOLT......?
    Last edited by mister_e; - 7th December 2007 at 19:52.
    Steve

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

  5. #5


    Did you find this post helpful? Yes | No

    Default

    Let me correct my last statement:

    Having 2 LM35 on my breadboard

    Porta.1 working fine either each one

    Porta.0 showing 0.00 when conected to any one of them

    Tryed a pot to get a lower voltage ( 0.16v ) like the LM35 but with the pot is working !!!
    Also getting good readings from other like pulldown resistor or 5v supply !

    Same code for both though

    added :

    pauseus 500 between each adc reading,

    also

    CMCON=7 on top of code

    Any ideas ?

  6. #6


    Did you find this post helpful? Yes | No

    Default

    sorry Mister-e...

    You did not undestand my post

    i was just quoting your statement...i did corrected that

    this is how it is:

    lcdout $fe,2,"VOLTAGE..",dec (volt/100),",",dec2 volt,"V"
    lcdout $fe,$c0,"TEMP.....",dec (temp/100),",",dec2 temp,"C"



    .

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


    Did you find this post helpful? Yes | No

    Default

    EDIT: let me see...
    Steve

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

  8. #8


    Did you find this post helpful? Yes | No

    Default

    i get

    voltage = 2.49
    temp = 1.25

    .

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


    Did you find this post helpful? Yes | No

    Default

    mmm, must be too drunk and blind now..
    what if you add
    Code:
    ansel=3
    trisa=3
    at the top of your code?

    what if you forget the decimal point but use
    Code:
    lcdout $fe,2,"VOLTAGE..",dec volt," V"
    lcdout $fe,$c0,"TEMP.....",dec temp," C"
    instead?
    Last edited by mister_e; - 7th December 2007 at 20:23.
    Steve

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

  10. #10
    skimask's Avatar
    skimask Guest


    Did you find this post helpful? Yes | No

    Default

    Code:
    lcdout $fe,2,"VOLTAGE..",dec volt," V"
    lcdout $fe,$c0,"TEMP.....",dec temp," C"
    [/QUOTE]

    Shouldn't that be dec (volt/100) and dec (volt // 100) above?

  11. #11


    Did you find this post helpful? Yes | No

    Default

    Thanks for the help

    The code is correct like Mister-e posted because the reading values are 0.xx and with the /100 i would have just 0 !

    Changed everything but i still get

    porta.1 = 17
    and
    porta.0 = 0

    changing each other i still get the same on lcd

    .

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


    Did you find this post helpful? Yes | No

    Default

    out of curiosity, which version of PBP are you using? i've never ever used ADCIN in my program since over 5-6 years.

    I may bet on some averaging... but i hate to bet on friday
    Steve

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

  13. #13


    Did you find this post helpful? Yes | No

    Default

    My version is 2.47

    But i will try a 2nd pic now and see...

    .

  14. #14


    Did you find this post helpful? Yes | No

    Default

    Tryed a 2nd pic but same result...

    it's not a pic failure

    .

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


    Did you find this post helpful? Yes | No

    Default

    How better/worst it is if you dump the appended .HEX file in your PIC... don't change anything in the config fuses.. use it AS-IS
    Attached Files Attached Files
    Steve

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

  16. #16


    Did you find this post helpful? Yes | No

    Default

    I just changed the MCLR off to on ( i was affraid i could get my pic locked ).

    But it worked and both ports are 0.15V ... meaning...are reading both LM35

    EDIT:
    The first line of the LCD is not steady...i mean...i get VOLTAGE..0.15V and dLTAGE..0.15V ( blinking some times )
    .
    Last edited by ruijc; - 7th December 2007 at 22:20.

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


    Did you find this post helpful? Yes | No

    Default

    After the Line2 command, I found that I often had to add a space ahead the text, or the first character would get dropped. Some LCD's are too slow to change lines and display immediately. Apparently you need a delay, since it's effecting more than one character.

  18. #18


    Did you find this post helpful? Yes | No

    Default

    I still get behaviour no matter what i change...


    except with Mister-e's code that works OK

    Is it just a pbp version issue or is it something else ?

    If it's a version problem...is there a way to get arround it ?

    .

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


    Did you find this post helpful? Yes | No

    Wink Success ...

    Hi, Ruijc

    I just re-wrote your code ... works fine ( I'm only talking of the PIC point of view - do not talk about precision ...)

    Try to write carefully ( and readably) ALL your config sequence ( I know ... ~ 50 lines ! )... and it will work !!!

    Just a tip:

    instead of :

    " temp = (va1*/500)>> 2 "

    try :

    " temp = val*125
    temp = temp.highbyte "

    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 " !!!
    *****************************************

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


    Did you find this post helpful? Yes | No

    Default

    Mine did some averaging, not much. Read the sensor couple of time (10-16 times) then calculate the average of it, go to next channel, do the same, show the results.

    I did it the 'bad' way
    Code:
            for loopw = 0 to 15
                ADCIN 0, TEMPW
                VA1=VA1 + (TEMPW>>4)
                NEXT
                
            pause 500
            
            FOR LOOPW=0 TO 15
                ADCIN 1, TEMPW
                VA2=VA2 + (TEMPW>>4)
                NEXT
    lost of precision and so on, now for something better, have a look at Darrel's routine.

    Averaging 16 bit values without using 32 bit math?
    http://www.pbpgroup.com/modules/wfse...hp?articleid=7
    Last edited by mister_e; - 9th December 2007 at 17:29.
    Steve

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

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


    Did you find this post helpful? Yes | No

    Post

    Quote Originally Posted by mister_e View Post

    lost of precision and so on, now for something better, have a look at Darrel's routine.
    Hi, Steve

    for precision ... measuring 150 or 200 mV on a 5 v full scale is a nonsense ...
    we already had this discussion here with ruijc ...

    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 " !!!
    *****************************************

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


    Did you find this post helpful? Yes | No

    Default

    Yup i agree, an external Vref or op-amp should be used.
    Steve

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

  23. #23


    Did you find this post helpful? Yes | No

    Default

    Hi guys

    thanks for all the help.

    Mister-e...you mentioned an external Vref.

    I have a 12v power down to 5v for this circuit.

    Can i use 12v as reference ? How can i do this ?

    I'm a bit confused...can i plug it directly to my 16F88 ?

    .

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


    Did you find this post helpful? Yes | No

    Default

    NO NO NO DON'T DO IT

    Vref have to be lower than Vdd. Let's see you have a sensor who produce you a max of 1 volt. Then you select a Vref of ~1 Volt, then your ADC give you the full 10 bit conversion scale between 0-Vref. This is the use of it.

    But yeah.. check out for the minimum Vref requirement...
    Last edited by mister_e; - 10th December 2007 at 17:51.
    Steve

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

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


    Did you find this post helpful? Yes | No

    Post

    Quote Originally Posted by mister_e View Post
    NO NO NO DON'T DO IT

    Vref have to be lower than Vdd. Let's see you have a sensor who produce you a max of 1 volt. Then you select a Vref of ~1 Volt, then your ADC give you the full 10 bit conversion scale between 0-Vref. This is the use of it.
    Hi, Steve

    a LM 385 or 385-1.2 will make a nice ( and cheap ! ...) 1.235 v reference here ...

    BUT, do not forget the higher the signal ... the smaller the noise ! ( and last digit flickering ! ) ...
    so, here, the sensor choice is " not so good" ... If I understood (?) , our friend wants to read ambiant temp ... 150-250 mv levels !


    ( note an OPA will amplify noise + signal ... "not so good" solution too ...)

    Alain
    Last edited by Acetronics2; - 10th December 2007 at 18:03.
    ************************************************** ***********************
    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 " !!!
    *****************************************

  26. #26


    Did you find this post helpful? Yes | No

    Default

    Hello Alain,

    the purpose of this circuit is first to learn
    Then it will be for reading temperatures between 20 and 130ºC.

    The forum mentioned the LM335 as the best choice but this one does not reach above 100ºC.

    I had the LM35 and the LM135 ( which does accept temps higher than 100ºC ) on my list.

    The problem is than my local store does not have the LM135 so i'm kinda stuck with this one !

    I will retry to write the code with your tip :

    " temp = val*125
    temp = temp.highbyte "


    .

  27. #27
    Join Date
    Mar 2006
    Location
    Pennsylvania, USA.
    Posts
    130


    Did you find this post helpful? Yes | No

    Default

    You might also try a little pause between reading adc channels, to make certain that the internal capacitor has fully discharged between readings. Someone else just had a similar problem last week, it's posted on this forum.

    Jerry.
    If your oscilloscope costs more than your car...

  28. #28


    Did you find this post helpful? Yes | No

    Default

    Hi guys,

    some changes made but still Porta.0 is running the show

    If i change the input on porta.0 it changes my "fixed" reading on porta.1

    What i did :

    Turned on the Vref+ and with a voltage drop through resistors i managed to get 1.6V vref in porta.3 and added this in my code:
    ADCON1 = %10100011

    Also added a pauseus between readings
    pauseus 1000

    placed on LCD the original adc reading followed by the math result
    lcdout $fe,2, dec tes1, " PA1 ", dec volt, " "
    lcdout $fe,$c0,dec te0," PA0 ", dec temp, " "

    Acetronics,

    you said that you re-wrote my code and it worked...

    One question:

    Have you made any changes ?

    I dont know where to turn now

    .

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


    Did you find this post helpful? Yes | No

    Wink

    Quote Originally Posted by ruijc View Post

    Acetronics,

    you said that you re-wrote my code and it worked...

    One question:

    Have you made any changes ?

    .
    Hi, Ruijc

    I did not make any noticeable change to your " functionnal " program ( = the part that runs )

    BUT ... as I told you, The config section took me ~ 50 lines.

    Here is your headache : The processor config lines !!!

    Code:
    '*****************************************************************************
    '*****************************************************************************
    '09/12/2007
    '
    'Lecture de 2 temp avec LM35 ( ambiant  temp ... LOL ! )
    '
    'PIC 16F88 @ 4Mhz
    
    '*****************************************************************************
    'Config
    
    @	__CONFIG    _CONFIG1, _CP_OFF & _CCP1_RB3 & _DEBUG_OFF & _WRT_PROTECT_OFF & _CPD_OFF & _LVP_OFF & _BODEN_OFF & _MCLR_ON & _PWRTE_ON & _WDT_ON & _INTRC_IO
    
    @ 	__CONFIG    _CONFIG2, _IESO_OFF & _FCMEN_OFF
    
    OSCCON 	= %01101110 'Internal RC w/ I/Os
    
    INTCON	= 0
    PIE1	= 0
    PIE2	= 0
    CMCON	= 7
    CVRCON 	= 0
    
            
    '*****************************************************************************
    'DEFINEs
    '*****************************************************************************
    
    'OSC
    
    DEFINE osc 4
    
    '*****************************************************************************
    '
    'ADC
    
    DEFINE ADC_BITS 10 ' Set number of bits in result ( 8 or 10 bits )
    
    'DEFINE ADC_CLOCK 3 ' Set clock source (3=rc)
    
    DEFINE ADC_SAMPLEUS 50 ' Set sampling time in uS
    
    '*****************************************************************************
    '
    'LCD 
    
    DEFINE LCD_DREG PORTB
    DEFINE LCD_DBIT 0
    DEFINE LCD_RSREG PORTB
    DEFINE LCD_RSBIT 4
    DEFINE LCD_EREG PORTB
    DEFINE LCD_EBIT 5
    DEFINE LCD_BITS 4
    
    DEFINE LCD_COMMANDUS 2000
    
    '*****************************************************************************
    'ADC parameters
    
    ADCON0	= %11000000 ' clock source
    ADCON1 	= %10000011 ' set porta.0 and .1 analog and right justify result
    ANSEL 	= %00000011 ' Porta.0 and  .1 used by ADC
    
    '*****************************************************************************
    ' variables
    
    va1 	var word
    va2 	var word
    temp 	var word
    volt 	var word
    
    LM351 	con 0
    LM352	con 1
    
    CLEAR
    
    '*****************************************************************************
    'I/O's
    
    PORTA = %00000000
    PORTB = %00000000
    
    TRISA = %00000011
    TRISB = %00000000
    
    '*****************************************************************************
    'PINS
    
    LM35_1	var PORTA.0 
    LM35_2	var PORTA.1 
    a2		var PORTA.2 
    a3		var PORTA.3 
    a4		var PORTA.4 
    MCLR	var PORTA.5 
    a6		var PORTA.6 
    a7		var PORTA.7 
    
    DATA1	var PORTB.0
    DATA2	var PORTB.1
    DATA3	var PORTB.2
    DATA4	var PORTB.3
    
    R_S		var PORTB.4
    E		var PORTB.5
    b6		var PORTB.6
    LED		var PORTB.7
    
    
    '*****************************************************************************
    '*****************************************************************************
    '
    '*****************************************************************************
    'Init LCD
    
    pause 500 'init LCD
    lcdout $fe,1 'clear LCD
    
    
    loop:
    
    ADCIN LM351, va1 ' 15 °C ... 150 /5000*1024 = 30.72 ... 30 = NOT GOOD !!!
    ADCIN LM352, va2
    
    'temp = (va1 */ 500 ) >> 2
    temp = (va1*125)
    temp = temp.Highbyte
    
    'volt = (va2 */500) >> 2
    volt = (va2*125)
    volt = volt.Highbyte
    
    high portb.7
    
    lcdout $fe,2,"VOLTAGE..",dec (volt/100),".",dec2 volt,"V"
    lcdout $fe,$c0,"TEMP.....",dec (temp/100),".",dec2 volt,"V"
    
    pause 250 
    
    Goto loop
    
    End
    as you can see it ....no great change to what you did ...


    IT IS FORBIDDEN TO YOU TO PASTE THAT CODE ... before having understood YOU MUST CONFIGURE the registers and ports by YOURSELF !!!

    PbP cares for some ... yes, but only some "general use" ones.

    Also try to show a "readable" listing where you ( mostly ! ) and others can find if you've programmed the "good" registers or not ...

    And for the end ... remember to separate the "config zone" and the "working zone" ... setting registers in the "working zone" must be kept ONLY if changes have to be made while running ...


    Here we are ... PbP doesn't do everything for you ...that's it

    Especially read those F...manual and Datasheet !!!


    Keep on ... thinking you're good at pics ... you'll become really good one day !!!

    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. Strange Behaviour - Simple code+DT_INT+16F676
    By financecatalyst in forum mel PIC BASIC Pro
    Replies: 10
    Last Post: - 17th February 2010, 18:53
  2. Strange behaviour of my PBP code.
    By Fredrick in forum mel PIC BASIC Pro
    Replies: 7
    Last Post: - 24th August 2009, 20:20
  3. Strange Serout Behaviour
    By bluesmoke in forum mel PIC BASIC Pro
    Replies: 2
    Last Post: - 12th August 2009, 04:12
  4. Strange behaviour from PIC16F877 on TMR0
    By mikebar in forum mel PIC BASIC Pro
    Replies: 18
    Last Post: - 19th August 2006, 01:31
  5. strange int behaviour
    By tom in forum mel PIC BASIC Pro
    Replies: 4
    Last Post: - 17th November 2005, 15:41

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