jueves, 7 de enero de 2016

Monitorizar en conky sensores de Arduino


Bendita estufa de butano para el invierno, al menos hasta llegar a la solución definitiva. Pero al carecer de termostato estará encendida indefinidamente hasta que nos estemos asando como pollos. Cómo saber cuándo apagarla o volverla a encender?

Podría estar mirando el termómetro periódicamente pero el que tengo se quedó la aguja atascada. Así que rebuscando he rescatado un Arduino Uno, un sensor de temperatura y un LED.

Dado que mi sensor de temperatura es un 4.7k he usado un código que he encontrado en el foro de arduino como base. Para un sensor 10k se puede usar el código del playground. El esquema eléctrico también está indicado.

Ya puestos, he modificado un poco el código para que un led se encienda al alcanzar la temperatura deseada. Quedando de la siguiente manera a partir de la línea #define ThermistorPIN 0
#define ThermistorPIN 0   // Analog Pin 0
const int ledPin = 13;
double temp;
double threshold = 18;

void setup() {
  // initialize the LED pin as an output:
  pinMode(ledPin, OUTPUT);
  Serial.begin(115200);
}

void loop() {
  temp = Thermistor(analogRead(ThermistorPIN));         // read ADC and convert it to Celsius
  if (Serial.available() > 0) {
    Serial.read();
    printDouble(temp, 3);    // display Celsius
    Serial.println("");                                   // End of Line
  }
  
  // if the analog value is high enough, turn on the LED:
  if (temp > threshold) {
    digitalWrite(ledPin, HIGH);
  } else {
    digitalWrite(ledPin, LOW);
  }
  delay(1000);                                           // Delay a bit... for fun, and to not Serial.print faster than the serial connection can output
}
Además, para poder obtener los datos desde el ordenador, se devolverá la temperatura sólo en caso de petición. Tampoco hace falta que esté enviando la información constantemente aunque el ordenador esté apagado. En este caso el LED serviría de guía.

Modificando la variable threshold puedes especificar a qué temperatura deseas que se encienda el LED.

Con esto, la parte de arduino ya está lista, puede funcionar sin necesidad de estar conectado al ordenador y da información suficiente.

Pero se puede ir más allá, por ejemplo, monitorizando la temperatura a través de Conky. Para ello, primero había creado un simple programa en python que se conectaba al puerto serie, hacía una petición y devolvía la temperatura. Al ejecutarlo con conky al principio funcionaba bien, bueno, el LED parpadeaba cada vez que se establecía la conexión. Pero en algún momento empezó a quedarse congelado esperando la respuesta.

Parece ser que si la conexión al puerto serie no ha terminado de establecerse al ejecutar un readline() se queda en tieso. Por suerte tiene fácil solución, se pausa el programa un par de segundos y la lectura de los datos ya funciona correctamente.

Pero esto lleva a otro problema, tengo configurado Conky con un intervalo de actualización de 1 segundo pero tendrá que esperar 2 segundos para mostrar la información. Tampoco es que sea un trauma, pero para no interferir en el funcionamiento de Conky he optado por cachear los datos. Ahora, el script que lee la temperatura abre la conexión una sola vez y actualiza periódicamente los datos al arrancar el sistema gracias a systemd. El script requiere permisos de ejecución.
# nano /usr/bin/arduinosensors.py
#! /usr/bin/python

import serial
import time
ser = serial.Serial('/dev/ttyACM0', 115200)
time.sleep(2)
while True:
    ser.write(b't')
    temp = ser.readline().decode("utf-8").strip()

    with open("/tmp/arduino_ttyACM0", "w") as f:
        f.write(temp)

    time.sleep(1)

Sólo hay que ajustar el puerto al que debe conectarse, en mi caso /dev/ttyACM0. Cada segundo guarda la temperatura en un fichero en /tmp que al estar montado como tmpfs evita hacer escrituras al disco.

Iniciar el script con systemd es muy fácil:
# nano /etc/systemd/system/arduinosensors.service
[Unit]
Description=Arduino Sensors

[Service]
ExecStart=/usr/bin/arduinosensors.py

[Install]
WantedBy=multi-user.target
# systemctl start /etc/systemd/system/arduinosensors.service
# systemctl enable /etc/systemd/system/arduinosensors.service
Y para terminar, para ver la temperatura en Conky sólo hay que añadir:
${head /tmp/arduino_ttyACM0 1}
en el fichero de configuración.

De momento parece que funciona, tampoco pretendía encontrar una solución perfecta pero como seguro que hay mil formas más de plantearlo tampoco hace falta estancarse aquí.

¿Se te ocurre alguna forma de mejorarlo?

Si lo deseas te puedo enviar un correo electrónico cada vez que publique algo en Mi backup tan sólo debes inscribir tu dirección de correo. Tú dirección de correo será confidencial y sólo te enviaré información que crea que te puede interesar.

No hay comentarios:

Publicar un comentario