# Escalar un lm35 temperatura con un microcontrolador



## transistor007 (Feb 11, 2009)

hola que tal, me he tirado algun rato y tengo un mal concepto o error de programa que no encuentro. resulta que tengo un microcontrolador de 10 bits osea que su resolucion es de 4.88mv. y un sensor lm35 con una resolucion de 10mv/°c.. como hacer una tabla de quivalencias de grados centigrados contra el valor que captura mi adc del microcontrolador?...... es decir  00 0000  1111 es igual a que valor de temperatura? una pregunta mas: perdere suficiente resolucion si solo capturo 8 bits en lugar de 10 bits?
saludos

gracias por responder


----------



## Ardogan (Feb 11, 2009)

> como hacer una tabla de quivalencias de grados centigrados contra el valor que captura mi adc del microcontrolador?...... es decir 00 0000 1111 es igual a que valor de temperatura?



Se calcula un factor de conversión (manejando unidades sale). Teniendo en cuenta que 1ºC = 10 mV y que en el conversor AD 5V corresponden a un resultado del ADC de 1024:


10 mV / ºC * 1024 cuentas /5V = 0,01 V /ºC * 1024 cuentas/ 5V = 2,048 cuentas/ ºC

Temperatura = 5 ºC -> 5 * 2,048 = 10,24 cuentas-> 10 cuentas= lectura del CAD
60 ºC -> 60 * 2.048 = 122,88 -> 123 cuentas
100ºC -> 204,8 = 205 cuentas

A la inversa podemos obtener que temperatura corresponde a una lectura dada del CAD haciendo

lectura CAD [cuentas]/ 2,048 [cuentas/ºC] = lectura CAD/2,048 [ºC]

00 0000 1111 = 15 -> 15/2,048 = 7,32 ºC.

Ahora bien, cabe notar algo, fijate que de 0 a 100ºC el valor que provee el CAD va de 0 a 205. Si ese fuera el rango de medición de interés estamos aprovechando menos de la cuarta parte del rango del conversor AD. Más precisamente 2^n = 205 -> n = log 205 / log 2 = 7,7 bits.
Si aparte de eso despreciás dos bits más.... te queda un conversor con 5,7 bits, es decir, que discrimina 52 valores (aprox 2ºC por cuenta del CAD).

Si querés aprovechar todo el rango del CAD, tendrías que amplificar la señal (y filtrar de manera que el ruido no invalide bits del CAD) por 1024/205 = aprox 5 veces. Se haría con un operacional en configuración amplificador no inversor, buscá en el foro que acondicionamiento de señal del LM35 se trató varias veces ya.

También habría que tener en cuenta el offset que metería el opamp, pero su valor dependerá del circuito utilizado y de los componentes utilizados. Bueno, no quiero alargarlo con eso, cualquier cosa lo hablamos cuando tengas el circuito/componentes definidos.

Saludos


----------



## transistor007 (Feb 12, 2009)

Que buena explicación! Gracias, hace rato que comencé a realizar mi programa, gracias a tu respuesta, me surgió lo siguiente: como tengo 10 bits, mi resolución es de 4.88mv como me lo indicaste. para el ejemplo anterior cuando tengo 100°c debo tener 205 cuentas... hasta ahí todo bien..
el caso es que yo lo quiero para medir temperatura ambiente es decir oscilara entre 18 y 34°c conforme el paso de las horas! en este momento tengo 21°c según otro termómetro digital comercial y el mio marca 19°c... debo realizar algún ajuste interno es decir multiplicarlo por alguna constante debido a que no ocupo toda el potencial del lm35?... gracias


----------



## thevenin (Feb 12, 2009)

Aparentemente lo tienes todo bien. El rizado de la fuente, así también como tener una fuente estabilizada en 5V exactos influye mucho.

Comprueba el valor de la fuente y además ponle un condensador 100uF entre +Vcc y GND del PIC lo más
cerca posible del integrado.

Por ejemplo a mi me marcaba 17 grados y en cuanto le puse el electrolítico subió a 23 que era la temp.
real.

