Temperatura con Arduino, sensor DHT11 y python (I)

modulo-sensor-de-tempertura-y-humedad-dht11-para-arduino_MEC-O-3277967849_102012El sensor DHT11 (Módulo de Sensor de Humedad Módulo de Temperatura Digital), y sus variantes, es uno de los sensores más fáciles de manejar para obtener la temperatura con arduino. Gracias a la librería disponible para el, solo tenemos que pedir la temperatura o la humedad y ya la tenemos, sin hacer ninguna otra operación.

Materiales usados

Arduino UNO Arduino UNO
 Sensor DHT 11 Sensor DHT11
protoboard Protoboard
cables_union Cables de conexión

Sensor DHT11

Para conectarlo al arduino es muy sencillo, alimentamos el pin vcc, primero por la izquierda, con 5v desde unos de los pines del arduino, conectamos la masa al más a la derecha, y desde un pin analogico del arduino al 2 pin del sensor, empezando por la izquierda, el 3 pin no hay que conectarlo a nada.

Montaje de un sensor DHT11 en una placa Arduino UNO
Montaje de un sensor DHT11 en una placa Arduino UNO

El código como he dicho antes es muy fácil gracias a la librería existente, solo tenemos que inicializar una variable que nos permita manejar en sensor y poco mas.

Importamos la libreria

#include <DHT.h>

Inicializamos la variable para manejar el sensor DHT11

#define DHTPIN A0     // Indicamos el pin donde conectaremos la patilla data de nuestro sensor DHT11

#define DHTTYPE DHT11   // modelo del sensor que vamos a usar DHT 11 

// Inicializamos la variable
DHT dht(DHTPIN, DHTTYPE);  //Indica el pin con el que trabajamos y el tipo de sensor

Ahora solo tenemos que leer los datos del sensor DHT11 tanto de temperatura como de humedad de la siguiente forma

int iHumedad = dht.readHumidity();  // Guarda la humedad en iHumedad
int iTemepratura = dht.readTemperature(); // guarda la temepratura en iTemperatura

y con esto ya tendríamos tanto el % de la humedad con los grados de temperatura en la escala Celsius.

Pero ahora me queda mandar la información por el puerto serie para luego poderla leer en python.

Para esto creo un registro de 30 caracteres formateado, donde incluyo los dos valores leídos, una cadena variable de caracteres para ajustar la longitud del registro, un carácter separador de los campos “|”  y un campo “|f|” indicando que es el final del registro. quedando de la siguiente forma

HH|TT|XXXXXXXXXXXXXXXXXXXXX|f|

  1. HH seria el valor de la humedad, puede ser 1 0 2 caracteres dependiendo de la humedad que haya.
  2. TT valor de la temperatura, como la humedad el tamaño de este campo puede ser de 1 o 2 caracteres.
  3. X cadena variable, que dependiendo de la longitud de humedad o temperatura puede variar su longitud.
  4. |f| indica que es el final del registro. Para comprobar luego mediante python, que hemos leído correctamente la información enviada.

Si queremos enviar mas información solo tenemos que añadirla incluyendo los separadores. El tamaño del registro lo he establecido en 30 caracteres pero lo podemos variar cambiando la configuración del programa.

// Tamaño del registro a enviar al puerto serie 
int iTamanoCadena = 30;

Y el código seria el siguiente

    // añadimos la humedad y la temperatura, añadiendo al final de cada uno el caracter "|" 
    sResultado = String(h) + "|" + String(t) + "|";
    sEspacios = "";
    / Calculamos cuantos espacios tenemos que crear
    // Le restamos 3 que es el tamaño del campo final
    if (sResultado.length() < (iTamanoCadena - 3))
    {      
      // Creamos la cadena
      for (iContador = 0; iContador < ((iTamanoCadena - 3) - sResultado.length()); iContador ++)
      {
        // le añadimos el caracter que queramos, no vale para nada
        sEspacios += "X";
      }
    }
    // Añadimos el campo de fin de registro
    sResultado = sResultado + sEspacios + "|f|";
    // lo enviamos al puerto serie
    Serial.println(sResultado);
  }

