sábado, 26 de abril de 2014

Interrupciones en Arduino

Fuentes:

Las interrupciones son sucesos que pueden ocurrir en cualquier momento por lo que no podemos prever exactamente cuando detectarlas. Por ejemplo, podemos colocar un sensor en el frente de un vehículo para que detecte a distancia los posibles obstáculos que encuentre en su camino y lo informe a la tarjeta cambiando el estado de un Pin.

Arduino Uno tiene dos de los pines específicos, el Pin 2 y el Pin 3, capaces de detectar interrupciones en cualquier instante, independientemente de lo que en ese momento esté haciendo la función principal “loop”, Cuando Arduino detecta un cambio en el estado de uno de esos pines puede parar el funcionamiento del bucle “loop”donde se encuentre y lanzar una función asociada a esa interrupción inmediatamente, para continuar posteriormente el proceso del bucle “loop” desde donde lo parará.

¿Qué necesitamos para gestionar una interrupción?

volatile
En primer lugar definir previamente una variable del tipo “volatile” . Esta variable se caracteriza por que su valor pueda ser modificado por algo fuera de la sección del código en el que aparece, o sea en una función concurrente. asociadas a interrupciones, tambien llamadas rutina de servicio de interrupción (interrupt service routine).

La palabra clave “volatile” conocida como variable clasificada (qualifier), se utiliza  delante de un tipo de datos, para modificar la forma en que se va a guardar el valor de la variable en el procesador. Una variable normal, una vez modificada por el programa en la memoria principal RAM, muy escasa y cara, se almacena en una dirección de memoria, mas abundante y barata ROM. Declarar un variable como “volatile” ordenamos al compilador que mantenga permanentemente presente el valor de la variable en la RAM y nos la suministre desde un registro de almacenamiento, ROM. 

La sintaxis de “volatile” es: Volatile definición_de_variable

“volatile” indica que la variable que definimos a continuación la cambie siempre que se produzca una interrupción

attachInterrupt


En segundo lugar hay que informar a Arduino que utilizaremos la interrupción lo que hacemos como es habitual en función “setup” con la instrucción “attachInterrupt”. Este mandato especifica la función a invocar cuando se produce una interrupción externa. La mayoría de las placas Arduino tienen dos interrupciones externas: Las número 0 (en el pin digital 2) y la 1 (en el pin digital 3). Arduino Mega tiene otras cuatro: Las número 2 (pin 21), 3 (pin 20), 4 (pin 19) y 5 (pin 18).

La sintaxis de “attachInterrupt” es: attachInterrupt(nint, nfuncion, modo) donde:

“attachInterrupt” avisa a Arduino que vamos a utilizar interrupciones
“nint” número de interrupción. 0 si utilizamos el pin2, 1 si utilizamos el pin 3 “
“nfuncion” nombre de la función que invocamos.
“modo” es el acontecimiento que provoca la interrupción: Los acontecimientos contemplados son:
  • LOW (bajo)dispara la interrupción cuando el pin pase a valor bajo (LOW).
  • CHANGE (cambio) dispara la interrupción cuando el pin cambia de valor .
  • RISING (aumentar) dispara la interrupción cuando el pin pasa de LOW a HIGH
  • FALLING (caer) dispara la interrupción cuando el pin pasa de HIGH a LOW


interrupt service routine

Por último tendremos que definir lo que se hace cuando se dispara la interrupción, o sea la rutina de servicio de interrupción o en inglés interrupt service routine.

Esta rutina no admite ni parámetros de entrada ni devuelve nada pues los valores que pudiéramos pasarla a no ser de tipo volatile no están presentes en la memoria RAM del procesador cuando comienza inesperadamente su actuación y por otra parte no tendría sentido entregar parámetros que fuera a utilizar alguien fuera de esta función sin saber si van a existir o no. Por tanto debe ser del tipo void nfuncion () como lo son por ejemplo las funciones “setup” y “loop” que tampoco tienen parámetros ni devuelven nada.

También hay que tener al programarla que los mandatos relacionados con el transcurso del tiempo, no funcionan, pues el ordenador de forma virtual ha interrumpido precisamente el paso del tiempo para “congelar” la función “loop”. Por ello las interrupciones son esencialmente atemporales, y dentro de ellas no funcionan correctamente ni el mandato “delay” que para el programa durante el tiempo que se le indique, ni el mandato “millis” que devuelve el tiempo en milisigundos en que ha estado funcionando Arduino desde que arranco por última vez.