Precisamente hoy terminé un termómetro de 0 a 60º con 16F876 (a 10bits).

Si te interesa te paso todo. Lo tengo multiplexado directamente conectados los displays al puerto C, sin
7447 ni nada.

Ya contarás


----------



## Moyano Jonathan (Feb 12, 2009)

Estaría bueno que postearas el código en la parte donde haces la formula para la conversión de temperatura que pusiste al principio


----------



## Leon Elec (Feb 12, 2009)

Yo armé uno, que mide de -55ºC a 150ºC con decimales. El problema es que el hardware, por ahora está echo para que trabaje desde 0ºC a 100ºC, Necesito hacer una fuente simétrica y lo actualizo.

Este es el link http://99055.forums.motigo.com/?action=messages_show&boardmessage_id=526063


----------



## tiopepe123 (Feb 12, 2009)

Si quieres mejorar un poco la resolucion utiliza la patilla ref+ del micro , yo  suelo ponerla a mitad de la tension o sea 2.5V. Lo puedes hacer con un simple divisor de tension y un condensador, pero lo ideal seria utilizar una referencia tipo ref02 o similar, es como un zener de precision.

Si necesitas medir temperaturas negativas, necesitas jugar con el ref- y en vez de conectarlo a masa lo conectas con dos diodos en serie y conectar ese punto a Vref-


Ademas para mejorar la precision deberias promediar la lectura, hay dos formas:

1.-Mides y sumas cuatro,8,16,32,64,128,...(2^n)veces. Una vez has sumado n veces lo divides por 4,8,16....
Para dividir es tan sencillo como rotar a la derecha, cada rotacion equivale a dividir por 2,4,8

Fijate que es potencia de 2, asi las cosas se simplifican mucho en asembler y trabajando en binario


2.-Este es mas rapido y preciso pero las primeras medidas dan un error grande.

resultado=/resuldado_temp+medida)/2
resultado_temp=resultado

Para mejorar el sistema cuando arranque el programa debes poner es resultado_temp el valor mas probable, por ejemplo 25ºC


Finalmente hablaremos un poco de fisica, los sistemas termicos son integradores o sea son lentos por definicion, promediando reduces el error por ruido o fluctuaciones, un termometro rapido no necesita dar miles de numeros por segundo, sino unos pocos pero precisos, cada 0.5seg es un valor razonable.


----------



## thevenin (Feb 12, 2009)

Leon Elec dijo:
			
		

> Yo armé uno, que mide de -55ºC a 150ºC con decimales. El problema es que el hardware, por ahora está echo para que trabaje desde 0ºC a 100ºC, Necesito hacer una fuente simétrica y lo actualizo.
> 
> Este es el link http://99055.forums.motigo.com/?action=messages_show&boardmessage_id=526063



Una pregunta, ¿porqué colocas los operacionales como seguidor de emisor para adaptar la impedancia?

¿No es suficiente colocar el LM35 directo?¿La impedancia del PIC no es lo suficientemente alta para esto? 
Y en todo caso ¿no hubiera sido mejor colocar un FET como seguidor de emisor?

Yo si acaso le coloqué un condensador de 100uF en paralelo con VOUT y GND en el LM35, claro que mi termómetro es de enteros solo, pero al cambiar el último dígito noté una importante mejora en el parpadeo, antes del condensador era bastante más inestable al cambio de dígito.

Saludos.


----------



## Leon Elec (Feb 12, 2009)

He estado leyendo bastante sobre como conectar el LM35 al pic, y llegué a la conclusión que poniendo un AO es mejor para adaptar la impedancia entre el ADC del PIC y la salida del LM35. Mañana voy hacer una prueba y ponerle un condensador de 33nF para reducir los posibles ruidos.


----------



## transistor007 (Mar 4, 2009)

buenos dias!
les comento lo siguiente: he estado reslñizadno algunas pruebas sobre medir la temperatura con un lm35 y determine lo siguiente: como leere temperatura ambiente de 6 a 93°c, mi adc del micro solo tendra valores de 14 a 93 en valor decimal.

