ADCIN & 16F870 - how to avoid non linear conversion?


Closed Thread
Results 1 to 13 of 13
  1. #1
    Join Date
    Feb 2013
    Posts
    1,122

    Default ADCIN & 16F870 - how to avoid non linear conversion?

    Hello.

    I've built a simple circuit, with 16F870 and MAX6126 as reference voltage supply.

    The problem is that I can't write a code that will properly convert read data into voltage.

    By using external multimeter, I've determined that with 678 read by ADC, voltage is 3 volts. Based on this, I've created a conversion formula, but it does not appears to work correctly, for example, when input is 4.1v, it reads as 4.35 volts. And when input is 1.4V, it reads as 1V. The code is as follows (based on :

    Code:
    Include "modedefs.bas"  ' Include serial modes
       TRISA = %11111111       ' Set PORTA to all input
       ADCON1 = %10000001      ' Set PORTA analog and right justify result
    
    DEFINE LCD_DREG PORTB
    DEFINE LCD_DBIT 4
    DEFINE LCD_RSREG PORTB
    DEFINE LCD_RSBIT 0
    DEFINE LCD_EREG PORTB
    DEFINE LCD_EBIT 1
    DEFINE LCD_BITS 4 
    DEFINE LCD_LINES 2
    DEFINE LCD_COMMANDUS 1500
    DEFINE LCD_DATAUS 44
    DEFINE OSC 4
    
    Define  ADC_BITS     10    ' Set number of bits in result
    Define  ADC_CLOCK    3     ' Set clock source (3=rc)
    Define  ADC_SAMPLEUS 50    ' Set sampling time in uS
    
    adval Var word             ' Create adval to store result 
    droebiti var word 'temporal value
    
    mainloox:
       ADCIN 0, adval          ' Read channel 0 to adval
       droebiti=adval*44 'convert to volts
       
       Lcdout $fe,$c0, "Value: ", DEC adval, "    "  ' Display the decimal value 
       Lcdout $fe,$80, "Voltage: ",  DEC (droebiti / 10000), ".", DEC4 droebiti, " V " 
       Pause 100               ' Wait .1 second
    Goto mainloox           ' Do it forever
    What I'm doing wrong?

    I'm using 10k pot with middle pin tied to RA0, one pin tied to Vss and another to voltage reference output. This might be the issue?

  2. #2
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,604


    Did you find this post helpful? Yes | No

    Default Re: ADCIN & 16F870 - how to avoid non linear conversion?

    Hi,
    The MAX6126 comes in various versions but I suspect you're using the 5V one, since you're feeding in voltages above 4.096V I'm guessing you're using the 5V version of the MAX6126 - is that correct?

    Your numbers don't quite add up.... With a VRef of 5V an input of 3V should give you a reading of (1024/5) * 3 = 614, you're getting 678. Have you followed the datasheet for the voltage reference regarding supply and output bypassing and have you verified that the VRef voltage actually IS what you expect it to be?

    /Henrik.

  3. #3


    Did you find this post helpful? Yes | No

    Default Re: ADCIN & 16F870 - how to avoid non linear conversion?

    You have ADCON1 set to use porta.3 as an input for a positive reference. Without a reference connected its floating

    Change ADCON1 to this
    Code:
     
    ADCON1 = %10000000
    then your references will be +Vref = vdd and -Vref = vss. Or you can connect porta.3 to +5v without changing adcon1

  4. #4
    Join Date
    Feb 2013
    Posts
    1,122


    Did you find this post helpful? Yes | No

    Default Re: ADCIN & 16F870 - how to avoid non linear conversion?

    I'm using MAX6126 with output voltage of 4.098v and it outputs that voltage - verified with precision multimeter.
    The +Vref is tied to MAX6126 output and +Vref is tied to GND. So this is why I have ADCON1=%10000001
    When I tie RA0 directly to MAX6126 output, the raw output reads 1023, when I connect it to GND, it reads 0.

  5. #5
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,604


    Did you find this post helpful? Yes | No

    Default Re: ADCIN & 16F870 - how to avoid non linear conversion?

    Hi,
    OK, that's a great value because then each bit in the ADC result equals exactly 4mV but your numbers still doesn't add up....

    If you input exactly 3V you should get a value of 750 +/- a couple of bits - not 678 as you're apparently getting.

    Have you checked the VRef voltage with a scope? Perhaps it oscillates or have a lot of noise?

    What if you replace the 10k pot with a 1k pot, and put a 10nF capacitor between the ADC input and GND. Or, what if you increas the sampling time? (I'll admit, I don't really have this sampling time and Tad stuff clear in my head at the moment, need to do a little reading)

    Once you get a correct ADC result for the voltage you're feeding it you can increase the resolution by oversampling. If you take 40 samples, add them together and divide the result by 10 you have a value reading in mV (well, almost - there's 4mV "missing" at the top).
    Code:
    adval = 0
    For i = 0 to 39
      ADCIN 0, adval
      Voltage = Voltage + adval
      PAUSEUS 100
    NEXT
    
    LCDOUT $FE, 1, DEC Voltage/10000, ".", DEC3 Voltage // 10000
    /Henrik.

  6. #6
    Join Date
    Feb 2013
    Posts
    1,122


    Did you find this post helpful? Yes | No

    Default Re: ADCIN & 16F870 - how to avoid non linear conversion?

    Ok I've double checked wiring and so on. When getting 1023, I was connecting the upper end of pot to +5V, not to MAX output. Now, when I connected it to MAX output, it reads 987, instead of 1023, so I assume, there might be some more register settings required?

  7. #7
    Join Date
    Feb 2013
    Posts
    1,122


    Did you find this post helpful? Yes | No

    Default Re: ADCIN & 16F870 - how to avoid non linear conversion?

    Code:
    Vin	Raw	Delta
    
    0.1	10
    0.5	88	78
    1	213	125
    1.5	335	122
    2	460	125
    2.5	580	120
    3	700	120
    3.5	807	107
    4	927	120
    4.1	960	33
    These are raw ADC reads according to different input voltage.

  8. #8
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,604


    Did you find this post helpful? Yes | No

    Default Re: ADCIN & 16F870 - how to avoid non linear conversion?

    Hi,
    First of all. With a VRef of 4.096 you can not input a voltage HIGHER than that, so the 4.1V (although very close) isn't a valid test. With that said something is seriously wrong - either with the code, the setup, or the hardware.

    And again, have you actually looked at the reference voltage AND at the input voltage with a scope to verify that they are clean? Simply measuring them with a voltmeter may not show the error.

    Instead of using the pot across the reference voltage, try using a low impedance source, ie a variable DC supply, to feed the ADC and put a 10nF capacitor from the PIC pin to GND to act as a noise filter. See if that makes it any better. Also, take a couple of readings and average them to further clean any noise.

    If the above doesn't help then try another channel on the ADC or try another PIC. It's possible, but not likely, that something got damaged when you overloaded the input.

    /Henrik.

  9. #9
    Join Date
    Feb 2013
    Posts
    1,122


    Did you find this post helpful? Yes | No

    Default Re: ADCIN & 16F870 - how to avoid non linear conversion?

    It is NOT 4.1V, it is 4.096v, I just wrote 4.1 to save space.

    Yes, looked with scope and precision (3 digits after decimal point) multimeter.

    Will try another channel and another pic, as well as another voltage supply.

  10. #10
    Join Date
    Feb 2013
    Posts
    1,122


    Did you find this post helpful? Yes | No

    Default Re: ADCIN & 16F870 - how to avoid non linear conversion?

    Set scope to 50mV resolution and AC input. Found an 120mv max noise pulses, with 3.35hz following frequency.

  11. #11
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,604


    Did you find this post helpful? Yes | No

    Default Re: ADCIN & 16F870 - how to avoid non linear conversion?

    Where?
    On the power rail, at the output of the voltage reference, at the ADC input or all of the above?

    If the noise is only present at the ADC input of the PIC then the problem is probably too high source impedance (that 10k pot you're using) and the 3.35Hz you're seeing is how often the ADC is sampling the input. Or is this with a low impedance source?

  12. #12
    Join Date
    Feb 2013
    Posts
    1,122


    Did you find this post helpful? Yes | No

    Default Re: ADCIN & 16F870 - how to avoid non linear conversion?

    Yes it was with 10k pot, measured at ADC input. no other tests so far.

    Actually, I went with ADC route because I was not able to make BH1750 light sensor to work with picbasic, and since I badly need light measurement, I've decided to do a circuit with photoresistor and ADC, but it appears to have it's own bunch of problems.

  13. #13
    Join Date
    Feb 2013
    Posts
    1,122


    Did you find this post helpful? Yes | No

    Default Re: ADCIN & 16F870 - how to avoid non linear conversion?

    Yes, these pulses were from ADC. If turn ADC off, pulses are gone.

    Problem is solved, but it was weird.

    Since PIC has two Vss pins, I was using one Vss for GND, and to other Vss pin I've tied LCD gnd pin. So current going trough the PIC was causing the troubles. After I've added jumper to feed Vss directly to LCD, problem had gone and linearity improved.

Similar Threads

  1. How can I avoid stack corruption
    By BrianT in forum mel PIC BASIC Pro
    Replies: 2
    Last Post: - 30th August 2013, 02:45
  2. linear data memory & large data arrays
    By ronsimpson in forum mel PIC BASIC Pro
    Replies: 0
    Last Post: - 27th June 2011, 23:21
  3. How to avoid DIV32 command?
    By pxidr84 in forum mel PIC BASIC Pro
    Replies: 9
    Last Post: - 16th May 2011, 06:11
  4. Help needed with 16F870 ADC
    By srob in forum mel PIC BASIC
    Replies: 1
    Last Post: - 10th May 2008, 13:14
  5. Linear to S Curve conversion
    By luminas in forum mel PIC BASIC Pro
    Replies: 20
    Last Post: - 22nd May 2007, 14:15

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