martes, 26 de enero de 2016

Humedad y temperatura en conky con Arduino


Recientemente me ha llegado un sensor DHT22 con el que poder medir la temperatura y la humedad. Partiendo de la idea de Monitorizar en conky sensores de Arduino veamos cómo sacarle jugo a éste sensor.

El DHT22 es un sensor de temperatura y humedad digital bastante preciso pero algo lento comparado con otros.

La conexión de los pines es muy sencilla

DHT22Arduino
15v *
22 *
3N/A
4Ground

* Se debe conectar una resistencia 10k entre el pin 1 y el pin 2, aunque venden algunos sensores con la resistencia incluida, como el que tengo.



Puedes conectar el pin 2 del DHT22 a cualquier otro conector digital de arduino, en el código de más abajo tendrás que indicar a la variable DHTPIN el número de pin usado.

Al poder enviar más datos por lectura a través del puerto serie es mejor estructurar la información usando algún estándar. En este caso, se implementa JSON, un formato ligero para intercambio de datos.

Es necesario instalar las librerías "DHT sensor library" y "ArduinoJson" desde el administrador de librerías del Arduino IDE.

Partiendo del ejemplo DHTtester se ha modificado para quedar así:
#include "DHT.h"
#include "ArduinoJson.h"

#define DHTPIN 2     // what digital pin we're connected to

// Uncomment whatever type you're using!
//#define DHTTYPE DHT11   // DHT 11
#define DHTTYPE DHT22   // DHT 22  (AM2302), AM2321
//#define DHTTYPE DHT21   // DHT 21 (AM2301)

// Connect pin 1 (on the left) of the sensor to +5V
// NOTE: If using a board with 3.3V logic like an Arduino Due connect pin 1
// to 3.3V instead of 5V!
// Connect pin 2 of the sensor to whatever your DHTPIN is
// Connect pin 4 (on the right) of the sensor to GROUND
// Connect a 10K resistor from pin 2 (data) to pin 1 (power) of the sensor

// Initialize DHT sensor.
// Note that older versions of this library took an optional third parameter to
// tweak the timings for faster processors.  This parameter is no longer needed
// as the current DHT reading algorithm adjusts itself to work on faster procs.
DHT dht(DHTPIN, DHTTYPE);

const int ledPin = 13;
StaticJsonBuffer<44> jsonBuffer;
JsonObject& root = jsonBuffer.createObject();
double threshold = 20;

void setup() {
  pinMode(ledPin, OUTPUT);
  Serial.begin(115200);
  while (!Serial) {
    // wait serial port initialization
  }

  dht.begin();
}

void loop() {
  // Wait a few seconds between measurements.
  delay(2000);

  // Reading temperature or humidity takes about 250 milliseconds!
  // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
  float h = dht.readHumidity();
  // Read temperature as Celsius (the default)
  float t = dht.readTemperature();

  // Check if any reads failed and exit early (to try again).
  if (isnan(h) || isnan(t)) {
    return;
  }
  // Compute heat index in Celsius (isFahreheit = false)
  float hic = dht.computeHeatIndex(t, h, false);

  if (Serial.available() > 0) {
    Serial.read();
  
    root["sensor"] = DHTTYPE;
    root["temperature"] = t;
    root["humidity"] = h;
    root["hic"] = hic;

    root.printTo(Serial);
    Serial.println();
  }
  
  if (hic > threshold) {
    digitalWrite(ledPin, HIGH);
  } else {
    digitalWrite(ledPin, LOW);
  }
}

He eliminado las referencias a grados Fahrenheit del ejemplo.

En caso de petición, devuelve en formato JSON el nombre del sensor, la temperatura, la humedad y la sensación térmica. De ésta forma:

{"sensor":"dht22","temperature":21.30,"humidity":54.40,"hic":20.91}

Recuerda que modificando la variable threshold puedes especificar a qué temperatura deseas que se encienda el LED. Aprovechando la librería del sensor, ahora se compara con la sensación térmica calculada para un resultado más confortable. Funciona independientemente de si la placa está conectada a un ordenador.

Por el lado del ordenador, al recibir más datos, hay que modificar un poco el script. Ahora guarda los tres datos en tres archivos distintos:

# nano /usr/bin/arduinosensors.py
#! /usr/bin/python

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

    with open("/tmp/arduino_ttyACM0_temperature", "w") as ft:
        # At this point, myfile has been opened for writing,
        # deleting all existing content.
        ft.write(str(temp['temperature']))
    with open("/tmp/arduino_ttyACM0_humidity", "w") as fh:
        fh.write(str(temp['humidity']))
    with open("/tmp/arduino_ttyACM0_hic", "w") as fhic:
        fhic.write(str(temp['hic']))
Para ver la temperatura, humedad y/o sensación térmica en Conky sólo hay que añadir la línea correspondiente:
${head /tmp/arduino_ttyACM0_temperature 1}
${head /tmp/arduino_ttyACM0_humidity 1}
${head /tmp/arduino_ttyACM0_hic 1} 
en el fichero de configuración.

He notado que al volver de una suspensión del sistema el script arduinosensors.py (iniciado con Systemd) a veces deja de comunicarse con la placa arduino, en conky aparecen permanentemente las mismas cifras. De momento se soluciona reiniciando el servicio:
$ systemctl restart arduinosensors.service 
Es muy fácil imaginar que ésto puede terminar en una estación meteorológica, aunque tengo ideas más locas que iré mostrando.

Y a ti, ¿qué magnitud te gustaría medir?

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