PDA

View Full Version : Temp project using LM34



Philley
- 25th April 2007, 16:23
Hi just started getting into the whole Microcontroller world and have a problem that I can't wrap my head around. I've made some code up that will use the LM34 to measure the temperature in C and F and display them on the LCD. But my problem now is that I want to be able use SW1 on the 16F877 to switch from a Celsius reading to a Farenheit reading but still being able to get current temperature readings. Below I have the code that I'm using at the moment but figuring out how to use the SW1 to switch back and forth is bothering me to say the least. Any help or guide me in the right direction would be appreciated.

The board I'm using is a LabX-1 16F877.

DEFINE LCD_DREG PORTD 'data register
DEFINE LCD_RSREG PORTE 'register select
DEFINE LCD_RSBIT 0 'pin number
DEFINE LCD_EREG PORTE 'enable register
DEFINE LCD_EBIT 1 'enable bit
DEFINE LCD_RWREG PORTE 'read/write register
DEFINE LCD_RWBIT 2 'read/write bit
DEFINE LCD_BITS 8 'width of data
DEFINE LCD_LINES 2 'lines in display
DEFINE LCD_COMMANDUS 2000 'delay in micro seconds
DEFINE LCD_DATAUS 20 'delay in micro seconds

'Set the port directions. We are setting PORTA.0 to an input, all rest outputs
'all of PORTD is set to outputs to run the LCD
'and all of PORTE as outputs even though PORTE has only 3 lines.

TRISA = %11111111 'set PORTA lines
TRISD = %00000000 'set all PORTD lines to output
TRISE = %00000000 'set all PORTE lines to output
'Set the Analog to Digital control register
ADCON1=%10000010 'see discussion above
'Define the variables used
ADVAL VAR BYTE 'Create ADVAL to store result
TEMP VAR BYTE 'temperature Farenheit variable
TEMPC VAR BYTE 'temperature Celsius variable
DEG CON 223 'write an degree mark on lcd
'define the adcin parameters
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
LCDOUT $FE, 1 'clear screen

LOOP: 'The main loop of the program
PAUSE 250 'pause 0.5 seconds
ADCIN 4, ADVAL 'Read channel 0 to adval
ADVAL =(ADVAL*/500)>>2
TEMP=ADVAL
TEMPC=((TEMP-32) *100) /180
LCDOUT $FE, 2 'go to home position
LCDOUT "Temp=", DEC3 TEMP,DEG, "F" 'print to line 1 of 2 line display
LCDOUT $FE,$C0, "Temp=", DEC3 TEMPC,DEG, "C"
GOTO LOOP
END

mackrackit
- 25th April 2007, 16:37
I would say have LOOPC and LOOPF and MAIN program blocks. SW1 sits in main and depending on HIGH or LOW GOTO LOOPC or LOOPF. Then go back to main to check SW1.

Add a PAUSE 250 in the LOOPs before going back to MAIN.

You can shorten this up a bit, but try this first.

mister_e
- 25th April 2007, 16:43
PAUSE 200 ' or whatever
if SW1=1 then
LCDOUT "Temp=", DEC3 TEMP,DEG, "F"
ELSE
LCDOUT "Temp=", DEC3 TEMPC,DEG, "C"
ENDIF
GOTO LOOP

mmm SW1 is an Tact switch connected between PORTB.0 and PORTB.4 right?

mister_e
- 25th April 2007, 16:58
try this

<code><font color="#000000"> <font color="#000080">DEFINE </font>LCD_DREG PORTD <font color="#008000">'data register
</font><font color="#000080">DEFINE </font>LCD_RSREG PORTE <font color="#008000">'register select
</font><font color="#000080">DEFINE </font>LCD_RSBIT 0 <font color="#008000">'pin number
</font><font color="#000080">DEFINE </font>LCD_EREG PORTE <font color="#008000">'enable register
</font><font color="#000080">DEFINE </font>LCD_EBIT 1 <font color="#008000">'enable bit
</font><font color="#000080">DEFINE </font>LCD_RWREG PORTE <font color="#008000">'read/write register
</font><font color="#000080">DEFINE </font>LCD_RWBIT 2 <font color="#008000">'read/write bit
</font><font color="#000080">DEFINE </font>LCD_BITS 8 <font color="#008000">'width of data
</font><font color="#000080">DEFINE </font>LCD_LINES 2 <font color="#008000">'lines in display
</font><font color="#000080">DEFINE </font>LCD_COMMANDUS 2000 <font color="#008000">'delay in micro seconds
</font><font color="#000080">DEFINE </font>LCD_DATAUS 20 <font color="#008000">'delay in micro seconds

'Set the port directions. We are setting PORTA.0 to an input, all rest outputs
'all of PORTD is set to outputs to run the LCD
'and all of PORTE as outputs even though PORTE has only 3 lines.
</font>TRISA = %11111111 <font color="#008000">'set PORTA lines
</font>TRISD = %00000000 <font color="#008000">'set all PORTD lines to output
</font>TRISE = %00000000 <font color="#008000">'set all PORTE lines to output
</font> <font color="#008000">'Set the Analog to Digital control register
</font>ADCON1=%10000010 <font color="#008000">'see discussion above

' added
' -----
</font>TRISB = %00001111 <font color="#008000">'PORTB&lt;3:0&gt; = input
</font> <font color="#008000">' others to output
</font>OPTION_REG.7=0 <font color="#008000">' ENABLE INTERNAL PULL-UPS
' -----

'Define the variables used
</font>ADVAL <font color="#000080">VAR</font> <font color="#000080">BYTE</font> <font color="#008000">'Create ADVAL to store result
</font>TEMP <font color="#000080">VAR</font> <font color="#000080">BYTE</font> <font color="#008000">'temperature Farenheit variable
</font>TEMPC <font color="#000080">VAR</font> <font color="#000080">BYTE</font> <font color="#008000">'temperature Celsius variable
</font>DEG <font color="#000080">CON </font>223 <font color="#008000">'write an degree mark on lcd

</font>Mode <font color="#000080">VAR BIT
</font>C <font color="#000080">CON </font>1
F <font color="#000080">CON </font>0


<font color="#008000">'define the adcin parameters
</font><font color="#000080">DEFINE</font> ADC_BITS 10 <font color="#008000">'Set number of bits in result
</font><font color="#000080">DEFINE</font> ADC_CLOCK 3 <font color="#008000">'Set clock source (3=rc)
</font><font color="#000080">DEFINE</font> ADC_SAMPLEUS 50 <font color="#008000">'Set sampling time in uS

</font><font color="#000080">PAUSE </font>500
<font color="#000080">LCDOUT </font>$FE, 1 <font color="#008000">'clear screen
</font>PORTB.4=0
Mode = C

LOOP: <font color="#008000">'The main loop of the program
</font><font color="#000080">ADCIN </font>4, ADVAL <font color="#008000">'Read channel 0 to adval
</font>ADVAL =(ADVAL*/500)&gt;&gt;2
TEMP=ADVAL
TEMPC=((TEMP-32) *100) /180

<font color="#000080">IF </font>PORTB.0=0 <font color="#000080">THEN
</font>Mode = Mode ^ 1
<font color="#000080">WHILE </font>PORTB.0 = 0 : <font color="#000080">WEND
PAUSE </font>50
<font color="#000080">ENDIF

PAUSE </font>200
<font color="#000080">LCDOUT </font>$FE, 1,&quot;Temp=&quot;
<font color="#000080">IF </font>Mode=F <font color="#000080">THEN
LCDOUT DEC3 </font>TEMP,DEG, &quot;F&quot; <font color="#008000">'print to line 1 of 2 line display
</font><font color="#000080">ELSE
LCDOUT DEC3 </font>TEMPC,DEG, &quot;C&quot;
<font color="#000080">ENDIF

GOTO </font>LOOP
<font color="#000080">END


</font></code>

sure a INT0 interrupt would have it's own advantages as well. Begin with it.

Philley
- 1st May 2007, 22:51
Ok thank you for the helpful ideas I've used those ideas now I want to incorporate an LED alarm that when the temp gets to >=80 degrees F that the LED 0 will flash and I won't be able to turn the alarm off until the temp goes below 80 degrees and switch 2 has been pressed.

Below I have the code that I've tried to put into the microcontroller but everytime i try to do something I get caught up with no display on the LCD, any help would be appreciated.


DEFINE LCD_DREG PORTD 'data register
DEFINE LCD_RSREG PORTE 'register select
DEFINE LCD_RSBIT 0 'pin number
DEFINE LCD_EREG PORTE 'enable register
DEFINE LCD_EBIT 1 'enable bit
DEFINE LCD_RWREG PORTE 'read/write register
DEFINE LCD_RWBIT 2 'read/write bit
DEFINE LCD_BITS 8 'width of data
DEFINE LCD_LINES 2 'lines in display
DEFINE LCD_COMMANDUS 2000 'delay in micro seconds
DEFINE LCD_DATAUS 20 'delay in micro seconds

'Set the port directions. We are setting PORTA.0 to an input, all rest outputs
'all of PORTD is set to outputs to run the LCD
'and all of PORTE as outputs even though PORTE has only 3 lines.

TRISA = %11111111 'set PORTA lines
TRISB = %00101111
TRISD = %00000000 'set all PORTD lines to output
TRISE = %00000000 'set all PORTE lines to output

ADCON1=%10000010 'see discussion above
OPTION_REG.7=0
'Define the variables used
ADVAL VAR BYTE 'create ADVAL to store result
TEMP VAR BYTE 'temperature Farenheit variable
TEMPC VAR BYTE 'temperature Celsius variable
DEG CON 223 'write an degree mark on lcd
MODE VAR BIT
C CON 1
F CON 0
LED VAR BYTE
'define the adcin parameters
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
PAUSE 500
LCDOUT $FE, 1 'clear screen
PORTB.4=0
PORTB.5=0
MODE=C

LOOP: 'The main loop of the program
ADCIN 4, ADVAL 'Read channel 0 to adval
ADVAL =(ADVAL*/500)>>2
TEMP=ADVAL
TEMPC=((TEMP-32) *100) /180
IF TEMP<32 THEN TEMP=32
IF TEMP>100 THEN TEMP=100
IF TEMP>=80 THEN GOSUB FLASH
IF PORTB.0=0 THEN
MODE=MODE^1
WHILE PORTB.0=0 : WEND
PAUSE 50
ENDIF
PAUSE 100
LCDOUT $FE, 1, "TEMP=" 'go to home position
IF MODE=F THEN
LCDOUT DEC3 TEMPC,DEG, "C" 'print to line 1 of 2 line display
ELSE
LCDOUT DEC3 TEMP,DEG, "F"
ENDIF
GOTO LOOP
END
FLASH:
PAUSE 100 ' pause .1 sec to hear tone
HIGH PORTD.0
PAUSE 350
LOW PORTD.0
PAUSE 350
RETURN