Arduino Pt100 problema de reinicio.

Hola chicos,

Hará ya un tiempo creé un medidor de temperatura para pt100, con el cual tuve algunos problemas y ya comente por el foro. Ahora he querido mejorar el programa y el hardware y me he topado con un problema nuevo, que se me escapa y no veo.

Primero os pongo en situación. El circuito se basa en meter una corriente a través de la pt100 y leer la caida de tensión en sus extremos. El generador de corriente es un lm317 y la caida de tensión se amplifica con un amplificador LM324N.

El hardware parece estar funcionando bien. Y el software también. Pero trasteando me dio por tocar dentro del circuito y ¡tachan! el arduino se reinicia.

Video del circuito funcionando.

En este video vereis como al tocar el circuito se produce un ruido que altera la señal analogica, en este caso la información que se muestra es la resistencia que esta midiendo. Y no se producen reinicios. He visto que el ruido no es muy importante pero aun así me “mosquea”.

Video del circuito fallando

En este otro video, si se produce fallo. ¿Cual es la diferencia? Una línea de código.

// LECTURA DE UN CANAL: devuelve el valor de temperatura y lo guarda en registro apropiado.
int readChannel(int ch)
{
  float analogvoltage, voltage, resistance, temperature;
  analogvoltage=(analogRead(ch+A0)*VREF)/1023.0;
  if ( analogvoltage==0.0 )
  {
    holdingRegs[ch]=0;
    return 0;
  }
  voltage = (analogvoltage-VOFFSET)/GAIN;
  resistance = voltage/IREF;
  //temperature = (resistance-100.0)/0.385;
  //temperature = ((resistance-100.0)*1000.0)/385;
  holdingRegs[ch]=(int)temperature;
  return 1;
}

Este es el código que utilizo en el programa. Básicamente una operación matemática. Leo la tensión de la entrada analógica (si esta es cero, significa que no hay nada enchufado), calculo el voltage de la resistencia, quitandole la tensión de offset y dividiendo por la ganancia del amplificador, calculo la resistencia dividiendo por la corriente y por último aplico la fórmula de la pt100.

T = (R-100)/0.385.

La única diferencia entre el primer video y el segundo es el cálculo de la temperatura y que en holdingRegs guardo la resistencia en el primero, la temperatura en el segundo. El resto de código es exactamente igual. Pero en el primero se reinicia y el segundo si.

Que conste que no se cuelga si no toco y mide la temperatura bien. Pero si toco malo. Y he comprobado que la diferencia de tensión de tocar y no tocar es del orden de 0.02 voltios.

Dejo el esquema de una etapa (el resto son iguales) y todo el código del programa comprimido como attachment.

A ver si alguien me puede dar inspiración porque no veo el problema, no se si es software (si quito esa linea funciona y no se reincia aunque toque) o si es hardware…

ArduPt100.zip (1.97 KB)

Mi primera hipotesis tiene que ver con un watchdog.

Porque no vigilas si se esta disparando y en ese caso que provoca que superes 8 seg?

Tal vez este relacionado con MODBUS y ese ruido.

Te he hecho caso y he hecho unas pruebas:

  1. Comentado las lineas del perro guardian. El resultado es el mismo, se reinicia.

  2. Comentado lo referente a modbus. Igualmente se reinicia.

  3. Para descartar tambíen he comentado el guardado de paramétros en la
    EEPROM tanto como al escribir o leer. Se reinicia.

  4. He comprabado lo siguiente:

// LECTURA DE UN CANAL: devuelve el valor de temperatura y lo guarda en registro apropiado.
int readChannel(int ch)
{
  float analogvoltage, voltage, resistance, temperature;
  analogvoltage=(analogRead(ch+A0)*VREF)/1023.0;
  if ( analogvoltage==0.0 )
  {
    holdingRegs[ch]=0;
    return 0;
  }
  voltage = (analogvoltage-VOFFSET)/GAIN;
  resistance = voltage/IREF;
  resistance = resistance - 100.0
  //temperature = (resistance-100.0)/0.385;
  //temperature = ((resistance-100.0)*1000.0)/385;
  holdingRegs[ch]=(int)resistance;
  return 1;
}

La resistencia la calcula bien, pero al hacer solo la resta, sin dividir, ¡¡se cuelga!!

  1. He pensado que algo no le gusta cuando intento leer con analogRead(ch+A0) y he añadido una línea por cada canal: analogRead(A0), A1, ..., A5. El mismo resultado...

Las pruebas han sido una detras de otra, y lo que se ha comentado en el codigo no se ha vuelto a poner. Asi que se ha quedado el código pelao.

Solo me queda una cosa y es el compilador. Me he dado cuenta de que tengo la versión 1.8.2, y se que de unas versiones a otras el ide comete errores sobretodo con el tratamiento de FLOAT, de hecho la 1.8.1 la descarté porque daba error de compilacion al hacer una resta similar. No tengo en el taller internet así que me bajaré despues la version 1.8.5 y compilaré a ver...

Hola de nuevo,

He cambiado al IDE 1.8.5 y el problema persistia. Así que he seguido investigando a ver por donde podía estár el problema cambiando parte del código, y creo, que he encontrado el problema.