observo en la tabla que hice que cuando el adc lee un 42, ese numero lo divido entre 2 y da como resultado un 21, ese numero 21 es para mi la temperatura en °c, de tal manera que no entiendo muy bien lo que pasa!
otra cuestion que queria comentar es que cuando tengo un numero impar como el 43, el resultado de 43/2 es 21.5 que deberia marcarme por redonde como 22°c, pero como esa variable la declare como nuemro entero solo toma 21°c en lugar de 22°c.  nesecito alguna funcion en c que realice el redondeo de un numero, alguien sabe una? todo lo estoy deplegando en 4 displays 7 segmentos.

saludos


----------



## Dr. Zoidberg (Mar 4, 2009)

transistor007 dijo:
			
		

> les comento lo siguiente: he estado reslñizadno algunas pruebas sobre medir la temperatura con un lm35 y determine lo siguiente: como leere temperatura ambiente de 6 a 93°c, mi adc del micro solo tendra valores de 14 a 93 en valor decimal.
> 
> observo en la tabla que hice que cuando el adc lee un 42, ese numero lo divido entre 2 y da como resultado un 21, ese numero 21 es para mi la temperatura en °c, de tal manera que no entiendo muy bien lo que pasa!
> otra cuestion que queria comentar es que cuando tengo un numero impar como el 43, el resultado de 43/2 es 21.5 que deberia marcarme por redonde como 22°c, pero como esa variable la declare como nuemro entero solo toma 21°c en lugar de 22°c.  nesecito alguna funcion en c que realice el redondeo de un numero, alguien sabe una? todo lo estoy deplegando en 4 displays 7 segmentos.



Mirá transistor007, antes de seguir con este proyecto te recomiendo que leas sobre *sensores y acondicionamiento de señales*, por que a juzgar por lo que estas consultando no tenes mucha idea de como tienes que procesar la señal del LM35 para aprovechar el rango disponible en el ADC. Como pista...te doy algunas palabras: *amplificador operacional, ganancia, pendiente y offset*.

Saludos!


----------



## transistor007 (Mar 4, 2009)

Mirá transistor007, antes de seguir con este proyecto te recomiendo que leas sobre *sensores y acondicionamiento de señales*, por que a juzgar por lo que estas consultando no tenes mucha idea de como tienes que procesar la señal del LM35 para aprovechar el rango disponible en el ADC. Como pista...te doy algunas palabras: *amplificador operacional, ganancia, pendiente y offset*.

Saludos![/quote]

gracias por tus coments!

si tengo idea de como tratar una señal, he estado realizando pruebas con base a lo que entiendo estudio y a lo que se me sugiere en el foro, no nesecito de un operacional ya que el rango de temperatura que deseo leeer es temperatura ambiente y un micro lo puede detercar facilmente ya que el lm35 es un sensor que en mi caso no requiere de acondicionamiento de señales, como si lo requeririra un termopar tipo j o k.. etc etc...

en este momento ya estoy viendo la señal en mis 7 segmentos y tengo toda una adquisicion de mi pic, considero que me encuentro en la etapa de ajuuste fino, donde se requiere escuchar experiencias y pruebas para integrar el sistema de una forma correcta para su funcioanmiento.

no es que no sepa. sino que trato de recopilar información y experiencias para aprender aportando... digo,,, ese es el fin de todos en este foro... saludos y espero puedan contribuir.!


----------



## Leon Elec (Mar 4, 2009)

Lo que yo hago, una vez que obtengo la conversión, a esta la paso a volt de nuevo, y leo directamente el valor.


----------



## Dr. Zoidberg (Mar 4, 2009)

> en este momento ya estoy viendo la señal en mis 7 segmentos y tengo toda una adquisicion de mi pic, considero que me encuentro en la etapa de ajuuste fino, donde se requiere escuchar experiencias y pruebas para integrar el sistema de una forma correcta para su funcioanmiento.
> 
> no es que no sepa. sino que trato de recopilar información y experiencias para aprender aportando... digo,,, ese es el fin de todos en este foro... saludos y espero puedan contribuir.!



