Need advice on A/D


Closed Thread
Results 1 to 10 of 10
  1. #1
    Join Date
    Jul 2007
    Location
    Maryland, USA
    Posts
    15

    Default Need advice on A/D

    Hello,

    I am currently working on a project that consists of a Seconds Counter, 2 A/D inputs(1 for Temperature, 1 for monitoring battery voltage). The idea is to take the data and transmit via morse code. I have it all wired up to an 2x16 LCD display, and a piezo speaker until I can get everything running correctly. Currently using a PIC16F88 to test all of this, in the end I will be using a PIC12F675.

    flow should be as follows
    1)Read A/D
    2)Turn on Tx
    3)Send morsecode in this order: Counter, Temperature, Battery Voltage, and Identification
    4)Turn off for 15sec
    5)Repeat

    My problem is, I am not so sure my A/D is working correctly.. my temperature displayed stays at 77degrees F. the voltage input to the processor is 3.16v Im using an LM335z which is calibrated at 10mv/K..and I know its not 109degree's F. more like 73 F...

    I dont mean to come here and get all the answers, although I would love to get some constructive critizism. Not just about problem previously mentioned, but my coding in general..

    Thanks in advance,
    James



    Code is as follows:

    Code:
    'Define LCD connections
    '
    Define  LCD_DREG        PORTB        'LCD data bits on PORTB   
    Define  LCD_DBIT        0                'PORTB starting address
    Define  LCD_RSREG       PORTB        'LCD RS bit on PORTB
    Define  LCD_RSBIT       5               'LCD RS bit address
    Define  LCD_EREG        PORTB        'LCD E bit on PORTB
    Define  LCD_EBIT        4                'LCD E bit address
    Define  LCD_BITS        4                'LCD in 4-bit mode
    DEFINE  LCD_LINES       2               'LCD has 2 rows
        
    ' Define ADCIN parameters
    '
    Define OSC              8                   'Set oscillator at 8MHz
    Define ADC_BITS         8                 'Set number of bits in result
    Define ADC_CLOCK        3                'Set Clock source (3 = rc)
    DEFINE ADC_SAMPLEUS     50           'Set sampling time in uS
    CMCON = 7                                   'Turn comparators OFF
    
    '------( Variables )------
    '
    tx          var byte                     'Transmitter variable
    adval       var byte                    'A/D input for temperature
    adval2      var byte                    'A/D input for . . . .
    tempF       var byte                   'Result of A/D after temperature conversion
    counter     var byte                    'Time variable
    dit         var byte                       'for morse code "dot"
    dah         var byte                       'for morse code "dash"
    ditpause    var byte                     'for morse code pauses between letters/numbers
    wordpause   var byte                    'Pause between words
    i           var byte                          'Variable for subroutine
    dig1        var byte                        'Variable for subroutine
    dig2        var byte
    
    '------( Registers )------
    '             76543210
        TRISA  = %00000001                 'PortA.0 = input, all else = outputs
        TRISB  = %00000000                 'PortB = outputs
        OSCCON = %01110000               '
        ADCON0 = %01000001               'Make AN0 analog inputs, 
        ADCON1 = %00000000               'Format selection/divide clock                              
                                                     'Reference voltage = VDD
        ANSEL  = %00001001                'Sets all A/D off, except RA0 &
    
    '------( Initialization )------
    '
        
        dit       = 4                         'Length of dot in morse code(Lower number is Faster)
        dah       = dit * 3                 'Length of dash in morse code
        ditpause  = dit * 12              'Length of pause between dits & dahs in morse code
        wordpause = ditpause * 5      'Pause between letters/numbers
        counter   = 0                       'Clear time to 0
        Pause 18                             'Wait for LCD to initialize
        LCDOUT $FE, 2, "Loading..."     
    
    '------( Main Code )------
    '    
    Loop:    
        
        pause 1000
        tx = 1
    'PORTA.3 = 1  ' Tx ON
        counter = counter + 1            'Increment time
        
        ADCIN 0, adval                      'Read channel 0 - Temperature
        pause 20
        adcin 3, adval2                      'Read channel 3 - Battery Voltage
        tempf = adval / 10                 '
        Tempf = tempf - 273              '** Conversion from 10mV/K to Fahrenheit**
        TempF = Tempf * 9                '
        tempf = tempf / 5                  '
        tempf = tempf + 32                '      
        
        LCDout $FE, 1
        LCDOUT $FE, 2,$14,$14,$14,$14,$14,$14,$14,$14,$14, "A=", #adval2
        LCDOUT $FE, 2, "Cnt=", #counter                             
        Lcdout $FE, $C0, "F=", #tempf,$14,$14,$14,"ID:N3PX"
    
    '------( Subroutine )------                           
    '
    for i = 2 to 0  step -1              '
        dig1 = counter dig i             'Subroutine to send out :Time
        gosub outdigit                    '
    next i                               
         
    pause 1000                           'Pause before sending next reading
    
    for i = 2 to 0 step -1               '
        dig1 = tempf dig i               'Subroutine to send out :Temperature 
        gosub outdigit                    '
    next i                              
              
    pause 1000                           'Pause before sending next reading
    
    for i = 2 to 0 step -1               '
        dig1 = adval2 dig i              'Subroutine to send out :Battery Monitor
        gosub outdigit                    '
    next i                               
    
    Pause 1000                           'Pause before sending Callsign
    
        gosub a                           '
        gosub num3                     'Subroutine to send out :Callsign
        gosub b                           '
        gosub c                           '
    
      tx = 0           
    'PORTA.3 = 0 'Tx off
       
    Pause 2000                      'Pause before recycling        
    
    goto loop
    
    outdigit:
    
    
    Branchl dig1, [num0,num1,num2,num3,num4,num5,num6,num7,num8,num9]
    Last edited by james; - 15th August 2007 at 17:13.

  2. #2
    Join Date
    Jul 2007
    Location
    Maryland, USA
    Posts
    15


    Did you find this post helpful? Yes | No

    Default Correct way

    Whats the corect way for posting code in the nice window?

    I thought it was code: then /code ?

  3. #3
    Join Date
    Feb 2003
    Posts
    432


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by james View Post
    Whats the corect way for posting code in the nice window?

    I thought it was code: then /code ?
    Code:
    It is but you need the square brackets [ code ] code here [ /code ]
    
    (no space inside the brackets!)
    Keith

    www.diyha.co.uk
    www.kat5.tv

  4. #4
    Join Date
    Jul 2007
    Location
    Maryland, USA
    Posts
    15


    Did you find this post helpful? Yes | No

    Default Shed some Light

    I still cannot come up with a solution as to whats wrong with the A/D converter. I've used Mister E's "PicMultiCalc" to make sure my clock/bits and sampleus are defined correctly, though it was not the ticket. . . Any idea's?

    Another thing I'd like to learn how to fix : The seconds counter gets way behind, due to the output of morse code taking time. I've rigged up a way to compensate for the lost time by adding in counter = counter + 3, throughout my subroutines... but feel this isnt the correct way of keeping my seconds counter on track. I'd like to have the counter as accurate as possible.

    any light shed is greatly appreciated.

    James

  5. #5
    Join Date
    Mar 2005
    Location
    Mandalay,Myanmar
    Posts
    9


    Did you find this post helpful? Yes | No

    Default 10 bits not 8 bits

    Hi,
    12F675 A/D converter output is 10 bits wide data.
    adval and adval2 should assign as word.
    Please take care about ansel and adcon settting.
    from_myanmar

  6. #6
    Join Date
    Jul 2007
    Location
    Maryland, USA
    Posts
    15


    Did you find this post helpful? Yes | No

    Default Still having problems

    majid,

    Define ADC_BITS 8 'Set number of bits in result

    This should take care of changing the result from 10bits to 8bits, and would eliminate the need for setting adval/adval2 as a WORD. Correct?

    I have looked over the ansel and adcon register numerous times, and still I can find no problem with A/D.

  7. #7
    Join Date
    Nov 2003
    Location
    Wellton, U.S.A.
    Posts
    5,924


    Did you find this post helpful? Yes | No

    Default

    Being that you are using ADCIN, VDD as a reference and 8 bit resolution, You do not need to set all of the ADCON0,ADCON1 and so on, PBP does that for you. The default DEFINES are fine for what you are doing so you do not need to put them in your code either.

    This is all you need to read the ADC, All the other stuff is available it you need to change the defaults.

    Code:
    tempF VAR WORD     'or BYTE  What ever the conversion needs
    ANSEL=%00000001   'AN0 Input
    CMCON=7
    
    R_ADC:          'Read ADC Loop
    ADCIN 0, tempF
    LCDOUT $FE,1,#tempF
    PAUSE 100
    GOTO R_ADC
    Last edited by mackrackit; - 22nd August 2007 at 23:57. Reason: Spelling
    Dave
    Always wear safety glasses while programming.

  8. #8
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default

    I think you've got several problems going on here.

    First, is the 3.16V output from the device when it's "not 109°F".
    Until you resolve the hardware issue, it will never work in software.

    Next, while the A/D resolution is 8-bits, and adval doesn't need to be a WORD, the variable used to convert it to Fahrenheit (Ftemp) DOES need to be a WORD.

    Also, by using 8-bit A/D, it limits the resolution of the final reading to +/- 3.5°F (horrible).
    If you use 10-bit A/D it reduces that to about +/- 0.8°F (better).

    Now the formula,
    > The LM335 is calibrated as 10mv/°K.
    So you have to convert the A/D reading to a voltage before you can convert it to a temperature.
    And the math needs to be done differently to avoid overflows and to handle negative values.
    Code:
    DEFINE ADC_BITS 10
    
    adval  VAR WORD
    TempF  VAR WORD
    Sign   VAR BIT
    
        ADCIN 0, adval                   'Read channel 0 - Temperature
        pause 20
        adcin 3, adval2                  'Read channel 3 - Battery Voltage
    
        TempF = adval * 4887             ' Convert to Voltage
        TempF = DIV32 1000               '  in millivolts (°K*10)
        TempF = TempF -2730              ' Convert °K to °C
    
        Sign = TempF.15                  ' Convert °C to °F
        TempF = ABS(TempF) * 9 / 5
        if TempF DIG 0 > 5 then          ' Round up to whole digit over .5
            TempF = TempF + 10           
        endif
        TempF = TempF / 10
        
        if Sign = 1 then TempF = -TempF  ' restore sign
        TempF = TempF + 32
    That will give it the full -50 to +150°C range (-58 to +302°F)

    Since there are negative numbers, you'll also need to change the Temperature output routine...
    Code:
        IF TempF.15 = 1 then
            dig1 = "-"
            gosub outdigit
        endif
        for i = 2 to 0 step -1            '
            dig1 = ABS(TempF) dig i       'Subroutine to send out :Temperature 
            gosub outdigit                '
        next i
    Tested on a 16F88.

    HTH,
    DT

  9. #9
    Join Date
    Jul 2007
    Location
    Maryland, USA
    Posts
    15


    Did you find this post helpful? Yes | No

    Talking

    Thank you, everyone who helped!

    Added Darrel's code into my program and still had no luck. I then put adval straight on to the LCD to see what kind of value I was getting, Ended up being a 5 digit number. I recently learned that 1024 should be the highest possible value to be displayed. So back to the registers for A/D, sure enough I had it left justified, and adcon0 bit 7 set at Fosc/8 instead of FRC(bit6 & 7 = 11). Also when I posted my code,I had TRISA = %00000001, I needed %00001001. So many problems including my formula. Fixed all that, and put the A/D back through Darrel's code ..My LCD now displays 71degree's fahrenheit, and increases when I add heat. (Am very excited!)

    Just wanted to thank everyone who replied. Came through great!
    Almost ready to launch my weather balloon!

    Have a good weekend,
    James

  10. #10
    Join Date
    Mar 2005
    Location
    Mandalay,Myanmar
    Posts
    9


    Did you find this post helpful? Yes | No

    Default to ease maths

    Hi james,
    Scaling the A/D input voltage by (230ohm+10kohm) divider or adjust the Vdd at
    5.115 volt,and if ADVAL>=511 then Farenheit=9ADVAL-4594.(Last digit is decimal fraction)
    If ADVAL<=510 then
    minus_sign=1
    Farenheit=9ADVAL-4594
    Farenheit=~Farenheit+1
    endif
    Last digit of Farenheit is decimal fraction.

    I was really sorry for first reply.At that time I didn't know PBP's 8Bits A/D conversion can
    done on 12F675.We use 16F676 to make 10 bit A/D conversion.Today we made 8bit A/D on 16F676 well.
    Thank you for sharing.

    a.majid

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. A/D conversion problem in 18F2520, 2523, 2550 etc.
    By selimkara in forum mel PIC BASIC Pro
    Replies: 9
    Last Post: - 10th March 2008, 16:26
  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