lunedì 22 settembre 2014

Domotica - Controllo remoto

Il controllo remoto delle luci è ottenuto grazie all’utilizzo della scheda aggiuntiva di Arduino chiamata “Ethernet Shield”. Impostando l’indirizzo IP del router a cui è collegato Arduino, ci si potrà , grazie ad una connessione internet e un browser, collegare al sistema  e comandare l’accensione e lo spegnimento delle luci all’interno della casa.
Grazie al controllo remoto è possibile controllare la nostra abitazione anche a distanza, ad esempio chi possiede una casa in montagna può attivare il riscaldamento a distanza in modo da trovare una temperatura accogliente una volta raggiunta la destinazione.

PROGRAMMA ARDUINO

#include <SPI.h>
#include <Ethernet.h>
byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = {192, 168, 9, 55 };
byte subnet[] = {255, 255, 255, 0 };
EthernetServer server(80);
String readString;
byte out_1 = 7;
byte out_2 = 6;
byte out_3 = 5;
byte out_4 = 4;
byte out_5 = 3;

void setup() {

Ethernet.begin(mac, ip);

pinMode (out_1, OUTPUT);
pinMode (out_2, OUTPUT);
pinMode (out_3, OUTPUT);
pinMode (out_4, OUTPUT);
pinMode (out_5, OUTPUT);
}

void loop() {

EthernetClient  client = server.available();

  if (client) {
    boolean currentLineIsBlank = true;

    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        readString.concat(c);  
        if (c == '\n' && currentLineIsBlank) {

          if(readString.indexOf("on_1") > 0) {
            digitalWrite(out_1, HIGH);
            delay(325);
            digitalWrite(out_1, LOW);
            }       
          if(readString.indexOf("off_1") > 0) {
            digitalWrite(out_1, HIGH);
            delay(325);
            digitalWrite(out_1, LOW);
            }         
          if(readString.indexOf("on_2") > 0) {
            digitalWrite (out_2, HIGH);
            delay (325);
            digitalWrite (out_2, LOW);
            }       
          if(readString.indexOf ("off_2") > 0) {
            digitalWrite (out_3, HIGH);
            delay (325);
            digitalWrite (out_3, LOW);
            }
          if(readString.indexOf ("on_3") > 0) {
            digitalWrite (out_3, HIGH);
            delay (325);
            digitalWrite (out_3, LOW);
            }
          if(readString.indexOf ("off_3") > 0) {
            digitalWrite (out_4, HIGH);
            delay (325);
            digitalWrite (out_4, LOW);
            }
          if(readString.indexOf ("on_4") > 0) {
            digitalWrite (out_4, HIGH);
            delay (325);
            digitalWrite (out_4, LOW);
            }
          if(readString.indexOf ("off_4") > 0) {
            digitalWrite (out_4, HIGH);
            delay (325);
            digitalWrite (out_4, LOW);
            }
          if(readString.indexOf ("on_5") > 0) {
            digitalWrite (out_5, HIGH);
            delay (325);
            digitalWrite (out_5, LOW);
            }       
          if(readString.indexOf ("off_5") > 0) {
            digitalWrite (out_5, HIGH);
            delay(325);
            digitalWrite (out_5, LOW);
            }

Parte dedicata al rilevamento della selezione dalla pagina HTML all'azionamento vero e proprio dell'azione fisica, accensione/spegnimento luci.

          client.println("HTTP/1.1 200 OK");
          client.println ("Content-Type: text/html");
          client.println ();
          client.print ("<html><head><title>CASA DOMOTICA</title><meta http-equiv='Content-Type' content='text/html; charset=iso-8859-1' ></head><body>");
          client.print("<BR><BR>");
          client.print ("<h2>Controllo remoto</h2>");
          client.print ("<p>");
          client.print ("<br>");
          if (digitalRead(2)== true) client.print ("<a href=/?off_1><strong>PULSANTE</strong>"); 
          else client.print ("<a href=/?on_1><strong>PULSANTE</strong>");
          client.print ("<-- LUCE BAGNO");
          client.print ("<br>");
          if (digitalRead(3)== true) client.print ("<a href=/?off_2><strong>PULSANTE</strong>"); 
          else client.print ("<a href=/?on_2><strong>PULSANTE</strong>");
          client.print ("<-- LUCE CORRIDOIO");
          client.print ("<br>");
          if (digitalRead(4)== true) client.print ("<a href=/?off_3><strong>PULSANTE</strong>"); 
          else client.print ("<a href=/?on_3><strong>PULSANTE</strong>");
          client.print ("<-- LUCE CAMERA");
          client.print ("<br>");
          if (digitalRead(5)== true) client.print ("<a href=/?off_4><strong>PULSANTE</strong>"); 
          else client.print ("<a href=/?on_4><strong>PULSANTE</strong>");
          client.print ("<-- LUCE CUCINA");
          client.print ("<br>");
          if (digitalRead(6)== true) client.print ("<a href=/?off_5><strong>PULSANTE</strong>"); 
          else client.print ("<a href=/?on_5><strong>PULSANTE</strong>");
          client.print ("<-- LUCE SALOTTO");
          client.print ("<br>");
          client.println("</body></html>");

          readString="";
          delay(5);

          client.flush();
          client.stop();
        }
      }
    }

}