No es un ajuste fino no mucho menos, por que acá vos pusiste:



			
				transistor007 dijo:
			
		

> como leere temperatura ambiente de 6 a 93°c, mi adc del micro solo tendra valores de 14 a 93 en valor decimal.



Entonces para 87 grados de span del termómetro tu rango de conversión ocupa 93-14 = 79 valores diferentes, *lo que es una resolución muy pobre, de 1.1ºC por cada valor del ADC*.

Si tu ADC tiene 8 bits, estos son 256 valores posibles y para un span de 87 grados tendrías, si ocuparas el rango completo del conversor, 87/256=*0.34ºC por cada valor del ADC*.

Es decir, si *acondicionaras* la señal del LM35 tendrías 4 veces mas resolución que lo que estas haciendo vos ahora. Si el conversor fuera de 10 bits, tendrías una resolución con tu método de 0.28ºC contra 0.08ºC factibles de obtener sin mucho esfuerzo. Te das cuenta que estas subutilizando completamente el ADC?

Ninguna operación aritmética que hagas sobre los valores del ADC te va a devolver la resolución que perdiste, por que solo vas a tener mediciones totalmente ficticias.

Saludos!


----------



## neomatrix7776 (Mar 31, 2009)

hola a todos, yo estoy de acuerdo con tiopepe, utilizando voltaje de referencia;recien estoy entrando al mundo de la conversion analogica digital y mas o menos entiendo algo de las resoluciones.;
como dice el amigo transistor 007que solo quiere medir temperatura de ambiente me imagino que no superara los 100 grados,es decir 100x10mv=1voltio, me imagino o no se si sera posible hacer un voltaje de referencia de 1,024 voltios entonces asi tranquilamente se puede medir hasta decimales desde 0,1 grado y asi se solucionarian todos los problemas ya que tambien se olvida de escalar , la medicion estaria lista para displayar ;y todos felices ,todos contentos.
saludos a todos y espero ayudar.


----------



## yukardo (Jun 1, 2009)

Saludos.

Yo tambien he estado realizando un termometro usando el lm335 (10mV/°K) y al parecer esta todo bien el problema es que al parecer tengo algo de ruido lo cual me varia la temperatura.

Me gustaria saber de que tipo son los condensadores que mencionan arriba y como podria hacer para mejorar mi señal.

Gracias espero sus respuestas.


----------



## tormentero (Mar 24, 2010)

Hola que tal buenas tardes a todos, quisiera mass bien pido ayuda para que resolver un problema que tengo con el LM35 y el PIC165f877A ya tengo el codigo pero no se como convertir el resultado del ADC para que lo muestre en 3 display, les agradeceria mucho que me ayudaran


----------



## Chico3001 (Mar 25, 2010)

este tema te puede ayudar:

https://www.forosdeelectronica.com/f26/linealizacion-sensores-metodo-minimos-cuadrados-22866/


----------



## Meliklos (Jun 1, 2010)

veo que los que postean estan al tanto del funcionamiento del LM35, pero por favor aclarenme una duda, que no encontre en la hoja de datos...

como toma la temperatura el integrado?? 

se que es una pregunta muuuy basica pero quiero saber...
gracias!


----------



## Fogonazo (Jun 1, 2010)

Meliklos dijo:


> veo que los que postean estan al tanto del funcionamiento del LM35, pero por favor aclarenme una duda, que no encontre en la hoja de datos........



Mira el datasheet del *LM135* que es muy similar, pero aparece el esquema interno.


----------



## Meliklos (Jun 1, 2010)

sinceramente no aclaro mucho mi duda...

es muy basica mi pregunta: el lm35 capta por aproximacion verdad?


----------



## Fogonazo (Jun 1, 2010)

Meliklos dijo:


> .....es muy basica mi pregunta: el lm35 capta por aproximacion verdad?



pss:

Yo entendí que querías conocer de que manera censa la temperatura internamente.