Tambien puede ocurrir y hay que tener en cuenta, que si se envían datos serie desde el exterior, por ejemplo del PC a Arduino, cuando se encuentra “ocupado” con una interrupción, pueden perderse, pues el ordenador está entonces volcado a hacer “otra cosa”, lo que mande hacer la interrupción.

Ejemplo:

int pin = 13; 
volatile int estado = LOW; 
void setup() { 
  pinMode(pin, OUTPUT); 
 attachInterrupt(0, parpadeo, CHANGE); 
}

void loop() { 
  digitalWrite(pin, estado); 

void parpadeo() { 
  estado = !estado; 
} 

Otros comandos:

interrupts()
Descripción: Activa las interrupciones (después de haberlas desactivado con noInterrupts(). 
Parámetros: ninguno
Devuelve: no devuelve nada

noInterrupts()
Descripción: Desactiva las interrupciones (pueden reactivarse usando interrupts()).

Parámetros: ninguno
Devuelve: no devuelve nada

detachInterrupt(interrupt)
Descripción: Apaga la interrupción dada.
Parámetros: interrupt: el número de interrupción a invalidar (0 o 1).

viernes, 18 de abril de 2014

Tamagochi arduino

Este Tamagotchi de escritorio dispone de todas las funciones que hicieron tan populares aquellos aparatos de los 90 y toma vida gracias al uso de una placa Arduino y una matriz de luces LED.





Si te gustaría hacer la tuya propia, puedes hacerlo siguiendo el tutorial.

Visto en gizmologia.com

jueves, 17 de abril de 2014

Proyecto Arduino-Android: Temperatura y Humedad

En este proyecto, el objetivo es medir la temperatura y la humedad relatica utilizando arduino y mostrar los resultados en un dispositivo android. 

Para medir la temperatura y la humedad relativa utilizo el módulo DHT-11 y para la conexión con el dispositivo Android utilizo el módulo HC-06

Para la programación de mi placa Arduino UNO utilizaré el IDE de Arduino y para programar el dispositivo android utilizaré App Inventor 2.

El esquema que voy a utilizar es el siguiente:


Nota: el módulo DHT11 que utilizo dispone únicamente de 3 pins, VCC-Data-GND.
Las conexiones son sencillas: Los pines de alimentación (VCC) de los módulos HC-06 y DHT-11 se conectan a los pines 3 y 7 de Arduino respectivamente. Los pines TxD y RxD del HC-06 se conectan a los pines 0 y 1 (RxD y TxT) de Arduino. El pin OUT del DHT-11 se conecta al pin 6 de Arduino

El código de Arduino es el siguiente:

//Añadimos la libreria con la cual trabaja nuestro sensor de temperatura/humedad
#include "DHT.h" 
//Definimos el pin 3 de arduino para alimentar el módulo Bluetooth HC-06
#define PinVccHC06 3 
//Definimos el pin 7 de arduino para alimentar el módulo de Temperatura DHT-11
#define PinVccDHT11 7 
//Definimos el pin 6 de ardunino para conectar el pin OUT del módulo DHT
#define PinOutDHT 6
#define TypeDHT DHT11 //Definimos el tipo de sensor de temperatura
//Configura el pin con el que trabajamos y el tipo de sensor
DHT dht(PinOutDHT, TypeDHT); 

float h,t; //variables de humedad y temperatura
char dato;
String readString;

void setup(){
  //por defecto, el módulo HC-06 viene configurado 9600 N 8 1
  Serial.begin(9600); 
  pinMode(13,OUTPUT);
  pinMode(PinVccHC06,OUTPUT);
  pinMode(PinVccDHT11,OUTPUT);
  //Alimentamos el módulo HC-06 a 0v
  digitalWrite(PinVccHC06,LOW); 
  //Alimentamos el módulo DHT-11 a 0v
  digitalWrite(PinVccDHT11,LOW); 
  digitalWrite(13,HIGH);
  delay(1000);
  //Activa los sensores
  digitalWrite(13,LOW);
  //Alimentamos el módulo HC-06 a 5v
  digitalWrite(PinVccHC06,HIGH);
  //Alimentamos el módulo DHT-11 a 5v 
  digitalWrite(PinVccDHT11,HIGH); 
  delay(1000);
  dht.begin(); //Inicializamos el módulo DHT
}
//Antes de ejecutar el programa, hay que vincular el dispositivo android con el módulo de bluetooth HC-06
//La clave por defecto del módulo HC-06 es 1234

void loop(){
  //Comprobamos que los valores de t y h son´números. Si es un error enviamos un código de error
  LeerDato();
  if (readString.length() > 0){
    if (readString == "Temp"){
      EnviarTemperatura();}
    if (readString == "Hum"){
      EnviarHumedad();}     
  }
}

void LeerDato(){
  readString ="";
  while(Serial.available()) {
    delay(10);
    if (Serial.available() > 0) { //¿Hay datos en el buffer?
      dato = Serial.read(); //Lee el dato
      readString += dato; //Lo almacena en readString
    }
  }
}

void EnviarTemperatura(){
  t = dht.readTemperature(); //Lee la temperatura
  if (isnan(t)){ //Comprueba que el dato es un número
    Serial.print("Error");
  } else {
    Serial.print(t); //Envía el dato por el puerto serie
  }
}

void EnviarHumedad()
{
  h = dht.readHumidity(); //Lee la humedad
  if (isnan(h)){ //Comprueba que el dato es un número
    Serial.print("Error");
  } else {
    Serial.print(h); //Envía el dato por el puerto serie
  }
}

De forma resumida, el programa realiza las siguientes tareas:
  1. Carga la librería para programar el sensor de temperatura.
  2. Define en que pins y que modelo de sensor de temperatura vamos a utilizar
  3. En setup inicializamos tanto el puerto serie que se comunicará con el sensor bluetooth como el sensor de temperatura. Además, alimentamos ambos módulos.
  4. En loop básicamente llamamos al procedimiento de leer un dato por el puerto serie. Si la lectura es correcta comprobamos si nos solicitan la temperatura o la humedad, realizamos la medición  y enviamos el dato por el puerto serie.
El diseño de la aplicación es el siguiente:


El código utilizado es el siguiente:

Variables utilizadas:

Nota: MAC es la dirección de mi módulo bluetooth

Inicializamos:

Conexión Bluettooth:


Lectura de los datos (TimeInterval clock 1 : 1000):


La parte más complicada de entender es seguramente la lectura de los datos. Utilizo la variable Enviar para saber cuando debo enviar la orden de lectura de la temperatura o la humedad y cuando debo esperar a recibir la lectura de dichos datos enviada por la placa arduino. Por otra parte, la variable T la utilizo para alternar la lectura de la temperatura y de la humedad.

Recepción del Texto enviado por Arduino:


Desconexión del módulo Bluetooth:


Salir y cerrar el programa:


Para más información sobre programación en app inventor puedes consultar mi blog appinventoramuete. En la entrada Cliente Bluetooth podrás aprender a utilizar este componente.

Descargas:

martes, 15 de abril de 2014

El puerto serie y Arduino

Fuentes: 

Comunicación Serial

Arduino posee como principal característica la habilidad de comunicarse con nuestra computadora a través del puerto serie. Esto se conoce como comunicación serial. Debido a que el uso de este puerto ha quedado un poco en desuso a favor de la tecnología USB, Arduino cuenta con un convertidor de Serial a USB que permite a nuestra placa ser reconocida por nuestra computadora como un dispositivo conectado a un puerto COM aún cuando la conexión física sea mediante USB.

Arduino IDE nos proporciona una herramienta que nos permite enviar y visualizar los datos que se manejan a través del puerto Serie. Dicha herramienta se conoce como Monitor Serial y se puede encontrar en el menú de herramientas, en la opción “Monitor Serial”. Es la forma más simple que existe para establecer la comunicación serial con Arduino.


A través de esta ventana se puede enviar o recibir información utilizando el puerto serie. Nótese que para poder abrir esta ventana es necesario que tengamos nuestra placa Arduino conectada a nuestra PC mediante USB.

Para iniciar la comunicación serial con Arduino utilizando el Monitor Serial debemos establecer algunos comandos en el Arduino IDE y luego subirlos al microcontrolador.

Comandos:El código es el siguiente:

Serial.begin(9600); En la función Setup inicializamos la comunicación serial. El 9600 indica el baud rate, o la cantidad de baudios por segundo que manejará el puerto serie. Se define baudio como una unidad de medida, usada en telecomunicaciones, que representa el número de símbolos por segundo en un medio de transmisión analógico. Para nuestros propósitos utilizaremos comúnmente el número 9600 aunque puede utilizar estas velocidades: 300, 1200, 2400, 4800, 9600, 14400, 19200, 28800, 38400, 57600 o 115200. Sin embargo, puedes especificar otras velocidades - por ejemplo, para comunicarte a través de los pines 0 y 1 con un componente que requiere una velocidad de transmisión en particular

Serial.println('caracteres'); Cuando usamos println le estamos diciendo al microcontrolador que tendrá que imprimir un caracter a través del puero serie. Hay otros métodos como Serial.print o Serial.write que nos sirven para imprimir o escribir en el puerto serie, sin embargo la función println agrega un salto de línea cada vez que se envía un dato, lo que es provechoso para nosotros en algunos casos, especialmente cuando utilizamos el monitor serial. En la función println se debe establecer lo que se quiere imprimir entre paréntesis y con comillas. En este caso vamos a imprimir el caracter ’1′. Mediante la sintaxis Serial.println(val, format) se puede especificar el número de la base (para números enteros) (por ejemplo DEC) o el número de posiciones decimales (para números de coma flotante o tipo "float")

if (Serial.available()>0){...} Cuando halla datos disponibles para leer en el puerto serie, el método Serial.available() tendrá un número mayor a cero (>0) por lo que cumplirá con la condición establecida en la estructura selectiva y el programa procederá a ejecutar los comandos que estén dentro de las llaves ({}) del if. De forma general, esta función devuelve el número de bytes (caracteres) disponibles para ser leídos por el puerto serie. Se refiere a datos ya recibidos y disponibles en el buffer de recepción del puerto (que tiene una capacidad de 128 bytes).

Serial.write(); Escribe datos binarios en el puerto serie. Estos datos se envían como un byte o una serie de bytes; para enviar los caracteres que representan los dígitos de un número usar funcion print() en su lugar.
Sintaxis:
  • Serial.write(val); val: un valor para enviar como un solo byte   
  • Serial.write(str); str: una cadena 'string' para enviar como una serie de bytes 
  • Serial.write(buf, len); buf: un 'array' para enviar como una serie de bytes y len: longitud del búfer

input=Serial.read(); Cuando entre en la estructura selectiva, a la variable input (al principio del  código se declara una variable tipo int llamada inputse le asignará un valor que se lea desde el puerto serie mediante el método Serial.read(). Siempre que necesitamos leer algo lo hacemos mediante este método (devuelve -1 si no hay datos disponibles).

Nota: Cuando se intenta imprimir un entero (1,2,3,4,5…), el método Serial.println() imprimirá  dicho entero en formato ASCII.


Serial.end(); Desactiva la comunicación serie, permitiendo a los pines RX and TX ser usados como entradas o salidas digitales.

Serial.flush(); Vacía el búfer de entrada de datos en serie. Es decir, cualquier llamada a Serial.read () o Serial.available () devolverá sólo los datos recibidos después la llamada más reciente a Serial.flush ().


Conectado el puerto serie con el exterior

Arduino dispone de un puerto serie que, en la placa Arduino UNO, está localizado en los pins 0 y 1 (Rx, Tx).



Nota: La placa Arduino Mega tiene tres puertos adicionales de serie: Serial1 en los pines 19 (RX) y 18 (TX), Serial2 en los pines 17 (RX) y 16 (TX), Serial3 en los pines 15 (RX) y 14 (TX).

Podemos utilizar otros pines de Arduino para la transmisión serie si añadimos al programa la la librería “SoftwareSerial.h” que viene incluida en el IDE de Arduino. Con esta librería podremos usar, por ejemplo, los pines 2 y 3 como RX y TX. Al ser un puerto "software" la velocidad máxima que se puede utilizar es de 9.600 bps

Ejemplo:

#include "SoftwareSerial.h"
SoftwareSerial blue(2, 3);
int pot=0;

void setup(){
  blue.begin(9600);
  blue.println("Conectado");
}
void loop(){
 pot=analogRead(0);
  blue.println(pot);
  delay(1000);
}

Nota: Actualmente, en realidad, se suele usar una extensión del código ASCII (llamada Unicode) que permita el uso de caracteres no incluidos en la tabla original, y que permita representar caracteres como las Ñ, o acentos para el español, pero también alfabetos distintos como el Kanji chino o el alfabeto cirílico. Y este es el motivo por el que podéis leer las letras chinas o rusas en las páginas de internet de estos países.

Para mostrar por ejemplo la o acentudad ó habría que utilizar:

Serial.println(char(243));
 
 

Módulo de Bluetooth HC-06

Fuente: diymakers.es

El Bluetooth es un estándar de comunicación inalámbrica que permite la transmisión de datos a través de radiofrecuencia en la banda de 2,4 GHz. Existen muchos módulos Bluetooth para usarlos en nuestros proyectos de electrónica, pero los más utilizados son los módulos de JY-MCU, ya que son muy económicos y fáciles de encontrar en el mercado. Son módulos pequeños y con un consumo muy bajo que nos permitirán agregar funcionalidades Bluetooth a nuestro Arduino. Estos módulos contienen el chip con una placa de desarrollo con los pins necesarios para la comunicación serie.

Existen dos modelos de módulos Bluetooth: el HC-05 que puede ser maestro/esclavo (master/slave), y el HC-06 que solo puede actuar como esclavo (slave). La diferencia entre maestro y esclavo es que en modo esclavo es el dispositivo quien se conecta al módulo, mientras que en modo maestro es el módulo quien se conecta con un dispositivo.

Físicamente, los dos módulos son muy parecidos, solo varían algunas conexiones. Los pins del módulo HC-06 son los siguientes:
  • Vcc: Alimentación del módulo entre 3,6V y 6V.
  • GND: La masa del módulo.
  • TXD: Transmisión de datos.
  • RXD: Recepción de datos (Precaución: Algunos módulos no permiten en su pin RX mas de 3.3v. En mi caso, he adquirido un módulo que admite hasta 5 v.)

Comandos AT

Los comandos AT son un tipo de comandos que sirven para configurar el módulo Bluetooth a través de un microcontrolador, un ordenador o con cualquier dispositivo que posea una comunicación serie (Tx/Rx). Son unas instrucciones que nos permiten cambiar los baudios del módulo, el PIN, el nombre, etc. Para usar los comandos AT el módulo Bluetooth no debe estar vinculado a ningún dispositivo (led rojo del módulo parpadeando). Según las especificaciones del módulo, el tiempo que se tiene que respetar entre el envío de un comando AT y otro tiene que ser de 1 segundo. Si se envía un comando AT y en menos de un segundo se envía otro, el módulo no devuelve respuesta.


Los parámetros por defecto del módulo HC-06 son los siguientes:
  • Baud rate: 9.600 N 8 1
  • ID: Linvor
  • Password: 1234
Los comandos AT que admite el módulo HC-06 son los siguientes:




Lo normal es conectar el módulo HC-06 a los pines del Arduino 0 y 1 (RX y TX) y establecer una conexión serie:

Serial.begin(9600);

Luego, utilizaremos los métodos estándar para trabajar con el puerto serie (ver el siguiente enlace)


Fecha y Hora para el Arduino

Interesante artículo publicado en diverteka sobre el módulo RTC1307:

"Mostramos la forma de dotar a nuestro Arduino de “fecha y hora” de una manera sencilla. ¿Qué necesitamos? … pues tan solo nuestra placa Arduino y un módulo RTC (Real Time Clock) que incorpora como núcleo de su operativa el chip DS1307, además del conexionado de los pocos componentes periféricos que precisa incorpora – y esto si es interesante – la pila tipo botón que se encargará de que guarde fecha y hora aunque desconectemos el módulo del Arduino"


Más información: combustory.com

viernes, 11 de abril de 2014

Sensores de temperatura y humedad DHTxx

Los sensores DHT11 o DHT22 son unos pequeños dispositivos que nos permiten medir la temperatura y la humedad relativa. A diferencia de otros sensores, éstos los tendremos que conectar a pines digitales, ya que la señal de salida es de este tipo. Entre las desventajas, el DHTxx solo lee enteros, no podemos leer temperaturas con decimales por lo que tenemos que pensarlo muy bien a la hora de utilizar este sensor para trabajos en los que se requieran lecturas precisas de temperatura y/o humedad. Llevan un pequeño microcontrolador interno para hacer el tratamiento de señal.

¿Cómo funcionan?

Los DHTxx (xx por “11″ o “22″) se componen de un sensor capacitivo para medir la humedad y de un termistor. Ambos sensores están calibrados por lo que no es necesario añadir ningún circuito de tratamiento de señal. Esto sin duda es una ventaja porque nos simplifica las cosas en la protoboard. Además, como los DHTxx han sido calibrados en laboratorios y presentan una gran fiabilidad.


Ambos sensores funcionan con ciclos de operación de duración determinada (1s en el caso del DHT11 y 2s en el caso del DHT22). En este tiempo, el microcontrolador externo (Arduino por ejemplo) y el microcontrolador que lleva integrado el sensor, se hablan entre sí de la siguiente manera:

  • El microcontrolador (Arduino) inicia la comunicación.
  • El sensor responde estableciendo un nivel bajo de 80us y un nivel alto de 80us.
  • El sensor envía 5 bytes.
  • Se produce el handshaking.

¿Cuál elijo, DHT11 o DHT22?

Tanto DHT11 como DHT22 son geniales para empezar a jugar con Arduino o si estas pensando en alguna aplicación que requiera medir humedad y/o temperatura. Son además muy fáciles de conectar y sólo requieren de un pin de Arduino. Sin embargo, el DHT22 tiene rangos de medida más amplios y mayor resolución, a cambio de resultar algo más caro.

A modo resumen, las características de cada uno de los sensores las resumimos en la siguiente tabla:


Por lo que se refiere al pinout, los pines del DHT11 y del DHT22 siguen el mismo orden:




En la siguiente figura mostramos la conexión entre un Arduino Uno y un DHT22 sobre la protoboard:


Del montaje realizado, destacamos que no utilizamos el pin 3, y que La resistencia (10 K en este caso) tiene que conectarse entre la alimentación y el pin de salida de datos. También es interesante ver que, aunque el sensor entrega señales de naturaleza analógica como son la humedad y la temperatura, estas señales las leemos por un pin digital de Arduino. Este hecho revela que en un solo pin somos capaces de obtener dos lecturas, y nos damos cuenta de la ventaja que aportan las señales digitales frente a las analógicas: menos cables, más simplicidad en los montajes.

Yo he usado un módulo que adquirí a un precio muy económico y que me ahorra estar poniendo la resistencia de pull-up. Os pongo una imagen del módulo:
De izquierda a derecha, el uso de los pines es el siguiente
  • VCC
  • Out
  • GND
Programación de Arduino

Hay tutoriales que explican como leer este sensor sin dicha librería, sin embargo el tema es bastante complicado para alguien que no esté acostumbrado a programar. Se necesita leer una onda cuadrada en la cual se envían los bits con separaciones de unos cuantos microsegundos. 



Estructura de los datos del sensor DHT11 :
  1. Humedad (entero) : 8bit
  2. Humedad (fracción) : 8bit
  3. Temperatura (entero) :8bit
  4. Temperatura (fracción) : 8bit
  5. Check sum : Humedad (entero) + Humedad (fracción) + Temperatura (entero) + Temperatura (fracción)
La verdad prefiero usar la librería DHT11. Para ello, la descargo del siguiente link de adafruit (para instalar una librería consulta este enlace).

Instrucciones

#include "DHT.h" : Añadimos la librería para trabajar con el sensor
DHT dht(PinOut,TipoDHT) : Definimos con PinOut el pin al que se conectará el sensor en la placa de Arduino y TipoDHT el tipo de sensor que puede ser DHT11, DHT21 y DHT22). Ademas declaramos dht como un objeto DHT
int h = dht.readHumidity(); Lee el valor de la humedad relativa
int t = dht.readTemperature(); Lee el valor de la temperatura


Ejemplos

Para probar nuestro módulo, podemos utilizar el siguiente programa que es una variación del programa que viene como ejemplo en la librería:

// Sketch de ejemplo para testear el famoso sensor DHT de humedad y temperatura
// Escrito por ladyada, de dominio público
// Modificado por Regata para www.tallerarduino.wordpress.com
#include "DHT.h"  //Añadimos la libreria con la cual trabaja nuestro sensor
#define DHTPIN 2     // 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
// Conecta una resistencia de 10K del pin 2 (data) al pin 1 (+5V) del sensor
DHT dht(DHTPIN, DHTTYPE);  //Indica el pin con el que trabajamos y el tipo de sensor
int maxh=0, minh=100, maxt=0, mint=100;  //Variables para ir comprobando maximos y minimos
void setup()
{
  //Inicio comunicacion serie para ver los datos en el ordenador
  Serial.begin(9600);
  //Mensaje de inicio
  Serial.println("Comprobacion sensor DHTxx:");
  //Iniciamos el sensor
  dht.begin();
}
void loop()
{
  // La lectura de la temperatura o de la humedad lleva sobre 250 milisegundos 
  // La lectura del sensor tambien puede estar sobre los 2 segundos (es un sensor muy lento)
  int h = dht.readHumidity();  //Guarda la lectura de la humedad en la variable float h
  int t = dht.readTemperature();  //Guarda la lectura de la temperatura en la variable float t
  // Comprobamos si lo que devuelve el sensor es valido, si no son numeros algo esta fallando
  if (isnan(t) || isnan(h)) // funcion que comprueba si son numeros las variables indicadas
  {
    Serial.println("Fallo al leer del sensor DHT"); //Mostramos mensaje de fallo si no son numeros
  } else {
    //Mostramos mensaje con valores actuales de humedad y temperatura, asi como maximos y minimos de cada uno de ellos
    Serial.print("Humedad relativa: ");
    Serial.print(h);
    Serial.print(" %\t");
    Serial.print("Temperatura: ");
    Serial.print(t);
    Serial.println(" *C");
    //Comprobacion de maximos y minimos de humedad y temperatura
    if (maxh<h)
      maxh=h;
    if (h<minh)
      minh=h;
    if (maxt<t)
      maxt=t;
    if (t<mint)
      mint=t;
    Serial.print("Max: ");
    Serial.print(maxh);
    Serial.print(" % ");
    Serial.print("Min: ");
    Serial.print(minh);
    Serial.print(" %\t");
    Serial.print("Max: ");
    Serial.print(maxt);
    Serial.print(" *C ");
    Serial.print("Min: ");
    Serial.print(mint);
    Serial.println(" *C\n");
  }
  delay(1000);
}


Si no queremos utilizar las librerías, podemos utilizar este código:


//Programa test para sensor DHT11 de humedad y temperatura
//cleaned by sucotronic
//Modificado por Regata para tallerarduino.wordpress.com
#define DHTPIN 2 // Indicamos el pin del arduino donde conectamos el sensor
byte bGlobalErr;  //para pasar el codigo de error de vuelta de las funciones
byte DHTDAT[5];  //Array para almacenar los bytes enviados por el sensor
int maxh=0,minh=100,maxt=0,mint=100,t,h; //variables para ir guardando las maximas de
// humedad y temperatura y las minimas de humedad y temperatura
void setup()
{
  InitDHT();  // Inicializamos el pin empleado para leer el sensor
  Serial.begin(9600);  //Iniciamos comunicacion serie con el pc para ver los datos leidos
  Serial.println("Test sensor DHT11:");
  delay(1000);  //Este delay es para esperar el tiempo recomendado para acceder al sensor (1 segundo)
}
void loop()
{
  ReadDHT(); // Leemos el sensor y almacenamos el resultados en variables globales
  switch (bGlobalErr)
  {
     case 0:
        //Como en este sensor la humedad y la temperatura no nos sale con decimales,
        //podemos desechar los bytes 1 y 3 de la lectura del sensor
        h=DHTDAT[0];
        t=DHTDAT[2];
    Serial.print("Humedad relativa: ");
    Serial.print(h);
    Serial.print(" %\t");
    Serial.print("Temperatura: ");
    Serial.print(t);
    Serial.println("*C");
        //Comprobacion de maximos y minimos de humedad y temperatura
        if (maxh<h)
          maxh=h;
        if (h<minh)
          minh=h;
        if (maxt<t)
          maxt=t;
        if (t<mint)
          mint=t;
        Serial.print("Max: ");
        Serial.print(maxh);
        Serial.print(" % ");
        Serial.print("Min: ");
        Serial.print(minh);
        Serial.print(" %\t");
        Serial.print("Max: ");
        Serial.print(maxt);
        Serial.print(" *C ");
        Serial.print("Min: ");
        Serial.print(mint);
        Serial.println(" *C\n");
        break;
     case 1:
        Serial.println("Error 1: Condicion de start 1 no conocida.");
        break;
     case 2:
        Serial.println("Error 2: Condicion de start 2 no conocida.");
        break;
     case 3:
        Serial.println("Error 3: DHT checksum error.");
        break;
     default:
        Serial.println("Error: Encontrado codigo irreconocible.");
        break;
  }
  delay(1000);// Esperamos 1 segundo para la siguiente lectura
}
// Initilize pin for reading
void InitDHT(){
        pinMode(DHTPIN,OUTPUT);
        digitalWrite(DHTPIN,HIGH);
}
void ReadDHT(){
  bGlobalErr=0;
  byte dht_in;
  byte i;
  // Enviamos el comando "start read and report" al sensor
  // Primero: ponemos a "0" el pin durante 18ms
  digitalWrite(DHTPIN,LOW);
  delay(18);
  delay(5);//TKB, frm Quine at Arduino forum
  //Segundo: ponemos a "1" el pin durante 40us,enviamos el comando de "start read" al sensor
  digitalWrite(DHTPIN,HIGH);
  delayMicroseconds(40);
  //Tercero: Cambiamos el pin de Arduino a entrada de datos
  pinMode(DHTPIN,INPUT);
  delayMicroseconds(40); //Esperamos 40 us
  dht_in=digitalRead(DHTPIN);
  //si hay un 1 en la lectura del pin, indicamos que hay error de tipo 1
  if(dht_in)
  {
    bGlobalErr=1;
    return;
  }
  delayMicroseconds(80); //Esperamos 80us
  dht_in=digitalRead(DHTPIN);
  //si no hay un 1 en la lectura del pin, indicamos que hay error de tipo 2
  if(!dht_in){
    bGlobalErr=2;
    return;
  }
  /*Despues de 40us a nivel bajo, el pin deberia de estar durante 80us a nivel alto.
  Despues de esto comienza el envio del primer bit hasta alcanzar los 40 bits enviados.
  The routine "read_dht_dat()" expects to be called with the system already into this low.*/
  delayMicroseconds(80); //Esperamos 80us
  //Ahora comienza la recepcion de datos, son 5 bytes de datos, es decir 40 bits, almacenamos en un array de 5 bytes
  for (i=0; i<5; i++)
    DHTDAT[i] = read_dht_dat();
  //Cuarto: Volvemos a configurar el pin del arduino como salida
  pinMode(DHTPIN,OUTPUT);
  //Quinto:Ponemos a "1" el pin de salida
  digitalWrite(DHTPIN,HIGH);
  //Comprobamos si los datos recibidos coinciden con el checksum recibido
  byte DHTCHECKSUM = DHTDAT[0]+DHTDAT[1]+DHTDAT[2]+DHTDAT[3];
  //Si no coincide el byte recibido de checksum con la suma de los 4 primeros bytes enviamos error tipo 3
  if(DHTDAT[4]!= DHTCHECKSUM)
    bGlobalErr=3;
  };
byte read_dht_dat()
{
  //Cogemos 8 de los bits recibidos y los devolvemos como un byte.
  //Si por ejemplo recibimos 00000100 , devolvemos en decimal 4
  byte i = 0;
  byte result=0;
  for(i=0; i< 8; i++)
  {
    //Entramos mientras dura el primer bit de start (a nivel bajo durante 50us) del byte
    //Esperamos hasta que el pin se pone a nivel alto señalizando fin del la transmision del bit de start
    while(digitalRead(DHTPIN)==LOW);
    //La linea de datos debera estar ahora a nivel alto durante 27 o 70us,
    //dependiendo si un "0" o un "1" esta siendo enviado respectivamente
    delayMicroseconds(30);  //Esperamos 30 us
    if (digitalRead(DHTPIN)==HIGH)
      result |=(1<<(7-i));  //Si despues de los 30us el pin permanece a "1" añadimos un 1 al byte, sino queda un "0"
    //Esperamos hasta que el pin se vuelve a poner a nivel bajo,
    // el cual indica la señal de start del siguiente bit de la transmision
    while (digitalRead(DHTPIN)==HIGH);
  }
  return result; //devolvemos el resultado
}

Fuentes

Datasheet:
Más información: