# LM35 with PIC16F877A using PICBasic

Status
Not open for further replies.

#### hckeat

##### Newbie level 5
lm35dz circuit pic

Hi, I'm new here and new to PICBasic as well.

I'm working on a project which I was required to use several temperature sensors (LM35DZ) to measure the temperature inside each room and another temperature sensor to measure the atmospheric temperature. When there is huge difference of reading between atmospheric temperature with any of the temperature sensor inside, PIC16F877A will turn on a buzzer.

Since I am new, so I started by doing the simple thing, which is to show the temperature reading of single LM35DZ using a LCD. Here's my PICBasic code below:

DEFINE osc 20

Define LCD_DREG PORTD
Define LCD_DBIT 4
Define LCD_RSREG PORTE
Define LCD_RSBIT 0
Define LCD_EREG PORTE
Define LCD_EBIT 1

lmtemp var word
temp var word

TRISA = %11111111

Start:

temp = (lmtemp*5)/10
Lcdout $fe, 1 Lcdout "Temp = ", dec temp,"C" pause 100 goto start LCD is working fine, by showing the word "Temp =", but the reading of temperature is wrong, which is "417C"! The output of LM35DZ is direct input to AN0, when I measured the output voltage of LM35DZ, it is 4.06V. I decided to remove the output of LM35DZ from PIC and measure the output voltage again, which is the correct now, 0.28V (28 deg C). I was wondering what was the problem cos the code looks OK for me. Hope you guys can help me up with this. Thanks #### leemarrow ##### Full Member level 3 calculation lm35 for pic Hi, maybe you don't have considered the quantization With 10 bits conversion you must divide by 1250. this is my code with a ref at 2,5 v and not zero, so you must subtract the read value at 25000 (2,5 v) for read negative temperature @ DEVICE pic16F876, WDT_OFF ' Watchdog Timer @ DEVICE pic16F876, PWRT_OFF ' Power-On Timer @ DEVICE pic16F876, BOD_OFF ' Brown-Out Detect @ DEVICE pic16F876, LVP_OFF ' Low-Voltage Programming @ DEVICE pic16F876, CPD_OFF ' Data Memory Code Protect @ DEVICE pic16F876, PROTECT_OFF ' Program Code Protection DEFINE LCD_DREG PORTB ' lcd on port b DEFINE LCD_DBIT 4 ' lcd data 4 bit DEFINE LCD_RSREG PORTB ' rs on port b DEFINE LCD_RSBIT 3 ' rs on rb3 DEFINE LCD_EREG PORTB ' E on port b DEFINE LCD_EBIT 0 ' on port rb0 DEFINE LCD_BITS 4 ' lcd bus 4 bit DEFINE LCD_LINES 2 DEFINE LCD_COMMANDUS 2000 DEFINE LCD_DATAUS 50 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 valore_ra1 var word 'risultato della conv. su ra1 valore_ra2 var word 'riusltato della conv. su ra2 temperatura var word 'variabile per calcolo temp segno var byte quantizza con 1250 riferimento con 25000 TRISA = %11111111 ' Setta tutte le PORTA come input ADCON1 = %10000010 ' Setta la PORTA come analogica e giustifica il risult a destra Pause 500 ' attendi .5 second Lcdout$fe, 1 'Clear screen

loop: loop: ADCIN 1, valore_ra1 'inizia conversione su ra1
adcin 2, valore_ra2 ' inizia la conversione su ra2
pause 5

valore_ra1= (valore_ra1*10) */ quantizza 'quantizzazione
valore_ra2=(valore_ra2*10) */ quantizza
temperatura=abs(valore_ra1 - riferimento)
if valore_ra1 < riferimento then segno = $2D IF valore_ra1 >=riferimento THEN segno =$20
lcdout $fe,2 'cursore a home lcdout$fe,$80,"Int ",segno,dec2 (temperatura/100),".", dec1 (temperatura//100),$DF,"C" 'Display the decimal value

lcdout $fe,$C0,"Ex ",DEC2 (valore_ra2/100),".",dec1 (valore_ra2//100),$DF,"C" lcdout$fe,$C0+9,dec2 (valore_ra1/10000),".",dec4 (valore_ra1//10000) Pause 200 'Wait .1 second Goto loop 'Do it forever End #### hckeat ##### Newbie level 5 lm35 with pic16f877a circuit diagram Thanks for the reply leemarrow. Can you make it simple for me? Because after that I'll be using one reading of LM35DZ(Let's say Temp1) to compare with one or more reading of the others LM35DZ(Mayb Temp2, Temp3 and so on) instead of using reference voltage. If the reading of Temp1 exceeds Temp2 or Temp3 for mayb 30 degree C then it will trigger an alarm, which make it looks like a fire alarm. By the way, I thought since it is 10 bit it should be divide by 1024 instead of 1250 right? Hope to get your reply soon. #### leemarrow ##### Full Member level 3 lm35dz picbasic yes really it is 1024 but read this technique extract from "Experiment with Picbasic Pro Compiler" book: "Any quantasized result depends on the accracy of quanta level, which in this case is (5/1024). This gives the result, .0048828125, clearly this is too small for the compiler's integer maths to use, therefore, we will move the decimal point right a few times, this will leave us with a quanta level of 4.8828125. To make the quanta level a real number we multiply it by 256: 4.8828125 * 256 = 1250 We now have a nice real number for our quanta level. The formula for calculating the actual voltage is: Actual voltage= Result of conversion */ quanta level For example, suppose we have taken a sample from ADC and it has returned the result of 512, the calculation now looks like this: Actual voltage= 512*/1250 This will produce a result of 2500, or 2,5 V. To achieve a slightly more accurate result, the result of the conversion needs to be increased by multiplying it by 10: Actual voltage=(512*10)*/1250 Which will produce a result of 25000, again 2,5 Volts." This technique is only for simple calculation PS: post the schema so i can help you #### hckeat ##### Newbie level 5 fire alarm circuit using lm35 Thanks leemarrow. I don't have any schematic for this as I only connect the output of LM35DZ direct to the AN0 of the programmer board with PIC16F877 attached. I want to do the basic thing by showing the temperature on LCD before I proceed to the harder part. So you think is the calculation problem but not hardware problem right? :?: #### leemarrow ##### Full Member level 3 picbasic temperature sensor Ok, no hardware problem try this code: temp var word 'result of conv on AN0 (RA0) temperature var word quanta con 1250 TRISA = %11111111 ' Set all PORTA as input (optional) ADCON1= %10001110' Configure for AN0 as analogue input ' With right justified result Pause 500 ' wait .5 second Lcdout$fe, 1 'Clear screen

loop:
pause 5

temperature= (temp*10) */ quanta
lcdout $fe,2 'cursore a home lcdout$fe,$80,"Temp ",dec2 (temperature/100),".", dec1 (temperature//100),$DF,"C" 'Display the decimal value
Pause 200 'Wait .1 second

Goto loop
End

#### hckeat

##### Newbie level 5
pic con lm35

Hi,

I just tried the code, finally I get some decimal point. The results is 04.8 deg C, although the result after I removed the output of LM35DZ from PIC is 0.28V (28 deg C).

I'll try to build the hardware on breadboard and test later. See if I can get the result.

Thanks for the help. Appreciate that.

#### hckeat

##### Newbie level 5
circuit pic16f877a rc pic basic

Finally I got the result that I want! hehe

I tested the circuit on breadboard and the simple program of showing temperature reading was working!

Suspected problem with pull-up resistor in programmer caused the error of ADC reading.

Now I can move further to the next step XD

Thanks leemarrow for the help

#### leemarrow

##### Full Member level 3
lm35 pic16f877a circuit diagram

Good work
I'm happy for you
Now the next step is to use DS1820 Sensor !

#### hckeat

##### Newbie level 5
pic16f877a 5v lm35

Hi,

I still have some question about the calculation of LM35.

Take an example, if the output of LM35 is 0.28V, and the configuration bit of ADC is as above (ADCON1= %10001110) with AN0 as the analog input and Vref+ (Vdd = 5V) Vref- (Vss = 0V), then how does the PIC converts the analog data to digital and show it on LCD?

How does the calculation looks like? (10-bit resolution being used)

#### hugo

##### Full Member level 6
adc 10 bits pic basic pic16f877a

hckeat said:
Hi,

I still have some question about the calculation of LM35.

Take an example, if the output of LM35 is 0.28V, and the configuration bit of ADC is as above (ADCON1= %10001110) with AN0 as the analog input and Vref+ (Vdd = 5V) Vref- (Vss = 0V), then how does the PIC converts the analog data to digital and show it on LCD?

How does the calculation looks like? (10-bit resolution being used)

The PIC ADC modul is getting: adc_ in (0->5000 mv) --> adc_out(0->1023)

1 step=5000/1023

the formula to calculate the voltage in mV is :

mV = (adc_out x 5000) / 1023 ;

adc_in=0 --> adc_out =0 ; mV = 0 ;

adc_in = 5000 mV --> adc_out = 1023 ; mV = 5000;

but because the output of LM35 is 10 mV/' C we have to divide it with 10 ...

temperature (deg celsius) = mV/10 = ((adc_out x 5000) / 1023 )/10 ;

so if the output of LM35 is 0.28V ( 280 mV) then we expect the temperature to be 28 'C ;

[adc_in = 280 mV) --> adc_out = (1023 x 280) / 5000 ~ 57 ]

temperature (deg celsius) = ((57 x 5000)/1023)/10 ~ 28 'c

that was just the mathematical part of it ... as far as programming is concern one can use floating point math routines or integer math routines with some tricks in order to avoid losing the accuracy ...

I hope it helps...

#### hckeat

##### Newbie level 5
pic16877a picbasic

Yea the calculation is clear enough for me, at least I have some idea now on how to calculate it.

Thanks hugo

#### intan

##### Member level 2
lm35 temperatura negativa pic

can share me the whole code? thanks

##### Member level 4
pic16f877a picbasic lcd

The complete code for the interface of Temperature sensor LM35 with PIC16f877 with circuit diagram is here

copy and enjoy...

#### hckeat

##### Newbie level 5
negative temperature lm35

DEFINE osc 20

Define LCD_DREG PORTD
Define LCD_DBIT 4
Define LCD_RSREG PORTE
Define LCD_RSBIT 0
Define LCD_EREG PORTE
Define LCD_EBIT 1

temp var word
temperature var word
quanta con 1250

TRISA = %11111111

Pause 500
Lcdout $fe, 1 loop: ADCIN 0, temp pause 5 temperature= (temp*10) */ quanta lcdout$fe,2
lcdout $fe,$80,"Temp ",dec2 (temperature/100),".", dec1 (temperature//100),$DF,"C" Pause 200 Goto loop End OK. Now I have this code of displaying temperature on LCD, I need to improve it where I need to use a keypad to enter a value of temperature, when the air temperature equal of greater than the temperature being set, PIC will ON a LED. I am wondering how to insert the keypad part. I'll be using a 4*3 keypad. #### leemarrow ##### Full Member level 3 temperature sensors pic16f877a circuit hckeat said: loop: ADCIN 0, temp pause 5 temperature= (temp*10) */ quanta lcdout$fe,2
lcdout $fe,$80,"Temp ",dec2 (temperature/100),".", dec1 (temperature//100),\$DF,"C"
Pause 200
-------------------> put here gosub to keyscan routine and compare routine
Goto loop
End

OK. Now I have this code of displaying temperature on LCD, I need to improve it where I need to use a keypad to enter a value of temperature, when the air temperature equal of greater than the temperature being set, PIC will ON a LED. I am wondering how to insert the keypad part. I'll be using a 4*3 keypad.

lampaloon

### lampaloon

Points: 2

#### microalex

##### Newbie level 1
Buenas tardes amigos.. tengo un problema y quisiera ver si me podrian ayudar..
mi problema es que no puedo realizar una subrutina para poder tomar la lectura de un LM35 y posteriormente desplegarla en lcd. la rutina par apoder desplegar los valores en el lcd ya la tengo mi problema es con tomar la lectura del sensor.. estube leyendo que debia de tenerlo con un voltaje de referencia de 2.5v. lo hice pero mi problema sigue apareciendo.. podria ayudarme alguien? no se si ya alguien realizo algo similar pero con MPLAB?

#### Sufre

##### Newbie level 1
Hi, I am new in PIC, I am going to use Flow code or asm, any body experience on this software?
I want to run the motor from temperature sensor LM35DZ, the temperature will display on the LCD. When temp go up, the motor will rotates clockwise and when temperature go down, the motor turns anticlockwise direction.
Then this temperature setting can be altered using a push button, so the user will get easily control it depends on the situation.