Puede captar por proximidad, pero deberás lograr que no halla pérdidas de calor (Gradiente térmico) entre el elemento calefactor y el sensor, si no es así la temperatura detectada será irreal
Es mejor si esta inmerso en el elemento caliente o acoplado mecánica/térmicamente al elemento caliente.


----------



## Meliklos (Jun 2, 2010)

Ahora si! Gracias fogonazo  siempre aclarando dudas!


----------



## Gonzalonal (Jun 26, 2010)

Hola gente del foro. Como andan? bueno les cuento que yo recien pude terminar de hacer mi termometro digital de 10 bit de resolucion, pero tengo un pequeno error, que no se si es por culpa mia, o es error que introduce el ADC. (Los errores los veo en simulador Proteus, no en vida real)

Pensando que el lm35 mide hasta 150 C, entregando 1500mv decidi poner en el ADC la tension Vref+ a 1,5V, pensando que de esta forma iva a mejorar la precicion, agraeceria que me confirmara si esto es correcto.

Luego para hacer el calculo lo que hice: ValorADC=ValorADC/((0.01*1024)/1.5)
Es esto correcto?

El problema surge que cuando pongo por ejemplo en el simulador, 56 C el display me muestra 56.2.

Bueno espero haber aportado suficiente informacion como para que les sea facil ayudarme. Muchas gracias a todos
Saludos
Gonzalo


----------



## Chico3001 (Jun 26, 2010)

Gonzalonal dijo:


> Pensando que el lm35 mide hasta 150 C, entregando 1500mv decidi poner en el ADC la tension Vref+ a 1,5V, pensando que de esta forma iva a mejorar la precicion, agraeceria que me confirmara si esto es correcto.



Es correcto, solo asegurate de que no vaya a entrar un voltaje mayor a 1.5V en el Convertidor o existe riezgo de quemarlo 



Gonzalonal dijo:


> Luego para hacer el calculo lo que hice: ValorADC=ValorADC/((0.01*1024)/1.5)
> Es esto correcto?
> 
> El problema surge que cuando pongo por ejemplo en el simulador, 56 C el display me muestra 56.2.



Vpaso=1.5/1024=1.46484mV
560/1.46484mV=322.2941..... pasos del convertidor 

Si no usas todas las decimales en tu programa entonces tendras errores de redondeo, lo recomendable es usar voltajes de referencia que sean mutiplos de las potencias de 2 para que los calculos sean mas simples, por ejemplo si usas 2048 tendras:

Vpaso 2.048/1024= 2mV
560/2mV=280 pasos del convertidor


----------



## Gonzalonal (Jun 27, 2010)

Chico3001 muchas gracias por tu ayuda y por responder. 
Hice las modificaciones que me sugeriste, pero aun asi el error del digito decimal persiste. Te muestro el codigo que estoy usando, a ver si me podes ayudar a descubrir donde esta el error. Yo hice algunas pruebas y me parece que el error esta en el resultado que entrega el ADC mas que en el calculo. Lo que hice fue sacar por el lcd directamente la varriable ValueADC, sin hacerle ninguna modificacion, ni primedio, ni nada. La mande al lcd tal cual me la entrega el ADC, y en proteus puse en el lm35 100 C y el lcd mostraba 500.1 (Vref=2.048V)

Bueno espero que me puedan dar una mano en esta. Igual ya estoy muy agradecido
Saludos
Gonzalo


