En el post de hoy vamos a presentar un sistema domótico real casero basado en la plataforma Arduino cuyo software ha compartido el autor de forma desinteresada (el impresionante código fuente se adjunta más abajo)
El sistema lo componen los sistemas siguientes partes :
- Arduino Ethernet Shield
– Arduino Proto Shield con una pequeño breadboard.
- 4 Probes temperature-humidity sensor.
– Probe SCT-013-000 and the components refer here.(sensor sin contacto de consumo que no se ha implementado en el código del ejemplo)
-Un sensor PIR
- Un display LCD 16×2 compatible con Hitachi 44780
Como se puede apreciar el corazón es una placa Arduino con el escudo para dar conectividad ethernet a la red y una placa aparte tipo protoboard para poder conectar la pantalla LCD de 16×2 y los sensores que en princ¡pio el autor ha seleccionado sólo cinco:
- 4 sensores digitales de temperatura y humedad basados en el DHT11
- 1 sensor de consumo analógico ( no lo ha implementado en el ejemplo)
- 1 sensor PIR de movimiento
En cuanto al conexionado de los 4 sensores dht11 es el siguiente:
- pin 14 :qué pin estamos conectados con Entrada 0
- pin 15 :qué pin estamos conectados con Dormitorio 1
- pin 16 : lo que pin que estamos conectados a Salon 2
- pin 17 : lo que pin que estamos conectados a Terraza 3
Respecto a las conexiones particulares de cada DTH11 son la siguientes:
- Conectar el pin 1 (a la izquierda) del sensor a 5 V
- Conectar el pin 2 del sensor a lo que su DHTPIN
- Conectar el pin 4 (a la derecha) del sensor a a ov (GND)
- Conectar una resistencia de 10K desde el pin 2 (datos) al pin 1 (alimentación) del sensor
Respecto a la pantalla LCD, demuestra el uso de una pantalla LCD de 16×2. El LiquidCrystal biblioteca trabaja con todas las pantallas LCD que son compatibles con el controlador Hitachi HD44780. Hay muchos de ellos por ahí, y que por lo general se les puede decir por la interfaz de 16-pin.
El conexionado es el tipico de un LCD compatible Hitachi HD44780 y un placa x-Duino usando el modo de 4bits :
- pin LCD RS al pin digital 8
- LCD Enable pin a pin digital 9
- LCD D4 pin a pin digital 4
- LCD D5 pin a pin digital 5
- LCD D6 pin a pin digital 6
- LCD D7 pin a pin digital 7
- LCD R / W clavija a tierra
- resistencia de 10K: entre terminal +5 V y tierra
- limpiador de LCD pin VO (pin 3)
Por ultimo los datos del sensor PIR irán en este ejemplo también al PIN 5 ( y los dos restantes a +5v y GND)
El autor gracias a un hosting externo también envía todas las muestras a este servidor como una única cadena concatenando todas las muestras en una sola para poder almacenarla y visualizar estos datos desde cualquier parte gracias a la conectividad ofrecida por el escudo ethernet.
Como ejemplo , esta es una visualización del resultado:
CÓDIGO FUENTE PROTOTIPO
#
/
#include
#include
#include
#include
// include the library code:
#include
// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
#include “EmonLib.h” // Include Emon Library
EnergyMonitor emon1; // Create an instance
#include “DHT.h”
#define DHTPIN14 14 // what pin we’re connected to Entrada 0
#define DHTPIN15 15 // what pin we’re connected to Dormitorio 1
#define DHTPIN16 16 // what pin we’re connected to Salon 2
#define DHTPIN17 17 // what pin we’re connected to Terraza 3
#define DHTTYPE22 DHT22 // DHT 22 (AM2302)
#define DHTTYPE11 DHT11
// Connect pin 1 (on the left) of the sensor to +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
DHT dht0(DHTPIN14, DHTTYPE11);
DHT dht1(DHTPIN15, DHTTYPE22);
DHT dht2(DHTPIN16, DHTTYPE22);
DHT dht3(DHTPIN17, DHTTYPE22);
char strtemperatura0[4] = “0”;
char strhumedad0[4]= “0”;
char strtemperatura1[4] = “1”;
char strhumedad1[4] = “1”;
char strtemperatura2[4] = “2”;
char strhumedad2[4]= “2”;
char strtemperatura3[4] = “3”;
char strhumedad3[4] = “3”;
String H0=””;
String H1=””;
String H2=””;
String H3=””;
// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = {
0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
//the IP address for the shield:
byte ip[] = { 192, 168, 0, 5 };
byte gateway[] = { 192, 168, 0, 2 };
// the subnet:
byte subnet[] = { 255, 255, 255, 0 };
EthernetClient drupal;
String URLdrupal;
char strI[6];
IPAddress drupalserver(184,72,150,42);
#include “Time.h”
EthernetUDP Udp;
unsigned int localPort = 8888; // local port to listen for UDP packets
time_t prevDisplay = 0; // when the digital clock was displayed
//const int timeZoneOffset = 3600; // GMT zone +1;
const int timeZoneOffset = 7200; // GMT zone +2;
//IPAddress timeServer(192, 43, 244, 18); // time.nist.gov
//IPAddress timeServer(130, 149, 17, 21); // ntps1-0.cs.tu-berlin.de
//byte SNTP_server_IP[] = { 192,53,103,108}; // ptbtime1.ptb.de
//IPAddress timeServer(132, 163, 4, 103); // time-a.timefreq.bldrdoc.gov NTP server
IPAddress timeServer(132, 163, 4, 102); // time-b.timefreq.bldrdoc.gov NTP server
//IPAddress timeServer(132, 163, 4, 103); // time-c.timefreq.bldrdoc.gov NTP server
const int NTP_PACKET_SIZE= 48; // NTP time stamp is in the first 48 bytes of the message
byte packetBuffer[ NTP_PACKET_SIZE]; //buffer to hold incoming and outgoing packets
char dia[3] = “”;
char mes[3] = “”;
char ano[5] = “”;
char hora[3] = “”;
String fecha = “”;
String valor = “”;
char d[2] = “”;
String info=””;
String P=””;
int PIR = 0;
boolean pirState = false;
int pirPin = 5; //the analog/digital pin connected to the PIR sensor’s output
//the time when the sensor outputs a low impulse
long unsigned int lowIn;
//the amount of milliseconds the sensor has to be low
//before we assume all motion has stopped
long unsigned int pause = 3000;
//the time we give the sensor to calibrate (10-60 secs according to the datasheet)
int calibrationTime = 15;
void setup(){
// set up the LCD’s number of columns and rows:
lcd.begin(16, 2);
// start the Ethernet connection and the server:
if (Ethernet.begin(mac) == 0) {
//Serial.println(“Failed to configure Ethernet using DHCP”);
// no point in carrying on, so do nothing forevermore:
Ethernet.begin(mac, ip, gateway, subnet);
}
// initialize the serial communications:
Serial.begin(9600);
Serial.println(Ethernet.localIP());
Udp.begin(localPort);
setSyncProvider(getNTPTime);
while(timeStatus()== timeNotSet); // wait until the time is set by the sync provider
// emon1.current(9, 111.1); // Current: analog input pin, calibration.
emon1.current(9, 100);
dht0.begin();
dht1.begin();
dht2.begin();
dht3.begin();
/*
pinMode(pirPin, INPUT);
// digitalWrite (pirPin, LOW);
//give the sensor some time to calibrate
Serial.print(“calibrating sensor “);
for(int i = 0; i < calibrationTime; i++){
Serial.print(“.”);
delay(1000);
}
Serial.println(” done”);
Serial.println(“SENSOR ACTIVE”);
*/
lcd.clear();
}
void loop()
{
if( now() != prevDisplay) //update the display only if the time has changed
{
prevDisplay = now();
}
double Irms = emon1.calcIrms(1100); // Calculate Irms only
int I=Irms*220; // 220 voltios
// P = “Potencia “;
P = “”;
P.concat (I);
P.concat (“W”);
for(int i = 0; i < 30; i++){
if (i == 0) {
float h0 = dht0.readHumidity();
float t0 = dht0.readTemperature();
H0=”Entrada “;
itoa(t0,strtemperatura0,10);
itoa(h0,strhumedad0,10);
H0.concat(strtemperatura0);
H0.concat(“C “);
H0.concat(strhumedad0);
H0.concat(“%”);
pantalla (0,1,H0, true); //cuidado…….
Serial.println(H0); //cuidado…….
}
if (i == 5) {
float h3 = dht3.readHumidity();
float t3 = dht3.readTemperature();
H3=”Terraza “;
itoa(t3,strtemperatura3,10);
itoa(h3,strhumedad3,10);
H3.concat(strtemperatura3); //cuidado…….
H3.concat(“C “);
H3.concat(strhumedad3); //cuidado…….
H3.concat(“%”);
pantalla (0,1,H3, true);
}
if (i == 10) {
float h1 = dht1.readHumidity();
float t1 = dht1.readTemperature();
H1=”Dormito. “;
itoa(t1,strtemperatura1,10);
itoa(h1,strhumedad1,10);
H1.concat(strtemperatura1); //cuidado…….
H1.concat(“C “);
H1.concat(strhumedad1); //cuidado…….
H1.concat(“%”);
pantalla (0,1,H1, true);
Serial.println(H1);
}
if (i == 15) {
pantalla (0,1,H3, true);
}
if (i == 20) {
float h2 = dht2.readHumidity();
float t2 = dht2.readTemperature();
H2=”Salon “;
itoa(t2,strtemperatura2,10);
itoa(h2,strhumedad2,10);
H2.concat(strtemperatura2); //cuidado…….
H2.concat(“C “);
H2.concat(strhumedad2); //cuidado…….
H2.concat(“%”);
pantalla (0,1,H2, true);
Serial.println(H2);
}
if (i == 25) {
pantalla (0,1,H3, true);
Serial.println(H3);
}
pantalla (0,0,digitalClockDisplay(),false);
pantalla (9,0,P, true);
delay (1000);
/*
PIR = analogRead(pirPin);
Serial.println (PIR);
if(PIR > 400){
if(!pirState){
//makes sure we wait for a transition to LOW before any further output is made:
pirState = true;
lowIn = millis(); //save the time of the transition
pantalla (9,0,”P”, false);
Serial.println(“—“);
Serial.print(“motion detected at “);
Serial.print(lowIn/1000);
Serial.println(” sec”);
}
}
if(PIR < 400){
//if the sensor is low for more than the given pause,
//we assume that no more motion is going to happen
if(pirState & (millis() – lowIn > pause)){
//makes sure this block of code is only executed again after
//a new motion sequence has been detected
pirState = false; //make sure this is only done at the start of a LOW phase
pantalla (9,0,” “, false);
Serial.print(“motion ended at “); //output
Serial.print((millis() – lowIn)/1000);
Serial.println(” sec”);
}
}
*/
}
if (drupal.connect(drupalserver, 80)) {
Serial.println(“connected”);
URLdrupal=”GET /insert.php?Temperatura=”;
URLdrupal.concat(strtemperatura1);//cuidado…….
URLdrupal.concat(“&Humedad=”);
URLdrupal.concat(strhumedad1);//cuidado…….
URLdrupal.concat(“&Potencia=”);
itoa(I,strI,10);
URLdrupal.concat(strI);
URLdrupal.concat(“&Temperatura2=”);
URLdrupal.concat(strtemperatura0); //cuidado…….
URLdrupal.concat(“&Humedad2=”);
URLdrupal.concat(strhumedad0); //cuidado…….
URLdrupal.concat(“&Temperatura3=”);
URLdrupal.concat(strtemperatura2);
URLdrupal.concat(“&Humedad3=”);
URLdrupal.concat(strhumedad2);
URLdrupal.concat(“&Temperatura4=”);
URLdrupal.concat(strtemperatura3);
URLdrupal.concat(“&Humedad4=”);
URLdrupal.concat(strhumedad3);
URLdrupal.concat(” HTTP/1.1″);
drupal.println(URLdrupal);
drupal.println(“Host: drupal-forsale.rhcloud.com”); // needed in my case (virtualserver)
Serial.println(URLdrupal);
//Serial.println(“Host: drupal-forsale.rhcloud.com”);
drupal.println();
//String c = drupal.readString();
//Serial.println(c);
drupal.stop();
} else {
Serial.println(“connection drupal failed”);
}
}
/*——– LiquidCristal code —-*/
void pantalla (int columna, int fila, String texto, boolean completar) {
lcd.setCursor(columna, fila);
if (completar) {
for(int l=texto.length(); l<16; l++) {
texto.concat(” “);
}
}
lcd.print(texto);
}
/*——– NTP code ———-*/
unsigned long getNTPTime()
{
Serial.println(“In getNTPTime”);
sendNTPpacket(timeServer);
delay(1000);
if ( Udp.parsePacket() ) {
Serial.println(“Got Time Packet”);
Udp.read(packetBuffer,NTP_PACKET_SIZE);
unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);
unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]);
unsigned long secsSince1900 = highWord << 16 | lowWord;
const unsigned long seventyYears = 2208988800UL;
unsigned long epoch = secsSince1900 – seventyYears + timeZoneOffset;
return epoch;
}
Serial.println(“No Time Packet Found”);
return 0;
}
// send an NTP request to the time server at the given address
unsigned long sendNTPpacket(IPAddress& address)
{
// set all bytes in the buffer to 0
memset(packetBuffer, 0, NTP_PACKET_SIZE);
// Initialize values needed to form NTP request
// (see URL above for details on the packets)
// packetBuffer[0] = 0b11100011; // LI, Version, Mode
packetBuffer[0]= 0b10100011;
// packetBuffer[0] = 0b10010011; // LI, Version, Mode
packetBuffer[1] = 2; // Stratum, or type of clock
packetBuffer[2] = 6; // Polling Interval
packetBuffer[3] = 0xEC; // Peer Clock Precision
// 8 bytes of zero for Root Delay & Root Dispersion
packetBuffer[12] = 49;
packetBuffer[13] = 0x4E;
packetBuffer[14] = 49;
packetBuffer[15] = 52;
// all NTP fields have been given values, now
// you can send a packet requesting a timestamp:
Udp.beginPacket(address, 123); //NTP requests are to port 123
Udp.write(packetBuffer,NTP_PACKET_SIZE);
Udp.endPacket();
}
/*——– Clock code ———-*/
String digitalClockDisplay(){
// digital clock display of the time
fecha=printDigits(hour());
fecha.concat(“:”);
fecha.concat(printDigits(minute()));
fecha.concat(“:”);
fecha.concat(printDigits(second()));
return fecha;
}
String digitalClockDateDisplay(){
// digital clock display of the time and date
itoa(day(),dia,10);
itoa(month(),mes,10);
itoa(year(),ano,10);
itoa(hour(),hora,10);
fecha=hora;
fecha.concat(“:”);
fecha.concat(printDigits(minute()));
fecha.concat(“:”);
fecha.concat(printDigits(second()));
fecha.concat(” “);
fecha.concat(dia);
fecha.concat(” “);
fecha.concat(mes);
fecha.concat(” “);
fecha.concat(ano);
return fecha;
}
String printDigits(int digits)
{
// utility function for digital clock display: prints preceding colon and leading 0
// Serial.print(“:”);
// if(digits < 10)
// Serial.print(‘0′);
// Serial.print(digits);
valor = “”;
if (digits <10) valor=”0″;
itoa(digits,d,10);
valor.concat(d);
return valor;
}
Biblioteca originalmente añadido 18 de abril 2008 por David A. Mellis
biblioteca modificada 05 de julio 2009 por Limor Fried ( http://www.ladyada.net )
ejemplo de creación 09 de julio 2009 por Tom Igoe
modificado 22 de noviembre 2010 por Tom Igoe
Este código de ejemplo se encuentra en el dominio público.
http://arduino.cc/en/Tutorial/LiquidCrystalSerial
fuente aqui