Para mostrar las temperturas en el LCD he usado la función sprintf. La uso bastante con los lcd por la ventaja del formateo de texto. Por ejemplo:

sprintf(line, "%3d %3d %3d", holdingRegs[TCH1], holdingRegs[TCH2], holdingRegs[TCH3]);

Crea una cadena de texto donde si la tempetarua no tiene los digitos necesarios se rellena con espacios, así con solo hacer un lcd.print(line), el texto se queda ajustado en pantalla y no hay que borrar nada en pantalla.

Se ve que si el valor a escribir excede el tamaño de 3, el tamaño de la cadena aumenta, y aquí es donde falla, provocando un puntero "loco" que reinicia el Arduino.

Asi que he cambiado todos los sprintf, por un juego de setCursor, print, y pintar de cadenas de texto vacias. Y, efectivamente no se cuelga.

Ahora viene el problema de que si toco, el valor que muestra es -261 grados... Aunque tocar no es un problema como dice la frase: "no toques, por que tocas". En cambio si lo es a la hora de ruidos. Colocando un transformador de 220 a 110VAC y un taladro de 110V del año la pera, colocandolo cerca, se induce un ruido, que me gustaria poder solucionar...

Bien, entonce el reinicio del Arduino quedó resuelto y ahora te queda el ruido.

Hablamos del segundo video pero como hay mucho ruido de fondo cuesta para nosotros aislar el ruido que hace la placa.

En el segundo video es donde se produce el reinicio y no se nota nada. En el primero aunque no se ve bien, se nota que al tocar se genera una pequeña oscilación en la entrada, del orden de 0.02v que modifica el valor.

Con el motor, aunque de origen distinto, ocurre algo similar. Si pongo el motor cerca hace que la entrada oscile tanto en las entradas sin conectar como en las que hay una resistencia. Es más, si coloco la placa lejos y con un cable “largo” llevo la resistencia al motor, el ruido se transmite a través de ese cable.

Tengo que probar ha delimitar por software la tensión de entrada. Me explico cuando una entrada está al aire la tensión es de 0v por lo tanto, en el código no la leo. Pero si hace un ruido ya no es 0v, sino 0.01 por lo menos, con lo que al calcular la temperatura da alrededor de los -260 grados.

Para medir una temperatura entre 0 y 150 grados (mas o menos el rando a medir) la tensión en la entrada del arduino será de 1.0v a 1.57v. Por lo tanto creo que deberia poner algo así en el código:

int readChannel(int ch)
{
  float analogvoltage, voltage, resistance, temperature;
  analogvoltage=(analogRead(ch+A0)*VREF)/1023.0;
  if ( analogvoltage>=1.0 && analogvoltage<=1.57 )
  {
 voltage = (analogvoltage-VOFFSET)/GAIN;
 resistance = voltage/IREF;
 resistance = resistance - 100.0
 temperature = (resistance-100.0)/0.385;
 holdingRegs[ch]=(int)temperature;
 return (int)temperature;
  }
  holdingRegs[ch]=0;
  return 0;
}

Creo que con eso se filtrarán los ruidos con las entradas al aire. Y debería probar el código.

En una entrada con resistencia colocada parece que el ruido modifica la temperatura dos o tres grados, no es muy importante, pero quizas debiera aplicar a la entrada algún tipo de filtro digital (media, media, etc).

Tal vez un filtro promedio movil. Luis Llamas tiene una librería que permite ajustar todo.
Si mides valores que pueden cambiar el promedio mobil no te quita tiempo..

De todas formas, seguimos sin saber porque ocurre el ruido, no es asi?

La verdad es que no del todo...

Deduzco que al tocar puedo variar un poco la resistencia del circuito e incluso introducir una pequeña corriente electroestática de mi cuerpo. No es problemático, ya que nadie ha de tocar... ni ratones.

El ruido del taladro es diferente. En realidad no dejo el taladro en marcha, si no que enciendo y apago a mala ostia y rápido. Así que hay una bobina que genera un transitorio muy a menudo. Con el taladro en marcha todo el rato no hay ruido en la entrada.

Para que lo de por bueno tiene que pasar la prueba del taladro y el contactor quemado, que por cierto de tanto abusar se acabó quemando del todo y tendré que buscar otro que esté pasado de rosca.

¿Sabias que desde que hablamos de como generar ruido no se me ha jodido ninguna lámpara fluorescente? y mira que tengo muchas.

Jajaja pero eso que cuentas pasa todo el tiempo. Cuando quieres dar por terminado algo, falla por esto o lo otro pero cuando quieres probar a ver si mi ambiente ruidoso me genera una perturbación resulta que ese dia no tiene ganas de provocar problemas.

No he visto grandes realimentaciones salvo en tu AO diferencial. Porque no pruebas con el osciloscopio sobre la salida del LM324 mientras vuelves a insertar la perturbación a ver si es en la salida donde se aprecia. Y si es el caso entonces a pensar en como recortar el ancho de banda de ese AO.
A pesar que me parece que tu filtro pasabajos de salida esta como en 16hz no?