Y con esto ya hemos leído la temperatura y la humedad desde el sensor DHT11 (Módulo de Sensor de Humedad Módulo de Temperatura Digital), y enviada al puerto serie para ser leída por nuestro programa en python.

Código completo.

#include <DHT.h>

#define DHTPIN A0     // Indicamos el pin donde conectaremos la patilla data de nuestro sensor

// Descomenta el tipo de sensor que vas a emplear. En este caso usamos el DHT11
#define DHTTYPE DHT11   // DHT 11 
//#define DHTTYPE DHT22   // DHT 22  (AM2302)
//#define DHTTYPE DHT21   // DHT 21 (AM2301)

// Conecta el pin 1 (el de la izquierda) del sensor a +5V
// Conecta el pin 2 del sensor al pin que has elegido para DHTPIN
// Conecta el pin 4 (el de la derecha) del sensor a GROUND

DHT dht11(DHTPIN, DHTTYPE);  // indicamos en que pin esta conectado el data, y el tipo de sensor

String sResultado, sEspacios;
int iContador;
int iTamanoCadena = 30;

void setup() 
{
  //Inicio comunicacion serie para ver los datos en el ordenador
  Serial.begin(9600); 
  //Iniciamos el sensor
  dht11.begin();
}

void loop() 
{
  int iHumedad = dht11.readHumidity();  //Guarda la lectura de la humedad
  int iTemperatura = dht11.readTemperature();  //Guarda la lectura de la temperatura

  // Comprobamos si lo que devuelve el sensor es valido, si no son numeros algo esta fallando
  if (isnan(iHumedad) || isnan(iTemperatura)) // funcion que comprueba si son numeros las variables indicadas 
  {
    Serial.println("Fallo al leer del sensor DHT 11"); //Mostramos mensaje de fallo si no son numeros
  } 
  else 
  {
    // añadimos la humedad y la temperatura, añadiendo al final de cada uno el caracter "|" 
    sResultado = String(iHumedad) + "|" + String(iTemperatura) + "|";
    sEspacios = "";
    // Calculamos cuantos espacios tenemos que crear
    // Le restamos 3 que es el tamaño del campo final
    if (sResultado.length() < (iTamanoCadena - 3))
    {      
      // Creamos la cadena
      for (iContador = 0; iContador < ((iTamanoCadena - 3) - sResultado.length()); iContador ++)
      {
        // le añadimos el caracter que queramos, no vale para nada
        sEspacios += "X";
      }
    }
    // Añadimos el campo de fin de registro
    sResultado = sResultado + sEspacios + "|f|";
    // lo enviamos al puerto serie
    Serial.println(sResultado);
  }
  // y esperamos 1 segundo para volver a leer los datos del sensor.
  delay(1000);
}

Y con eso terminamos la primera entrega. en la segunda, la lectura de los datos en Python.

Como modificar la ruta de una carpeta Samba en ClearOS

clearos.jpg?w=480ClearOS nos permite montar un servidor basado en Linux fácilmente, especialmente recomendado para pequeñas empresas, que deseen un servidor estable y potente, sin tener que desembolsar una gran cantidad de dinero en licencias, este nos ofrece una forma sencilla de tener un servidor web, ftp, correo, proxy, firewall, y por supuesto, también de Samba.

Samba nos permite compartir carpetas en el servidor para que cualquier ordenador con Windows pueda tener acceso a ellas como si de un servidor Windows se tratase.

La compartición se realiza mediante la opción de Server – File – Flexshare, esta opción nos facilita el poder compartir carpetas del servidor ya sea para el servidor web, ftp o el samba (windows file share). Pero en esta opción no nos permite seleccionar que carpeta queremos compartir, sino que crear una por defecto con las opciones que le hayamos indicado.

Pero esto tiene facil solución, solo tenemos que editar el fichero donde se guarda la configuración de samba, el fichero normal para guardar la configuración del samba es /etc/samba/smb.conf.

sudo nano /etc/samba/smb.conf

Pero si editamos este fichero y nos movemos hasta la parte donde están definidos los recursos que estamos compartiendo, no encontramos las carpetas que acabamos de compartir, si no, que solo encontramos “include = /etc/samba/flexshare.conf”. La palabra “include” lo que hace es incluir el que contiene del fichero, al que hace referencia, dentro de este cuando el sistema lo esta procesando. Por ello para poder modificar la configuración que hemos creado con el Flexshare tendremos que editar ese fichero.

Si abrimos el fichero “/etc/samba/flexshare.conf” nos encontramos la estructura típica de la compartición de recursos con samba.

sudo nano /etc/samba/flexshare.conf

Con la única salvedad de que disponemos ya de todos los parámetros para compartir, sin tener que haber escrito nada. Como lo que queremos es cambiar la carpeta por defecto que nos ha creado Flexshare, vamos a la opción de “path” y cambiamos la ruta por defecto por la que nosotros queramos.

Ruta por defecto que crea Flexshare

path = /var/flexshare/shares/prueba1

Ruta que queremos compartir nostros

path = /home/Public

Ya solo nos queda grabar el fichero y reiniciar el servicio.

Comando para reiniciar el servidor de Samba en ClearOS (o en cualquier servidor Linux)

sudo /sbin/service smb restart

Para pararlo utlizariamos

sudo /sbin/service smb stop

Y para iniciarlo

sudo /sbin/service smb start

Y con esto nuestra carpeta compartida ya es la que nosotros queramos.

Quien dice que Linux es difícil.

Añadir un nuevo disco duro a un servidor Linux

Imagen de un disco duro por dentro
Disco duro por dentro

El añadir un nuevo disco a nuestro sistema basado en Linux parece una tarea difícil, en comparación con Windows, pero es mucho más fácil de lo que pueda parecer. Para hacerlo solo tenemos que seguir los siguientes pasos.

Lo primero que necesitamos es saber en que puerto esta conectado el nuevo disco. Para saber esto, solo tenemos que poner el siguiente comando.

sudo fdisk -l

Este comando nos muestra una lista con todos los disco que tenemos conectado a nuestro sistema y en que puerto esta conectado. El puerto sera una cosa como esto

Si el disco es un serial ata, sera algo como esto, /dev/sda, /dev/sdb, …, /dev/sdx. Si en encambio el disco es del tipo ata, el puerto sera algo como lo siguiente /dev/hda, /dev/hdb,… /dev/hdx.

Sabiendo donde esta instalado, podemos pasar a crear la partición. Para crear la partición utilizaremos de nuevo el mismo comando, pero indicando que disco vamos ha hacer la nueva partición.

sudo fdisk /dev/sdb

Y utilizaremos los siguientes comandos.

  1. “n” .- Para indicar que queremos crear una nueva partición.
  2. “p” .- Para indicar que vamos ha crear una partición primaria, podemos crear hasta 4 particiones primarias.
  3. “1” .- vamos ha utilizar la primera partición primaria.
  4. Pulsamos “Enter” para seleccionar el sector de inicio desde donde vamos ha crear la partición, por defecto, se muestra el primer cilindro libre.
  5. Volvemos ha pulsar “Enter”, para seleccionar todo el disco libre, aquí indicamos el tamaño que queremos que tenga nuestra partición, por defecto se selecciona el ultimo cilindro. Podemos indicar el tamaño en kilobytes (K), megabytes (M) o en gigabytes (G) poniendo el valor  y la letra deseada, o podemos indicar hasta que cilindro queremos que utilice la particón
  6. Con esto ya tenemos configurada nuestra partición. Pulsamos “w” para grabar la partición en el disco.

Una vez que tenemos creada la partición le tenemos que dar formato. Los tipo de formato mas habituales en Linux son ext3 o ext4. Para formatear el disco utilizaremos el siguiente comando.

sudo mkfs -t ext3 /dev/sdb1

Con el parámetro “-t ext3” le decimos al comando que queremos utilizar el formato ext3, si queremos formatearlo como ext4 cambiaremos “ext3″ por “ext4”, si queremos formatearlo como ntfs, pondremos “ntfs” después del parámetro “-t”.

