Need help with LM34 and 12F675


Closed Thread
Results 1 to 11 of 11
  1. #1
    Join Date
    Nov 2009
    Location
    Wagoner, USA
    Posts
    52

    Default Need help with LM34 and 12F675

    I'm trying to build a fan controller for a solar heater that I built but I can't seem to get it to work. I've tried everything I can think of and now I need help.
    Yes probably that kind too. I was sane before I started this.
    I'm using an LM34 temperature sensor which outputs 10mv/deg F from 5F (50mv) to 300F (3000mv) and a 12F675.
    Attached is a text file with the code and it is also listed below.
    Any help would be appreciated. I'm trying to make it come on at 115F and go off at 80F, settable in a constant at the beginning of the code. Later I want to add PWM for servo operated dampers.
    Any help will be appreciated.

    Code:
    'Modified from file found at Renolds Electronics
    'http://www.rentron.com/PIC12C67XAD.htm
    'LM34
    'PIN  NAME     Purpose
    ' 1    VDD      +5v
    ' 2   Output    10mv/degF, +5° to +300°F = 50mv-3000mv
    ' 3    VSS      GND      
    ' 
    'PIC12F675 
    ' PIN  NAME     Purpose
    '  1    VDD      +5v
    '  8    VSS      GND
    '  5   GPIO.2   PWM out to servo
    '  6   GPIO.1   Output to NPN transistor sinking relay.
    '  7   GPIO.0   A/D input from center leg of LM34
    '******************* Fuses, Defines, Variables & Constants ******************
    @ device pic12F675, intrc_osc_noclkout, wdt_off, pwrt_on, mclr_off, bod_off, protect_off
    define OSC 4        'Use 4mhz osc  
    CMCON=7             '(%00000111) Turn off analog comparators
    TRISIO=%001001      '(Dec 9)Port direction register. 1=input, 0=output Note TRISIO.3 is always an input.
    RESULT   VAR BYTE	'A/D CONVERSION RESULT STORAGE BYTE
    ADCON1=6		    '(%00000110) SET GP.0 TO ANALOG INPUT, Vref = Vdd, ALL ELSE = DIGITAL I/O
    HighTemp var byte   'High temperature setpoint 
    LowTemp  Var byte   'Low  temperature setpoint
    Relay    var GPIO.1 'Output pin tp transistor
    'PWMOut   var GPIO.2 'Pin 5 used to drive damper servos 'To be implemented later
    HighTemp = 115      'Relay turn on Temp
    LowTemp = 80        'Relay turn off temp
    '************************ Main ************************
    MAIN:
        GOSUB GETVAL		'SETUP A/D
            pause 500       'Wait 500ms 
        gosub Setrelay      'Turn on or off relay
            pause 500        
        GOTO MAIN           'Start over
    '************************
    GETRESULT:
            PAUSEUS 50	   'WAIT FOR A/D CHANNEL SETUP (50 uS)
            ADCON0.2 = 1   'START CONVERSION BY SETTING GO/DONE-BIT (HIGH)
    '************************
    LOOP:                  'WAIT FOR GO/DONE BIT TO BE CLEARED
        IF ADCON0.2=1 THEN 'CHECK GO/DONE BIT (0=DONE)
            GOTO LOOP      'NOT FINISHED CONVERTING, THEN LOOP UNTIL DONE
        ENDIF			   'IF STATEMENT SATISFIED, ADCON0.2 = 0 (DONE)
    RETURN			       'FINISHED CONVERSION, RETURN TO GETVAL ROUTINE
    '************************
    GETVAL:
            ADCON0=%10000001 'SET A/D Fosc/32,[4MHz], CHANNEL-0 = ON
        GOSUB GETRESULT	   'START THE CONVERSION
            RESULT = ADRES 'STORE THE A/D CONVERSION VALUE IN RESULT
    RETURN			       'RETURN TO MAIN ROUTINE, START OVER
    END			
    '************************
    SetRelay:       'Turn on or off relay with hysterisis                                 
        select case RESULT
            case RESULT <= lowTemp
                low relay
           'PWM GPIO.2, 127, 100 'Need 1ms wide pulse at about 40-50 per second. To be implemented later 
            case RESULT > LowTemp and Temp > HighTemp
                low Relay
           'PWM GPIO.2, 25, 100 'Need 1ms wide pulse at about 40-50 per second. To be implemented later                   
        end select 
    'PWM GPIO.2, 127, 100  'Send 50% (127) duty cycle pwm signal out pin 5 for 100 cycles                                                                    
    return             
        END
    Attached Files Attached Files

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


    Did you find this post helpful? Yes | No

    Default

    To start with, your PIC does not have a ADCON1
    It works more like this.
    http://www.picbasic.co.uk/forum/showthread.php?t=11947
    Dave
    Always wear safety glasses while programming.

  3. #3
    Join Date
    Nov 2009
    Location
    Wagoner, USA
    Posts
    52


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by mackrackit View Post
    To start with, your PIC does not have a ADCON1
    It works more like this.
    http://www.picbasic.co.uk/forum/showthread.php?t=11947
    Still not sure I understand. My brain hurts at this point.
    Ok Should be ADCON0=%00000101?
    I may need to sleep on this and try again tomorrow.
    The data sheet has me confused.

  4. #4
    Join Date
    May 2008
    Location
    Italy
    Posts
    825


    Did you find this post helpful? Yes | No

    Default

    Cancelled

    Al.
    All progress began with an idea

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


    Did you find this post helpful? Yes | No

    Default

    Maybe this will get you going with the ADC on this chip. Seems like MicroChip likes to keep folks guessing by changing some things around for different chips.

    This will display the 8 bit ADC reading on a terminal.
    Code:
    <font color="#000080"><i>'12F675 ADC TEST FOR CHANNEL 0
        </i></font><font color="#FF0000"><b>DEFINE </b></font><font color="#0000FF"><b>OSC </b></font><font color="#800000"><b>4
       </b></font>@ <font color="#0000FF"><b>__config _INTRC_OSC_NOCLKOUT </b></font>&amp; <font color="#0000FF"><b>_WDT_ON </b></font>&amp; <font color="#0000FF"><b>_MCLRE_OFF </b></font>&amp; <font color="#0000FF"><b>_CP_OFF
        ANSEL</b></font>=<font color="#800000"><b>%00000001 </b></font>:<font color="#0000FF"><b>CMCON</b></font>=<font color="#800000"><b>7 </b></font>:<font color="#0000FF"><b>TRISIO </b></font>= <font color="#800000"><b>%001001
        </b></font><font color="#0000FF"><b>RESULT   </b></font><font color="#FF0000"><b>VAR BYTE</b></font>	<font color="#000080"><i>'A/D CONVERSION RESULT STORAGE BYTE
    
        </i></font><font color="#0000FF"><b>START</b></font>:  <font color="#000080"><i>'A HEART BEAT
        </i></font><font color="#0000FF"><b>GPIO </b></font>= <font color="#800000"><b>%010000</b></font>:<font color="#FF0000"><b>PAUSE </b></font><font color="#800000"><b>500</b></font>:<font color="#0000FF"><b>GPIO </b></font>= <font color="#800000"><b>%000000</b></font>:<font color="#FF0000"><b>PAUSE </b></font><font color="#800000"><b>500
        </b></font><font color="#FF0000"><b>SEROUT2 </b></font><font color="#0000FF"><b>GPIO</b></font>.<font color="#800000"><b>5</b></font>, <font color="#800000"><b>16780</b></font>, [<b><i>&quot;RESULT &quot;</i></b>,<font color="#FF0000"><b>DEC </b></font><font color="#0000FF"><b>RESULT</b></font>,<font color="#800000"><b>$a</b></font>,<font color="#800000"><b>$d</b></font>]
        <font color="#FF0000"><b>PAUSE </b></font><font color="#800000"><b>50
        </b></font><font color="#FF0000"><b>GOSUB </b></font><font color="#0000FF"><b>ADC_0      </b></font><font color="#000080"><i>'STARTS THE READING OF ADC CHANNEL 0
        </i></font><font color="#FF0000"><b>GOTO </b></font><font color="#0000FF"><b>START
        
        ADC_0</b></font>:       <font color="#000080"><i>'READ AN0
        </i></font><font color="#0000FF"><b>ADCON0 </b></font>= <font color="#800000"><b>%00000001      </b></font><font color="#000080"><i>'TURNS ADC ON
        </i></font><font color="#FF0000"><b>GOSUB   </b></font><font color="#0000FF"><b>READ_AD
        RESULT </b></font>= <font color="#0000FF"><b>ADRESH    </b></font><font color="#000080"><i>'PLACES THE ADC VALUE INTO VAR
        </i></font><font color="#FF0000"><b>RETURN
        
        </b></font><font color="#0000FF"><b>READ_AD</b></font>:   <font color="#000080"><i>'DOES THE ADC CONVERSION
        </i></font><font color="#FF0000"><b>PAUSE   </b></font><font color="#800000"><b>50
        </b></font><font color="#0000FF"><b>ADCON0</b></font>.<font color="#800000"><b>1</b></font>=<font color="#800000"><b>1
        </b></font><font color="#FF0000"><b>WHILE </b></font><font color="#0000FF"><b>ADCON0</b></font>.<font color="#800000"><b>1</b></font>=<font color="#800000"><b>1</b></font>:<font color="#FF0000"><b>WEND
        RETURN  
    </b></font>
    Dave
    Always wear safety glasses while programming.

  6. #6
    Join Date
    Nov 2009
    Location
    Wagoner, USA
    Posts
    52


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by mackrackit View Post
    Maybe this will get you going with the ADC on this chip. Seems like MicroChip likes to keep folks guessing by changing some things around for different chips.
    This will display the 8 bit ADC reading on a terminal.
    Thanks I'll try it tomorrow. I just needed to get away from it for awhile.
    I started over from scratch this morning and finally got it working. Only thing is that it reads exactly half the temperature (input voltage from the LM34). I multiplied it by 2 in the software to fix the problem but I don't know why it does that. Is there a calibration for the A/D?
    Anyway here is my final working code for anyone interested. It could probably be optimized but it ain't broke so I ain't gonna fix it.

    I built this to control a solar heater (see it on my web site). It basically reads the voltage from the LM34 on GPIO.0 10mv per deg F and
    turns on a fan relay on GPIO.1 when the temperature goes above the preset temp (110F) and outputs a PWM signal on GPIO.2 to open a damper door.
    Below the preset low temperature (90F) it turns off the fan and again sends out a PWM signal to close the damper. I still need to tweak pulse widths for the servo. I just set them up to make sure the PWM works.
    It also sends out the current temperature and preset info on GPIO.4 to a PC terminal if needed using the debug command.
    Hope someone else can use the info and thanks to Bruce for making the basics available.

    Code:
    'Modified from file found at Renolds Electronics
    'http://www.rentron.com/PIC12C67XAD.htm
    'LM34 F temperature sensor
    'PIN  NAME     Purpose
    ' 1    VDD      +5v
    ' 2   Output    10mv/degF, +5° to +300°F = 50mv-3000mv
    ' 3    VSS      GND      
    ' 
    'PIC12F675 
    ' PIN  NAME     Purpose
    '  1    VDD      +5v
    '  8    VSS      GND
    '  3   GPIO.4   Serial out for debug
    '  5   GPIO.2   PWM out to servo
    '  6   GPIO.1   Output to NPN transistor sinking relay.
    '  7   GPIO.0   A/D input from center leg of LM34
    '********************************* Fuses ******************************
    @ device pic12F675, intrc_osc_noclkout, wdt_off, pwrt_on, mclr_off, bod_off, protect_off
    '********************************* Setup *******************************
    DEFINE debug_mode 1     '0=True, 1=Inverted serial data
    DEFINE debug_bit 4      'sends serial data out GPIO.4 at N,8,1
    DEFINE debug_baud 2400  'Default baud rate = 2400
    DEFINE osc 4            'We're using a 4 MHz oscillator
    Define OSCCAL_1K 1      'Set OSCCAL for 1K device
    DEFINE ADC_BITS 8       'Set A/D for 8-bit operation
    DEFINE ADC_SAMPLEUS 50  'Set A/D sampling time @ 50 uS
    CMCON=7                 '(%00000111) Turn off analog comparators
    TRISIO=%001001          'Port direction register. GPIO.0 & GPIO.3 =inputs (.3 is always input)
    ADCON0=%00000000        'Left justified,Vref = Vdd,GP.0=ANALOG INPUT
    ANSEL=%01010001         'FOSC=16=101,GPIO.0=analog
    Samples VAR WORD        ' Multiple A/D sample accumulator
    Sample  VAR BYTE        ' Holds number of Samples to take
    Temp    VAR BYTE        ' Temperature storage
    PWMPin  var GPIO.2      'Variable for PWM output
    Relay   var GPIO.1      'Variable for relay output
    'LowTemp var byte
    'HighTemp var byte
    LowTemp con 90          'Turn off relay
    HighTemp con 110        'Turn on relay
    Samples = 0             ' Clear Samples accumulator on power-up
    PAUSE 500               ' Wait .5 second
    '********************************* Main ********************************
    loop:
        FOR sample = 1 TO 20    ' Take 20 Samples
            ADCIN 0, temp       ' Read channel 0 into temp variable
            Samples = Samples + temp ' Accumulate 20 Samples
            PAUSE 250           ' Wait approximately 1/4 seconds per loop
        NEXT sample
            temp = Samples/20*2
            if temp >lowtemp and temp>hightemp then gosub onrelay
            if temp <=lowtemp then gosub offrelay
    DEBUG "Current Temp: ",DEC temp," Low Turn Off: ",dec lowtemp," High Turn On: ",dec hightemp,10,13
               Samples = 0         ' Clear old sample accumulator
        GOTO loop               ' Do it forever
        END
    '******************************* Output **********************************                                                                 
    OnRelay:
            high relay           'Turns on GPIO.1
            PWM PWMPin, 127, 500 '50% duty cycle for 500 cycles on GPIO.2
    return
    OffRelay:
            low relay            'Turns off GPIO.1
            PWM PWMPin, 64, 500 '25% duty cycle for 500 cycles on GPIO.2
    return

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


    Did you find this post helpful? Yes | No

    Default

    That is the way the LM34 is when running on 5 volts. Figure the steps in 8 bit and all that.

    If you want a 1 degree resolution set up the VREF and have the reference voltage at 3.3 volts.

    Then in place of multiplying by 2
    you would use
    ADC_VAR * 4 / 3

    At least that works for me

    Glad you got it going.
    Dave
    Always wear safety glasses while programming.

  8. #8
    Join Date
    Nov 2009
    Location
    Wagoner, USA
    Posts
    52


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by mackrackit View Post
    That is the way the LM34 is when running on 5 volts. Figure the steps in 8 bit and all that.
    If you want a 1 degree resolution set up the VREF and have the reference voltage at 3.3 volts.
    Then in place of multiplying by 2
    you would use
    ADC_VAR * 4 / 3
    At least that works for me
    Glad you got it going.
    Thanks for the tip. I'll have to try to find a 3.3v reference tomorrow. I have some 1.25's but that's a little shy.
    The LM34 is doing what it's supposed to. It is putting out .700v at 70 degrees but the pic reads it as .350v.
    Thanks..

  9. #9
    malc-c's Avatar
    malc-c Guest


    Did you find this post helpful? Yes | No

    Default

    Interesting thread, and quite by chance similar to a project I was contemplating.

    I was thinking of making my own pulse proportional thermostat for use with reptile enclosures. Your code could be the ideal starting point for me, thanks for sharing

  10. #10
    Join Date
    Nov 2009
    Location
    Wagoner, USA
    Posts
    52


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by malc-c View Post
    Interesting thread, and quite by chance similar to a project I was contemplating.
    I was thinking of making my own pulse proportional thermostat for use with reptile enclosures. Your code could be the ideal starting point for me, thanks for sharing
    I've made a couple of changes since I posted that. I'm using the plusout command instead of the PWM command. There is better control with the pulsout command.
    I've also added an external thermostat to turn it off. Man does it get hot!
    GPIO.1 is pulled low through a 10k then goes to VDD through a wall thermostat.
    Here is the final working code:
    Code:
    'LM34 F temperature sensor
    'PIN  NAME     Purpose
    ' 1    VDD      +5v
    ' 2   Output    10mv/degF, +5° to +300°F = 50mv-3000mv
    ' 3    VSS      GND      
    ' 
    'PIC12F675 
    ' PIN  NAME     Purpose
    '  1    VDD     +5v VDD
    '  2   GPIO.5   Serial out for debug
    '  3   GPIO.4   PWM out to servo
    '  4   GPIO.3   ***Programmer VPP
    '  5   GPIO.2   Output to NPN transistor sinking relay.
    '  6   GPIO.1   Input from thermostat /***Programmer Clk                  
    '  7   GPIO.0   Analog input from center leg of LM34 /***Programmer Data
    '  8    VSS     GND VSS
    '********************************* Fuses ******************************
    @ device pic12F675, intrc_osc_noclkout, wdt_off, pwrt_on, mclr_off, bod_off, protect_off
    '********************************* Setup *******************************
    DEFINE debug_mode 1     '0=True, 1=Inverted serial data
    DEFINE debug_bit 5      'sends serial data out GPIO.5 at N,8,1
    DEFINE debug_baud 2400  'Default baud rate = 2400
    DEFINE osc 4            'We're using a 4 MHz oscillator
    Define OSCCAL_1K 1      'Set OSCCAL for 1K device
    DEFINE ADC_BITS 8       'Set A/D for 8-bit operation
    DEFINE ADC_SAMPLEUS 50  'Set A/D sampling time @ 50 uS
    CMCON=7                 '(%00000111) Turn off analog comparators
    TRISIO=%00001011        '001001 Port direction register. GPIO.0 & GPIO.3 =inputs (.3 is always input)
    ADCON0=%00000000        '00000000 Left justified,Vref=VDD,GP.0=ANALOG INPUT
    ANSEL=%01010001         '01010001 FOSC=16=101,GPIO.0=analog
    Samples VAR WORD        'Multiple A/D sample accumulator
    Sample  VAR BYTE        'Holds number of Samples to take
    Temp    VAR BYTE        'Temperature storage
    Thermostat var bit      'Input from thermostat                        
    Relay   var GPIO.2      'Variable for relay output
    LowTemp con 90          'Turn off relay
    HighTemp con 110        'Turn on relay
    Samples = 0             'Clear Samples accumulator on power-up
    '****************************** Servo Stuff ****************************
    Servo  var GPIO.4       'Variable for PWM output
    low servo               'Initilize GPIO.4 to low
    Accum var byte          'GP Accumulator variable
    AccLow con 100           'Accumulator Min pulse (move CCW)
    AccHigh con 250         'Accumulator Max pulse  (Move Cw)
    Wait1 con 20            'Delay before repeating loop
    Flag   var bit          'Holds bit for servo position
    flag=0                  'initilize flag
    PAUSE 500               'Wait .5 second
    '********************************* Main ********************************
    Main:
        FOR sample = 1 TO 20    ' Take 20 Samples
            ADCIN 0, temp       ' Read channel 0 into temp variable
            Samples = Samples + temp ' Accumulate 20 Samples
            PAUSE 250           ' Wait approximately 1/4 seconds per loop
        NEXT sample
            temp = Samples/20*2
            if temp >lowtemp and temp>hightemp and thermostat=1 then gosub onrelay  
            if temp <=lowtemp then gosub offrelay
    DEBUG "Curr Temp: ",DEC temp,"° F ",10,13,10,13," Off Temp: ",dec lowtemp,"° F "," On Temp: ",dec hightemp,"° F ",10,13
    DEBUG "CCW Pulse Width: ",dec Acclow,"ms ", "CW Pulse Width: ",dec Acchigh,",ms ", "Flag: ",dec flag,10,13  
               Samples = 0      ' Clear old sample accumulator
        GOTO main               ' Do it forever
        END
    '******************************* Output **********************************                                                                 
    OnRelay:
            high relay           'Turns on GPIO.1
            if flag=0 then gosub VentOpen  'If vent is closed then open it.
    return
    OffRelay:
            low relay            'Turns off GPIO.1
            if flag=1 then gosub VentClosed 'if vent is open then close it.      
    return
    '**************************** Open Damper ********************************
    '@@@@@@@@@ SWAP LINES 75 & 76 AND LINES 84 & 85 TO REVERSE ROTATION @@@@@@@@@@@@
    VentOpen:  
        for Accum=acchigh to acclow step -1 'Move servo 90 deg CW
        'for Accum=Acclow to acchigh  'Move servo 90 deg CCW
            pulsout servo, Accum                                
            pause Wait1     
        next                         
    	    flag=1            'Set Flag to tell when open
    return
    '**************************** Close Damper *******************************
    VentClosed:
        for Accum=Acclow to acchigh  'Move servo 90 deg CCW
        'for Accum=acchigh to acclow step -1 'Move servo 90 deg CW
            pulsout servo, Accum
            pause Wait1
        next
    	    flag=0            'Set Flag to tell when closed
    return
    Last edited by polymer52; - 6th December 2009 at 12:27.

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


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by malc-c View Post
    Interesting thread, and quite by chance similar to a project I was contemplating.

    I was thinking of making my own pulse proportional thermostat for use with reptile enclosures. Your code could be the ideal starting point for me, thanks for sharing
    Hi, Malc

    I think there's something for you here ...

    http://www.parallax.com/Portals/0/Do...oks/edu/ic.pdf

    have a nice time ...

    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. 12f675 sensing temperature...
    By rossfree in forum mel PIC BASIC Pro
    Replies: 4
    Last Post: - 6th April 2007, 00:11

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