Efectivamente, filtro paso-bajo a 16Hz. Exageré un poco.

La lástima que no tengo un osciloscopio. Estoy a ver si consigo un DSO de esos de 20€ (lo que me permite el presupuesto) y tengo que ir a ver un amigo que tiene cientos (si, no miento, cientos, los colecciona) a ver si me deja alguno.

Bueno, pues recibí el DSO, se lo enchufé y si os digo la verdad no vi alteración de la señal. Ni en la entrada, ni en la salida.

Modifique el programa para que no me de fallos en las entradas que no hay nada, hago un promedio movil del valor de la entrada y he hecho el "ritual de los ruidos":

TEST ARDUPT100

Y por ahora bien. No tengo cuelgues ni nada por el estilo. Se aprecia mas o menos en el video que cambia un grado cada vez que desactivo el conjunto contactor/taladro. Algo que es aceptable.

Si, se que el contactor suena fatal, por que no tengo otro que esté peor, el que tenía antes parecia que se iba a quemar (al final lo hizó :P).

Muy bien!!! en esas condiciones el Arduino no se reinicia, cuando en la mayoría de los casos eso pasa.
Luego tendras que contarnos af fin de reforzar el tema las consideraciones con contactores que has hecho y otras cuestiones para evitar los reinicios.

Solo por que lo pides :smiley:

Después de mucho pelear, leyendo información, foreando, etc. La conclusión a la que hemos llegado siempre es que el ruido que nos reinicia el arduino es la alimentación. Pues lo mejor que podemos hacer es tener una buena fuente de alimentación.

La placa Arduino Uno viene con un regulador muy simple, con un condensador muy pequeño y como no, está pensada para lo que está pensada: aprender.

Lo fundamental para mi es que los 5 voltios de la alimentación estén bien filtrados. Para ello generalemente uso este esquema:

fuente.png

Explicación del circuito:

  • D1 Es un diodo supresor de transitorios. Generalmente yo alimento mis circuitos a 12-13.8V, por lo que pongo diodos de 18V. En caso de entrar un transitorio por la fuente esté debería absorverlo. Generalmente el diodo es bidireccional.
  • D2 Simplemente protege el circuito de conectar la alimentación al revés, además de que reduce en 0.6V la entrada al regulador
  • C5 Es un condensador de filtro, uso una capacidad grande, mínimo 2200uF. Añade un filtrado más al posible rizado de la alimentación
  • R1-C6 Es un filtro paso-bajo, “sintanizado” a una frecuencia baja.
  • C7-C8 Son filtros para el regulador. Un detalle importante es que estos deben estar todo lo cerca posible del regulador
  • D3 Protege el regulador de una tensión excesiva
  • C9 Es otro condensador de filtro. Generalmente suelo usar uno de 470uF aunque en la imagen ponga 220uF
  • C10 ni caso, es un filtro bypass en uno de los micros
  • El regulador es un 7805, no me gustan las fuentes conmutadas…

Como veis es filtro sobre filtro.

Otra parte fundamental es el reset del arduino. Internamente el atmega ya viene con su circuito de reset (resistencia-condensador), pero en un datasheet recomendaban poner el siguiente circuito:

reset.png

La resistencia es de 4k7 no de 10k. Y si bien, es redundante, haya donde fueres haz lo que vieres.

ArduPt100_montado.jpg

En esta foto podeis ver al ArduPt100 con detalle. Observad la fuente, el circuito de reset y la cantidad de condensadores de bypass de 100nF… los compro por centenas y luego me pasaré a los miles.

Luego está el diseño de la placa. Generalmente la placa arduino es para pruebas, siempre me gusta hacer el montaje final en mi propia placa. Intento que la alimentación esté lo mas cerca del microcontrolador posible, evitando todos lo cruces posible, alejando las posibles interferencias de la alimentación y del micro, simpre que se pueda.

No puedo explicar como hago el diseño de la placa en su totalidad. Solo deciros que el diseño está hecho en proteus y a la plancha (lejos queda cuando las hacia a rotulador permanente). No utilizo autorutado si no que lo hago todo a mano. Al proceso lo llamo jugar al tetris: coloco las piezas de una forma, hago las pistas, muevo, rehago, etc. hasta que veo tiene una distribución homogenea… mínimo numero de puentes… Después de unas cuantas placas el proceso es casi automatico porque el cerebro ya está acostumbrado, al principio cuesta.

ArduPt100_pistas.jpg

Como veis, parece que hay un “plano de masa”, generalmente un plano para GND de la placa, pero no siempre. Siempre hago que el programa lo modele, pero si hay etapas de potencia (relés por ejemplo), intento evitar que el plano de masa vaya por él. Aunque desde hace tiempo no utilizó relés que vayan a controlar cargas fuertes, si es así, estos estarán optoacoplados.

No sé que mas os puedo contar.

Fantastico... casi que este comentario tendría que ir en nuestro hilo de problemas de ruido.
Buen trabajo y mejor explicación de para el típico problema de Arduino.

Cuando escuché el RUIDO alrededor de tu Arduino y tu prendiendo y apagando el contactor y el micro como si nada, la pregunta surgió sola.

Gracias x compartir!!