Parte di programma utilizzata per la creazione della pagina HTML, visualizzabile dal browser, per l'accensione e lo spegnimento delle luci da remoto. Il risultato ottenuto è questo:

Domotica - Luci vialetto

Il controllo delle luci del vialetto è ottenuto tramite una foto-resistenza (trasduttore  che al variare dell’intensità luminosa a cui è sottoposto varia la sua resistenza), non appena il trasduttore rileva che la luce scende al di sotto di un determinato valore prefissato, la centralina accende le luci del vialetto. Inoltre se non si vogliono tenere accese le luci del vialetto durante l’intera notte o durante l’assenza da casa per risparmiare energia, l’impianto può essere disattivato tramite un pulsante interno all’abitazione.

Programma Arduino

#define vial 25 
#define puls 7
#define LED 18
int w = 0;  
int stato = 0;
int s = 0;
int k = 0;
const int  FOTOR = A9;

void setup() {
pinMode(LED, OUTPUT);  
pinMode (vial, OUTPUT);   
pinMode (puls, INPUT);
digitalWrite(vial, HIGH);
}

void loop() {
do{                       
float fotoValue = analogRead(FOTOR);
 if(fotoValue > 500 ){
   s=1
 delay(50);
}
   else (s=0);            
   if ((stato == 1)&&(s == 1)) {
   digitalWrite(vial, LOW);
    }
    else {
    digitalWrite(vial, HIGH);
    }   
}
 while ((LED == HIGH)&&(puls == LOW));

Ciclo while per l'accensione e spegnimento delle luci del vialetto tramite la fotoresistenza. Se il valore rilevato del sensore è maggiore del valore prefissato la variabile "s" andrà allo stato "1"e se anche la variabile "stato" è anch'essa a "1" allora il programma accenderà le luci del viale, se solo una di queste condizioni non è rispettata il programma non accenderà le luci.

 k = digitalRead(puls);
  if ((k == HIGH)&&(w == 0)) {
    stato = 1;
    digitalWrite(vial, HIGH);
    k = 0;
    delay(250);
  }
  if ((k == HIGH)&&(w == 1)) {
    stato = 0;
    k = 0;
    delay(250); 
  }
  if (stato == 1) {
    w = 1;
    digitalWrite(LED, HIGH);
}
    else {
    w = 0;
    digitalWrite(LED, LOW);
    digitalWrite (vial, HIGH);
  }
delay(100);
}

Codici del programma che servono per l'attivazione o il disinserimento dell'accensione delle luci del vialetto tramite la fotoresistenza. Per capire se il programma è abilitato o meno all'accensione delle luci del viale nel pulsante è stato aggiunto un LED per l'indicazione, se questo è acceso il programma è disinserito al contrario se questo è spento il programma è abilitato.

Domotica - Controllo tenda

L’innalzamento e l’abbassamento della tenda è ottenuto tramite pulsanti fisici inoltre se la tenda è del tutto abbassata e si preme il pulsante per abbassarla, il programma non farà nulla; lo stesso avviene per la tenda del tutto avvolta.Sono presenti due sensori: un anemometro, che permette alla centralina di determinare la velocità del vento, e un pluviostato, speciale trasduttore che riesce a determinare se sta piovendo oppure no  grazie al variare della sua resistenza. Questi due sensori tengono sotto controllo le condizioni ambientali esterne, non appena uno dei due rileva un  valore che supera quello prefissato nel programma la tenda viene riavvolta automaticamente per evitare danni.

Programma Arduino

const int btSuTenda = 5;
const int SuTendaPin = 22;
int StTSu = 0;
const int btGiuTenda = 6;
const int GiuTendaPin = 52;
int StTGiu = 0;
int StTenda = 0;

void setup() {
pinMode (btSuTenda, INPUT);
pinMode (btGiuTenda, INPUT);
pinMode (SuTendaPin, OUTPUT);
pinMode (GiuTendaPin, OUTPUT);
pinMode (pluvPin, INPUT);
pinMode (AnPin, INPUT);
}

