LM35 estabilizar lectura.

Buenos días.
Tengo una Arduino UNO con Ethernet y una LM35, lo he conectado de tal forma que la temperatura la pueda tenerla en Xively y poder ver un historial. El problema es que me varía mucho la lectura una más de un grado de diferencia, quisiera saber como podría conseguir que la lectura no me oscile tanto.
Saludos cordiales.
Francisco.

Depende del motivo de esa variación. Si es tipo rizado simplemente haz la media de las últimas X lecturas.

Buenos días, gracias por responder, pongo la instrucción que calcula la media y aún así me oscila bastante ; Como puedes ver
hago a media con 10 medidas y sigue mal, pongo el enlace en Xively para que puedas verlo.
" https://xively.com/feeds/1468193080 " . El LM35 lo tengo alimentado a 5 Vcc.
Un saludo y buen día¡¡¡¡

//tempC = analogRead(sensorPin);
 tempC = (analogRead(sensorPin)+analogRead(sensorPin)+analogRead(sensorPin)+analogRead(sensorPin)+analogRead(sensorPin)  +analogRead(sensorPin)+analogRead(sensorPin)+analogRead(sensorPin)+analogRead(sensorPin)+analogRead(sensorPin))/10; // 10 lecturas para la media.
 
 tempC = (5.0 * tempC * 100.0)/1024.0;  
 
 int sensorValue = analogRead(sensorPin);
 datastreams[0].setFloat(tempC);
 
 Serial.print("Read sensor value ");
 Serial.println(datastreams[0].getFloat());

Tu problema es una cuestión básica de la electrónica: ruido en la señal. Es algo que todo diseñador debe considerar.

El ruido en la medida puede tener diversas fuentes.
Ruido generado en el propio sensor, sus cables, ruido en el CAD debido al diseño deficiente de la placa Arduino ¡ala lo que acabo de decir :wink: ! ruido debido a fluctuaciones en la referencia de tensión interna del uC.

El LM35 da una señal de 10mC/ºC, osea a 22ºC da unos 0.22V. Prueba a medir con un osciloscopio el rizado de alimentación del uC en el Arduino UNO oficial y lo mismo para la señal a medir procedente de tu sensor.

Ante semejante panorama, una medida que resulte útil, probablemente precisa de un filtro digital paso bajo lo cual es relativamente fácil de hacer si utilizas alguna de las herramientas de diseño que hay en la red, otra opción para mitigar en parte el problema es hacerlo en analógico mediante una red RC o un filtro pasa bajos con un operacional, si bien ello no eliminará el ruido generado en la propia placa Arduino.

NOTA: en tiempos pasados, antes de Arduino, uno se leía Elektor, Resistor, Radio Plans y se aprendía electrónica no necesariamente la teoría del filtro Kalman, quizás sólo cacharreabamos.

Ahora con Arduino, se ha vendido la idea de "enchufas y hace cosas", pero no, la electróncia es más compleja. Antes meterse en diseño con micros eran palabras mayores y sin embargo aprendíamos más.

No es cupla tuya, pero la repetición de preguntas como la tuya me sirve para cuestionar muy mucho ese presunto enfoque didáctico de Arduino. Arduino es un producto, un producto con un enfoque claramente comercial, pero que deja a muchos frustrados por el camino como tu, preguntandose porqué no funciona.

Antes, leyendo las revistas y mirando esquemas de dos páginas al meno podías ver que había todo un mundo por aprender.
Ahora se vende la idea de que con subir un sketch ya "hace cosas". Muy comercial, así se han vendido 1M de Arduinos, la gente compite a ver quién tiene el Arduino más grande y largo, el Due, el Yun el Mega pero ¿aprende algo?.....

Además de todo lo dicho por jray puedes hacer lo siguiente.

La media de 10 valores no se hace así. Tú tomas bloques de 10 lecturas y haces la media. En lugar de eso, si vas tomando lecturas que numeraremos de la 1 a la 100, la medida 1 será la media de las lecturas 1 a 10, la medida 2 será la media de las lecturas 2 a 11, la medida 3 será la media de las lecturas 3 a 12, etc. Hay un ejemplo de cómo hacerlo en el IDE, en Ejemplos > Analog > Smoothing. Esto es similar a realizar por software un filtro paso bajos.

Después en tu caso imagino que las variaciones de temperatura reales serán suaves así que las tomas de lecturas del LM35 puedes hacerlas más distantes en tiempo, una lectura cada segundo o cada 10 segundos, lo que veas.

Lo que no entiendo es esa disparidad entre temperatura interior y exterior. La temperatura interior ahora marca 75 ºC, qué es, ¿un horno?