```
void temperatura(void)
{ 
	float ValueADC;
	float temp[5];
	float temprom;
	char tempres[10];
	
	adc_init(); //Inicializacion de ADC

	lcd_puts("Temperatura:");
	lcd_goto(64);
	lcd_puts("Obteniendo Datos");
		
		DelayBigMs(500);
		for(char i=0; i<5; i++)
		{
		//procesando();
		ADRESH=0b00000000;// no se si sera necesaro hacer esto pero por las dudas
		ADRESL=0b00000000;
		GODONE = 1;			// Inicia conversión
		
		while(GODONE);			// Espera a fin de converción
		ValueADC = 0;
		
		ValueADC = (ADRESH<<8)+ADRESL;	// Reune el valor en una varible
		
		ValueADC = ValueADC/((0.01*1024)/2.048); 
		temp[i]= ValueADC; //se obtienen 5 muestras oara mejor precicion, luego se saca el promedio
		
		}
		
		temprom = (temp[0] + temp[1] + temp[2] + temp[3] + temp[4])/5;
		sprintf(tempres,"%4.1f", ValueADC);
		lcd_goto(64);
		lcd_puts("                ");
		lcd_goto(64);
		lcd_puts(tempres);lcd_puts(" C");
		
		DelayBigMs(450);
		lcd_clear();
		
		ADON=0;//apago el modulo ADC
```


----------



## Chico3001 (Jun 27, 2010)

Posiblemente el error esta en esa formula tan rara, intenta probando con esta modificacion:


```
void temperatura(void)
{ 
	float ValueADC;
	float temp[5];
	float temprom;
	char tempres[10];
	
	adc_init(); //Inicializacion de ADC

	lcd_puts("Temperatura:");
	lcd_goto(64);
	lcd_puts("Obteniendo Datos");
		
		DelayBigMs(500);
		for(char i=0; i<5; i++)
		{
		//procesando();
		GODONE = 1;			// Inicia conversión
		
		while(GODONE);			// Espera a fin de conversión
		
		ValueADC = (ADRESH<<8)+ADRESL;	// Reune el valor en una varible		
		ValueADC = ValueADC*2			// solo se multiplica por el Vpaso
		temp[i]= ValueADC; //se obtienen 5 muestras oara mejor precicion, luego se saca el promedio
		
		}
		
		temprom = (temp[0] + temp[1] + temp[2] + temp[3] + temp[4])/5;
		sprintf(tempres,"%4.1f", temprom);
		lcd_goto(64);
		lcd_puts("                ");
		lcd_goto(64);
		lcd_puts(tempres);lcd_puts(" C");
		
		DelayBigMs(450);
		lcd_clear();
		
		ADON=0;//apago el modulo ADC
```


----------



## Gonzalonal (Jun 27, 2010)

Chico3001, hice la modificación que me recomendaste pero los problemas continuan. Multiplicando por 2, el lcd me muestra a 100 C, una temperatura de 1002.0 C, es decir que la escala esta mal. Probe multiplicando por 2mv (0,002V) y ya queda muy chica. Bueno, el error de escala seria lo de menos. El tema es que el error en los decimales, persiste, osea en la precisión. En lugar de 100C obtengo 100.2 C. Como te dije en el mensaje anterior, realice algunas pruebas, enviando solamente el error que entregaba el ADC al lcd y incluso ahí hay error, por eso digo que quizas, el problema este en el ADC. Tenes alguna sugerencia para mi? ya se me están acabando los recursos.
Muchas gracias por responder. Saludos


----------



## Chico3001 (Jun 27, 2010)

No veo donde puede estar el error, al menos en la rutina que pusiste... solko se me ocurre que el problema este en alguna otra parte del codigo, o sea por hardware...


----------



## Gonzalonal (Jun 27, 2010)

Gracias Chico de todas formas, ya vere que hago. Si se te ocurre alguna idea, te lo agradeceria. Saludos

Chico, teoricamente, si yo conecto la Vref a la entrada del ADC en lugar del LM35, y mostrando en pantallla solo el valor que entrga el ADC, me deberia mostrar 1024 no? por que a mi me muestra 1023. A que se debera esto?

Creo que ya descubri a que se debia el error. Parece que Proteus anade un  error a proposito en sus mediciones como para darle mas veracidad. conecte un voltimetro (virtual) al lm35 en el proteus, y cuando este decia 10C el voltimetro indicaba 111mv en lugar de 110.

Utilizando 10 bits de rsolucion, y con una VREF=2.048, cual es la precicion que puedo lograr que el lcd me muestre?
Como seria el calculo, asi decido que VREF me conviene usar
Gracias
Gonzalo


----------