void loop() {
ce = 0;
  t = millis();
  for (se = 0; se < 10000; se++) {  
    state = digitalRead(AnPin);
    if (state != oldstate) {
      ce++;
      oldstate = state;
    }
  }
  t = millis() - t;
  ce = ce / 2;
  f = 1000 * ce / t;

Questo ciclo for all'interno del programma rappresenta il contatore della frequenza di un treno di impulsi (segnali ottenuti dal pluviostato) in ingresso in una entrata digitale. Quest'azione viene ripetuta sempre durando 10000 cicli. Durante questo tempo il programma conta gli impulsi in ingresso e tramite opportuni calcoli matematici li trasforma in frequenza. 

  StTGiu = digitalRead(btGiuTenda);
  StTSu = digitalRead (btSuTenda);
  if ((StTGiu == HIGH) && (StTenda == 0)) {
    digitalWrite(GiuTendaPin, HIGH);
    delay(9500);
    digitalWrite(GiuTendaPin, LOW);
    StTenda = 1;
    delay(50);
  }

Parte di programma che abbassa la tenda non appena si pigia il pulsante, L'azione viene completata solamente se la tenda è alzata (stato definito dalla variabile StTenda, variabile a 0 la tenda è alzata mentre se la variabile è a 1 la tenda è abbassata).

  if ((StTSu == HIGH) && (StTenda == 1)) {
    digitalWrite(SuTendaPin, HIGH);
    delay(9500);
    digitalWrite(SuTendaPin, LOW);
    StTenda = 0;
  }

Parte di programma che alza la tenda non appena si pigia il pulsante, L'azione viene completata solamente se la tenda è abbassata (stato definito dalla variabile StTenda, variabile a 0 la tenda è alzata mentre se la variabile è a 1 la tenda è abbassata).

  if ((StTenda == 1) && ((analogRead(pluvPin) < 500) || (f >= 4))) {
    digitalWrite(SuTendaPin, HIGH);
    delay(9500);
    digitalWrite(SuTendaPin, LOW);
    StTenda = 0;
  }
}

Parte in cui se il programma riconosce che la tenda è abbassata e se la lettura del pluviostato è al di sotto di un determinato valore (fissato da noi per far riconoscere al programma che sta piovendo) oppure se la frequenza in ingresso dall'anemometro è troppo alta la centralina alzerà automaticamente la tenda per evitare danni. 

Domotica - Sistema anti intrusione

La casa è protetta da un antifurto perimetrale composto da reed (contatti magnetici) applicati a ogni
finestra. I contatti magnetici sono particolari interruttori che permettono il passaggio della corrente
a seconda che un magnete sia allontanato o avvicinato al dispositivo, in questo caso esso è posto su un oggetto mobile (porta o finestra). Mentre il sistema è abilitato, non appena una finestra o
porta viene aperta, l’allarme si attiva con una segnalazione acustica, ottenuta tramite un campanello, e da una segnalazione visiva data da una luce lampeggiante. Il sistema anti intrusione è attivabile e disattivabile tramite tastierino numerico, digitando una password. Il programma visualizza lo stato dell’allarme sul display della centralina.

Programma Arduino

#include <Keypad.h>
#define sirena 24
#define LEDA 17
#define mg1 4
#define mg2 3
#define mg3 2
#define mg4 44
#define mg5 45
#define mg6 14
#define mg7 15
#define mg8 16
int x = 0;
int y = 0;
int m = 0;
const byte ROWS = 4;
const byte COLS = 3;
char keys[ROWS][COLS] = {
  {'1','2','3'},
  {'4','5','6'},
  {'7','8','9'},
  {'*','0','#'}
};
byte rowPins[ROWS] = {34, 35, 36, 37};
byte colPins[COLS] = {38, 39, 40};
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

void setup() {
pinMode(LEDA, OUTPUT);
pinMode (sirena, OUTPUT);
pinMode (mg1, INPUT);
pinMode (mg2, INPUT);
pinMode (mg3, INPUT);
pinMode (mg4, INPUT);
pinMode (mg5, INPUT);
pinMode (mg6, INPUT);
pinMode (mg7, INPUT);
pinMode (mg8, INPUT);
keypad.addEventListener(keypadEvent);
}

void loop() {
char key = keypad.getKey();
  pinMode ( x == 0) {
    lcd.setCursor(0, 0);
    lcd.print("CASA DOMOTICA   ");
    lcd.setCursor(0, 1);
    lcd.print("allarme off     ");
  }
  else {
    lcd.setCursor(0, 0);
    lcd.print("CASA DOMOTICA   ");
    lcd.setCursor(0, 1);
    lcd.print("allarme on      ");
  }
  if ( (digitalRead(mg1) == LOW) || (digitalRead (mg2) == LOW) || (digitalRead (mg3) == LOW) || (digitalRead (mg4) == LOW) || (digitalRead (mg5) == LOW) || (digitalRead (mg6) == LOW) || (digitalRead (mg7) == LOW) || (digitalRead (mg8) == LOW)) {
    y = 1;
  }
  else {
    y = 0;
  }
  if (( y == 1) && ( x == 1)) {
    do {
      digitalWrite(sirena, HIGH);
      do {
        digitalWrite(LEDA, HIGH);
        delay(100);
        digitalWrite(LEDA, LOW);
        delay(100);
        m = m + 1;
      }
      while (m < 1);
      m = 0;
      char key = keypad.getKey();
    }
    while (x == 1);
    digitalWrite(sirena, LOW);
    digitalWrite(LEDA, LOW);
  }
}
void keypadEvent(KeypadEvent key) {
  switch (keypad.getState()) {
    case PRESSED:
      if (key == '#') {
        x = !x;
      }
      break;
  }
}