Nota: acabo de ver que en la gráfica se pueden ver los valores y realmente hay mucha variación. Revisa muy bien esas alimentaciones y filtros como te ha dicho jray y después sigue con lo que te he puesto.

Hola de nuevo. Antes de nada gracias a los dos Jray y Cheyenne.
Jray tienes toda la razón en lo que has expuesto, es cierto, pero cada vez se cacharrea menos, cada vez se repara menos y el osciloscopio se usa más de adorno que de otra cosa.
Arduino es más fácil para todo el mundo, está casi todo hecho y solo hace falta ingenio para encontrar una aplcación que te sirva para algo en tu día a día.
Hablemos del tema;
Cuando he probado el circuito con el programa todo va genia, alimentación USB, temperatura sin oscilar, en fín todo correcto, pero cuando lo conectoa al router con alimentador de 9 Vcc y entro en Xively se va a la porra, puede ser ruido, trataré de poner un filtro y ver si se estabiliza, el osciloscopio no puedo llevarmelo a casa para verlo y si traigo el circuito al laboro pues el problema no puedo reproducirlo.
Reconozco que de programación nada de nada pero todo ésto me apasiona y si eres tenaz y con mucho tesón se consigue muchas cosas.
Cheyenne gracias por tu report, sois muy amable, probaré a quitar el ruido, mediré con un Fluke la salida, alimentación en fin...probaré, por que modificar el programa se me va a hacer más arduo.
Un saludo cordial a vosotros y a los escuchas.

Se me olvidaba comentar que solo tengo conectada la sonda exterior,la interior está al aire, por eso da esas medidas tan dispares, la que funciona es la exterior con su LM35 y la LDR que también está conectad y que también oscila, menos pero oscila, con lo bien que salen las pruebas en el banco de trabajo y cuando lo llevas todo a casa y lo pruebas ¡¡¡¡zas¡¡¡¡¡,. A ver si cuando llegue a casa por la tarde sigo probando y dejaré las dos puestas y practicamente pegados los dos LM35, debería de dar casi la misma medida.
Saludos de nuevo.

La media de 10 valores no se hace así. Tú tomas bloques de 10 lecturas y haces la media. En lugar de eso, si vas tomando lecturas que numeraremos de la 1 a la 100, la medida 1 será la media de las lecturas 1 a 10, la medida 2 será la media de las lecturas 2 a 11, la medida 3 será la media de las lecturas 3 a 12, etc. Hay un ejemplo de cómo hacerlo en el IDE, en Ejemplos > Analog > Smoothing. Esto es similar a realizar por software un filtro paso bajos.

Ese es el problema que tienes. Sucede que se genera "ruido de quantificacion". Este aparece al digitalizar una senal analogica. El conversor A/D dependiendo de la resolucion no puede indentificar valores intermedios menores que su maxima resolucion. Usando el LM35 sin amplificacion, la senal varia muy poco para una variacion de temp del orden de las decimas de grado centigrados y el conversor da los valores mas proximos al valor real y esto introduce una variacion inaceptable. La situacion se agrava cuando el rango de medicion se reduce. La idea es que mientras menor sea la variacion del voltage analogico producido por el sensor menor sera la resolucion del sistema al digitalizarla y en consecuencia mayor el ruido de cuantificacion. Una possible solucion es utilizer amplificadores para aumentar la variacion del voltage con la variable que se mide. Otra, es utilizar un filtro digital paso bajo que promedia y elimina los saltos en los valores a la salida del conversor. Lo mejor es hacer las 2 cosas. Busca "moving average digital low pass filter".

Olvide mencionar que cambiar el voltage de referencia AREF tambien puede ayudarte en este caso a reducir el ruido de cuantificacion y aumentar la resolucion del sistema en conjunto.
Suerte

Hola tengo un Arduino con un LM35 pero me esta devolviendo un rango muy amplio de temperatura y quisiera acotarlo un poco entre 69F y 77F. Gracias de antemano

Y cual es el proyecto?
En todo caso es una consulta de software.

Bueno como veo que ya te han sermoneado bastante esta vez no lo haré solo dire un par de cosas.

La primera es que en lo personal no me gusta usar el LM35 la verdad es que es un sensor del cual no me fiaría pero para fines escolares o labores sencillas esta bien ya que su precio es bajo y es fácil de conseguir. Aunque si quieres algo más preciso te sugeriría un DS18b20 si tienes la oportunidad consiguelo y verás que te va mejor, ahora con respecto a tu problema de medición de variables hace tiempo atrás quería hacer algo así y como solo tenia ese mendigo sensor, lo que hice fue ponerme a investigar como solucionar el problema y encontré en un foro ingles que alguien había resuelto su duda con la instrucción "analogReference(INTERNAL)" la cual según arduino dice:

INTERNAL: un built-in de referencia, igual a 1,1 voltios en los ATmega168 o ATmega328 y 2,56 voltios en el ATmega8 (no disponible en el Arduino MEGA ).

haciendo esto pasa lo siguiente en el sensor:

  1. Se "puede" obtener una resolución del sensor de hasta 0.1 grados (Aclaro: El puede, esta entre comillas porque en realidad esto no pasa es más bien una especie de ilusión que creamos con esto más bien es una resolución de 0.5 grados lo cual ya es ganancia).

  2. Se limita el rango de medición del sensor, ya que este sensor solo lográ medir hasta los 150° al usar una referencia de 1.1v se limita a 110° (Si para lo que requieres este sensor no es muy complejo olvida esto).

Ahora a continuación te dejo un código el cual consistia en mostrar la temp en un display lcd 16x2, conectando el sensor al pin A5 del arduino y si la temp pasaba de cierto rango activaba un ventilador y si descendia de cierto rango se apagaba espero y esto te sirva.

Saludos

#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2); //Inicializamos la libreria con el numero de los pines a utilizar


float tempC;    //Aqui se van a guardar los datos de la temperatura del sensor
int lectura;    //Se agina el valor que sea leido por el sensor
int Sensor = A5;  //se declara el pin en el que estara el sensor, refiriendose en ocaciones futuras como variable "sensor"
int ventilador = 6;   //se declara la variable donde se colocara el ventilador
int foco = 7;

void setup()
{
analogReference(INTERNAL);  //usando la referencia interna del arduino, configuramos a este para que opere con 1,1V, limitando la temp. a solo de 0 a 110°C de los 150 que puede medir el LM35
                            //pero sino se hace esto, no se puede obtener la resolucion de 0.1 °C                            
   lcd.begin(16, 2);         // Configuramos el numero de columnas y filas del LCD. 
   lcd.print("Temperatura: ");  //impresion de mensaje
   lcd.setCursor(0,1);
   lcd.print ("      Grados");
   pinMode (6, OUTPUT);           //el pin del ventilador se declarara como salida
   delay (100);                  //se refresca el lcd
}

void loop()
{
lectura = analogRead(Sensor);  //asignacion de lo que se mida en la variable sensor, a la variable lectura
tempC = lectura / 9.31;        //ATENCION, al cambiar la ref analogica del arduino de 5v a 1.1v se tiene que reformular la ec. para obtener la temperatura de tal forma que
                               // se divide 1./1024 = 0.001074V = 1.0742 mV. Si 10mV es igual a 1 grado Celsius, 10 / 1.0742 = ~ 9,31.
                              // Así, por cada cambio de 9,31 en la lectura analógica, hay un grado de cambio de temperatura.
  lcd.setCursor (0,1);
  lcd.print(tempC);      //se imprime la temperatura en el display
  delay (500);           //cada 500ms
  
   if(tempC >25)   //Si la temperatura es mayor que 25  en este caso se encendera el ventilador para disipar calor
  {
    digitalWrite (6, HIGH);
  }
  
  else          //sino se apagará
 { 
    digitalWrite (6, LOW);
 }
  
 if (tempC < 20)
 {
 digitalWrite (7, HIGH);
 }
  
  else
  
  {
  digitalWrite(7, LOW);
  }
}

Hola quiero compartir el código que utilice para medir temperatura con un LM35 utilizando la teoria de filtro de kalman que me funciono realmente bien. Saludos

int sensorPin = A0;   // sensor de temperatura lm35 
int sensorVal;
int temperatura;
float varVolt = 1.12184278324081E-05;  // variante determinada utilizando Excel y lectura de muestras de datos de sensor sin procesar
float varProcess = 1e-8;
float Pc = 0.0;
float G = 0.0;
float P = 1.0;
float Xp = 0.0;
float Zp = 0.0;
float Xe = 0.0;


void setup() {
   Serial.begin(9600);   
}

void loop() {
// put your main code here, to run repeatedly:
  int sensorVal = analogRead(sensorPin);     // lea el valor en el pin analógico 0 y guárdelo en una variable
  float voltage = sensorVal * 5.0 * 100.0 / 1023.0;  // convertir la lectura de ADC a voltaje


  // proceso kalman
  Pc = P + varProcess;
  G = Pc/(Pc + varVolt);    // ganancia kalman
  P = (1-G)*Pc;
  Xp = Xe;
  Zp = Xp;
  Xe = G*(voltage-Zp)+Xp;  // estimación de kalman del voltaje del sensor
  
  temperatura=Xe;
  Serial.println(temperatura);

}