Una vez formateado tenemos que añadir la nueva partición al sistema para que cuando arranque esta unidad se monte automáticamente.

Lo siguiente que tenemos que hacer es crear la carpeta donde queremos que se monte la nueva unidad. La carpeta la podemos crear donde queramos. Para crear la nueva carpeta lo haremos con el siguiente comando.

sudo mkdir /home/disco_nuevo

y le aplicamos los privilegios que queramos, en este caso le doy acceso completo a todos los usuarios.

sudo chmod 777 /home/disco_nuevo

Ahora solo tenemos que conocer el UUID del disco para poder montarlo en el arranca, este dato lo podemos conocer con el siguiente comando.

sudo blkid

Apuntamos el UUID que nos da para ponerlo en el siguiente paso.

Editamos el fichero /etc/fstab para que cuando se inicie el sistema el nuevo disco se monte automáticamente en el directorio que hemos creado. Para ello añadimos la siguiente linea en el fichero

UUID=nnnnnnnn-nnnn-nnnn-nnnn-nnnnnnnnnnnn /home/disco_nuevo ext3 defaults 0 2

Explicación de la linea:

  • “UUID=” El código UUID que hemos copiado antes
  • “/home/disco_nuevo” dirección completa de la carpeta que hemos creado.
  • “ext3” tipo de formato que le hemos dado a la partición.
  • “defaults” opciones de montaje
  • “0” para el comando dump
  • “2” orden en el que se va a controlar el montaje del disco, cada linea que introducimos le pondremos un numero superior al anterior.

Después de esto solo nos queda grabar el contenido del fichero.

Ahora podríamos reiniciar el equipo para verificar que hemos configurado bien el montaje del disco.

Pero también podemos  verificar esto en caliente con los siguientes comandos.

sudo udevadm trigger
sudo mount -a

Con el comando “udevadm trigger” lo que hacemos el forzar la carga de la nueva configuración.

Con el comando “mount -a” montamos los discos con la nueva configuración.

Si no se produce ningún error la configuración es correcta y podemos reiniciar el equipo sin tener ningún miedo a que se produzca un error al cargar la configuración del nuevo disco.

Manejos de hilos (Threads) en python

wpid-python-thread-exitLos hilos o threads ( en ingles) nos permite realizar varias tareas a la vez sin tener que parar la ejecución del hilo principal que llamo a esa tarea. Para poder utilizar los hilos en python, lo primero que tenemos que hacer es añadir la librería que contiene las funciones de manejos de hilos.

# Libreria para el manejo de los hilos
import threading

Lo siguiente es crear la función que queremos que se ejecute ala llamar al hilo. Esto lo podemos hacer de dos maneras creando una nueva clase, o creando una simple función. Lo más habitual es utilizar las clases, por la flexibilidad que nos da. Las funciones las podemos utilizar para hilos que vamos a llamar utilizando un retardo.

Implantación de hilos mediante clases

La clase esta compuerta por varias secciones, Inicio, ejecución, y otras funciones.

Para definir una clase utilizamos el método “class”  seguido del nombre que queramos identificar a la clase y entre paréntesis el tipo de clase, en este caso “threading.Thread”

# Definición de clases
class MiHilo(threading.Thread):

Lo siguiente es definir la función de inicio, en esta función definiremos los objetos, variables, etc. que se van ha utilizar globalmente en la clase, solo serán globales dentro de la clase donde se han declarado.

# Funcion inicio del hilo
def __init__(self, pParam1, pParam2):  
	threading.Thread.__init__(self)  
	self.pParam1 = pParam1
	self.pParam2 = pParam2
	self.stoprequest = threading.Event()

Después de inicializar todas las variables y funciones de la clase, definimos la función “Run” que contiene el código que queremos que se ejecute.

def run(self):

El hilo se ejecutara hasta que termine la ejecución del código que este en esta función.

Con esto ya tememos definido lo básico que necesitamos para que nuestra clase se ejecute.

Para llamar ha esta clase lo  haremos de la siguiente manera.

hMiHilo = MiHilo(pParam1, pParam2)
hMiHilo.start()

Y con esto tenemos nuestro hilo funcionando.