Apriporta con smartphone

Questo post solo per condividere il mio primo e forse unico progetto con una arduino + ethernet shields. L'ho comprata solo per questo.

Si tratta di un sistema apriporta pilotabile da un qualunque apparato in grado di connettersi via wireless alla rete domestica.
Nulla di nuovo quindi. Infatti il tutto si basa su codice già disponibile in rete. Non ho fatto altro che adattarlo alle mie esigenze personali.

/*
 Arduino Data Web Server
 Hari Wiguna, g33k.blogspot.com
 created Sept 17, 2010
 
 Personalizzato come apriporta da Davide Pedrelli
 pobox.davide AT gmail DOT com
 Febbraio 2011
*/

#include <SPI.h>
#include <Ethernet.h>
#include <string.h>

byte mac[] = {0x00, 0x1E, 0x2A, 0x77, 0x24, 0x02 };
byte ip[] = { 192,168,1,222 };
byte subnet[] = {255,255,255,0};

Server server(80); //-- Porta 80 http.

char homepage[20];
char porta[20];
char pwd[20];
int nPorta;

//-- Parametri personalizzabili
char *path[]={"apritisesamo"};  //-- Path per la pagina web default ( es.: http://192.168.1.222/PATH_PERSONALIZZATO )
char *password[]={"123"};  //-- chiave segreta ( solo numerica, senza limiti di lunghezza )
char *tasti[]={"Cancello", "Ingresso", "Tasto 3", "Tasto 4", "", ""};  //-- Descrizioni bottoni interfaccia di controllo



//-- Designazione uscite digitali su Arduino e stato iniziale
void SetupPorte()
{
  for (int pin = 3; pin < 9; pin++) {  //-- uso i pin digitali da 3 a 8
  pinMode(pin,OUTPUT); digitalWrite(pin,LOW);
  }
}



void setup()
{
  Serial.begin(9600);
  SetupPorte();
  Ethernet.begin(mac, ip, subnet);
  server.begin();
}



#define bufferMax 128
int bufferSize;
char buffer[bufferMax];



void loop()
{
  Client client = server.available();
  if (client)
  {
    WaitForRequest(client);
    ParseReceivedRequest();
    PerformRequestedCommands();
    
    client.stop();
  }
}



void WaitForRequest(Client client)
{
  bufferSize = 0;

  while (client.connected()) {
    if (client.available()) {
      char c = client.read();
      if (c == '\n')
        break;
      else
        if (bufferSize < bufferMax)
          buffer[bufferSize++] = c;
        else
          break;
    }
  }
  PrintNumber("bufferSize", bufferSize);
}



void ParseReceivedRequest()
{
  Serial.println("in ParseReceivedRequest");
  Serial.println(buffer);
  
  /*
  La richiesta di pagina default va inoltrata verso Arduino nel seguente modo: http://192.168.1.222/PATH_PERSONALIZZATO
  ----------------------
  In caso di richesta pagina default, buffer conterrà      "GET /PATH_PERSONALIZZATO HTTP/1.1"
  In caso di click sui bottoni apriporta, buffer conterrà  "GET /PATH_PERSONALIZZATO?6=DESCRIZIONE_TASTO HTTP/1.1".
  */
  
  char* slash;
  char* uguale;
  char* commerciale;

  slash = strstr(buffer, "/") + 1;          //-- "PATH_PERSONALIZZATO?p=PASSWORD&6=DESCRIZIONE_TASTO HTTP/1.1" oppure "apritisesamo HTTP/1.1"
  uguale = strstr(buffer, "=") + 1;         //-- "PASSWORD&6=DESCRIZIONE_TASTO HTTP/1.1"
  commerciale = strstr(buffer, "&") + 1;    //-- "6=DESCRIZIONE_TASTO HTTP/1.1"
  
  homepage[0] = 0;
  pwd[0] = 0;
  porta[0] = 0;

  strncat(homepage, slash, strlen(path[0]));   //-- Isola il path della richiesta HTTP
  strncat(pwd, uguale, commerciale-uguale-1);  //-- Isola la chiave di accesso inserita da validare
  strncat(porta, commerciale, 1);              //-- Isola il numero di porta da aprite (es.: "6")

  nPorta = porta[0] - '0';                     //-- Numero pin digitale da attivate

  PrintString("Homepage",homepage);
  PrintString("Password",pwd);
  PrintString("Nr. porta da aprire",porta);
}



void PerformRequestedCommands()
{
  if ( strcmp(homepage, path[0]) == 0 and nPorta > 2 and nPorta < 9 and strcmp(pwd, password[0]) == 0 ) RemoteDigitalWrite();  //-- Contronta path, porta e chiave
  if ( strcmp(homepage, path[0]) == 0 ) DefaultWebPage();
}



void DefaultWebPage()
{
  //-- Invio pagine web
  server.print("<html><head><meta content='text/html; charset=utf-8' http-equiv='content-type' /><title>Apriti Sesamo</title>");
  
    if (nPorta > 2 and nPorta < 9 and strcmp(pwd, password[0]) == 0) {  //-- Se porta e chiave sono validi, redirect pagina web entro 2 secondi
      server.print("<META HTTP-EQUIV='refresh' CONTENT='2;URL=");
      server.print(path[0]);
      server.print("'>");
    }
    
       //-- Foglio di stile + javascript per gestione tastiera virtuale.
  server.print("<style type='text/css'>");
  server.print("body{background:#0259A1;text-align:center;margin-top:20px;font-family:sans-serif;font-size:70px;font-weight:bold;color:#FFF;}");
  server.print("input{padding:20px 15px;width:47%;margin:15px 1%;font-family:sans-serif;font-size:70px;font-weight:bold;color:#000;}");
  server.print("</style>");
  server.print("<script type='text/javascript'>function accoda(b){b.form.p.value+=b.value}</script>");
  server.print("</head><body>");

    if (nPorta > 2 and nPorta < 9 and strcmp(pwd, password[0]) == 0) {  //--  Se porta e chiave sono validi, notifica avvenuta apertura
        Serial.println("*** Apertura ***");  //-- Debug in seriale
        server.print("<div>");
        server.print("Attivato");
        server.print("</div>");
        server.print("<div style='font-size:50px;'>Pin digitale ");
        server.print(nPorta, DEC);
        server.print("</div>");
        }
      else {  //-- Pagina web default
        Serial.println("*** DefaultWebPage ***");  //-- Debug in seriale
        server.print("<form name='apriporte' action='' enctype='text/plain' method='get'>");
        server.print("<input style='background:#000;width:50%;color:#FFF;text-align:center;border:2px solid #57AEF6;' type='text' name='p'>");
        server.print("
<div style='height:15px;'></div>");
         //-- Crea i bottoni di apertura
         for (int conta = 0; conta < 6; conta++) {
           if (tasti[conta] != "") {  //-- Crea solo i bottoni a cui è associata una descrizione ( vedi array: tasti[] )
             server.print("<input type='submit' name='");
             server.print(conta + 3);
             server.print("' value='");
             server.print(tasti[conta]);
             server.print("'>");
             }
         }
      server.print("
<div style='height:30px;'></div>");
         //-- crea la tastiera numerica
         for (int conta = 0; conta < 10; conta++) {
             server.print("<input style='width:24%;margin:3px;background:#000;color:#FFF;' type='button' value='");
             server.print(conta);
             server.print("' onclick='accoda(this)'>");
         }
       server.print("<input style='width:48.5%;margin:3px;background:#8F0000;color:FFF;' type='reset' value='Canc'>");
       server.print("</form>");
       }

  server.print("</body></html>");
}



void RemoteDigitalWrite()
{
  digitalWrite(nPorta, HIGH);  //-- Attivo l'uscita digitale
  delay(500);
  digitalWrite(nPorta, LOW);
  
  Serial.println("RemoteDigitalWrite");
  PrintNumber("Porta", nPorta);
}



void PrintString(char* label, char* str)
{
  Serial.print(label);
  Serial.print("=");
  Serial.println(str);
}



void PrintNumber(char* label, int number)
{
  Serial.print(label);
  Serial.print("=");
  Serial.println(number, DEC);
}

Perdonate la pessima qualità dell'immagine

Quindi sostanzialmente quando arrivi nei pressi di casa, il tuo telefono prende la rete wifi di casa e da li puoi pilotare i rele' collegati al tuo arduino, corretto? Il codice mi pare ben commentato! Mi piacerebbe avere un cancello solo per fare questo progetto :slight_smile:
F

Veramente Complimenti!!! Un lavoro ben fatto, domani se ho un po di tempo lo provo, sembra molto interessante.

P.S.
Provato con il pc ed è fenomenale. Molto Bravo, dallo smartphone android invece non riesco a farlo andare, con il browser di default e dolphin HD da Impossibile comunicare con questo server.. Sia con il WIFI, che con l'umts tramite indirizzamento con dns dinamico.
Magari sarà un problema mio... Anche se con la mia webinterface comunica...
Tu lo hai testato da smartphone?

L'ho provato solo con, iPod e iPhone, quindi browser Safari. In effetti mi sarebbe molto utile avere feedback sul funzionamento con altri smartphone.
Per chi volesse accedere via interner al mio, questo è il link diretto: http://pedrelli.dyndns.org/apritisesamo
E' tutto montato, compresa la scheda relays, ma ovviamente è ancora sulla mia scrivania per testarlo a fondo prima di metterlo al lavoro.

Dimenticavo. La chiave di accesso è 123

Confermo che anche con il tuo arduino da il medesimo problema in Android. Sia con il browser di default che con DolphinHD, a breve installerò altri browser e testerò con quelli.

Sarebbe interessante sapere se altri che hanno android riscontrano gli stessi inconvenienti .

Comunque da wifi e in LAN funziona benissimo

Ciao,
complimenti per il progetto :wink:

Potresti dirmi che componenti hai usato (oltre all'Arduino, Ethernet Shield e Alimentatore) hai usato? Dalla foto non riesco a capire?!?
Grazie mille

intanto ti posso rispondere io..
Ti serve un relè per interfacciare arduino alla 220.

Qui un esempio di quello che ti servirebbe, Rele' con stadio pilota : EtherMania, The store for network enthusiasts .

Grazie mille per la celere risposta :astonished:

Avevo intuito che c'era di mezzo una scheda di controllo con relè, sembrerebbe anche facile da assemblare dal link che mi hai mandato!

Esistono, se le conoscete, altre schede di quel tipo ma con la possibilità di controllare più relè con Arduino?

Puoi autocostruirteli con quello schema.. E' semplicissimo, anche se non sei pratico..
Basta solo replicarli,
Io ho messo un connettore per l'alimentatore, ma si possono alimentare con arduino stesso.

Il mio è questo .. (ne manca uno nel mezzo che si era bruciato :smiley: )

Non c'entra assolutamente niente con il topic però volevo ringraziare dr4gone per il link e la foto che mi hanno semplificato un problema di interfacciamento con i relè :slight_smile:

volendo puoi migliorare il tutto, unendo l'alimentazione Vcc +5v e GND in comune per tutte l'entrate dei relè, e poi usare degli altri morsetti per collegare solo i segnali provenienti da rduino in entrata al relay.

Si, infatti.
Mi è piaciuto soprattutto il pdf che si trova al link da te segnalato che spiega tutto in maniera dettagliata.

Spero di fare cosa gradita, ho modificato leggermente il codice per utilizzarlo con il mio Blackberry e con IExplorer.

Complimenti per il lavoro
Nicola S.

/*
 Arduino Data Web Server
 Hari Wiguna, g33k.blogspot.com
 created Sept 17, 2010
 
 Personalizzato come apriporta da Davide Pedrelli
 pobox.davide AT gmail DOT com
 Febbraio 2011
 
 Adattato per IExplorer e BlackBerry da Nicola S.
 
*/



#include <SPI.h>
#include <Ethernet.h>
#include <string.h>

byte mac[] = {0x00, 0x1E, 0x2A, 0x77, 0x24, 0x02 };
byte ip[] = { 192,168,0,101 };
byte subnet[] = {255,255,255,0};

Server server(80); //-- Porta 80 http.

char homepage[20];
char porta[20];
char pwd[20];
int nPorta;

//-- Parametri personalizzabili
char *path[]={"stc"};  //-- Path per la pagina web default ( es.: http://192.168.1.222/PATH_PERSONALIZZATO )
char *password[]={"123"};  //-- chiave segreta ( solo numerica, senza limiti di lunghezza )
char *tasti[]={"Cancellino", "Basculante", "Cancello", "Apri", "Stop", "Chiudi"};  //-- Descrizioni bottoni interfaccia di controllo



//-- Designazione uscite digitali su Arduino e stato iniziale
void SetupPorte()
{
  for (int pin = 3; pin < 9; pin++) {  //-- uso i pin digitali da 3 a 8
  pinMode(pin,OUTPUT); digitalWrite(pin,LOW);
  }
}

void setup()
{
  Serial.begin(9600);
  SetupPorte();
  Ethernet.begin(mac, ip, subnet);
  server.begin();
}

#define bufferMax 128
int bufferSize;
char buffer[bufferMax];

void loop()
{
  Client client = server.available();
  if (client)
  {
    WaitForRequest(client);
    ParseReceivedRequest();
    PerformRequestedCommands();    
    client.stop();
  }
}

void WaitForRequest(Client client)
{
  bufferSize = 0;
  while (client.connected()) {
    if (client.available()) {
      char c = client.read();
      if (c == '\n')
        break;
      else
        if (bufferSize < bufferMax)
          buffer[bufferSize++] = c;
        else
          break;
        }
  }
  PrintNumber("bufferSize", bufferSize);
}
void ParseReceivedRequest()
{
  Serial.println("in ParseReceivedRequest");
  Serial.println(buffer);
  
  /*
  La richiesta di pagina default va inoltrata verso Arduino nel seguente modo: http://192.168.1.222/PATH_PERSONALIZZATO
  ----------------------
  In caso di richesta pagina default, buffer conterrà      "GET /PATH_PERSONALIZZATO HTTP/1.1"
  In caso di click sui bottoni apriporta, buffer conterrà  "GET /PATH_PERSONALIZZATO?6=DESCRIZIONE_TASTO HTTP/1.1".
  */
  
  char* slash;
  char* uguale;
  char* commerciale;

  slash = strstr(buffer, "/") + 1;          //-- "PATH_PERSONALIZZATO?p=PASSWORD&6=DESCRIZIONE_TASTO HTTP/1.1" oppure "apritisesamo HTTP/1.1"
  uguale = strstr(buffer, "=") + 1;         //-- "PASSWORD&6=DESCRIZIONE_TASTO HTTP/1.1"
  commerciale = strstr(buffer, "&") + 1;    //-- "6=DESCRIZIONE_TASTO HTTP/1.1"
  
  homepage[0] = 0;
  pwd[0] = 0;
  porta[0] = 0;

  strncat(homepage, slash, strlen(path[0]));   //-- Isola il path della richiesta HTTP
  strncat(pwd, uguale, commerciale-uguale-1);  //-- Isola la chiave di accesso inserita da validare
  strncat(porta, commerciale, 1);              //-- Isola il numero di porta da aprite (es.: "6")

  nPorta = porta[0] - '0';                     //-- Numero pin digitale da attivate

  PrintString("Homepage",homepage);
  PrintString("Password",pwd);
  PrintString("Nr. porta da aprire",porta);
}
void PerformRequestedCommands()
{
  if ( strcmp(homepage, path[0]) == 0 and nPorta > 2 and nPorta < 9 and strcmp(pwd, password[0]) == 0 ) RemoteDigitalWrite();  //-- Contronta path, porta e chiave
  if ( strcmp(homepage, path[0]) == 0 ) DefaultWebPage();
}
void DefaultWebPage()
{
  //-- Invio pagine web
  server.println("HTTP/1.1 200 OK");
  server.println("Content-Type: text/html");
  server.println();
  server.print("<html>");
  server.print("<head>");
  server.print("<meta content=text/html");
  server.print("charset=utf-8 http-equiv=content-type />");
  server.print("<title>Domotica STC</title>");
   
    if (nPorta > 2 and nPorta < 9 and strcmp(pwd, password[0]) == 0) {  //-- Se porta e chiave sono validi, redirect pagina web entro 2 secondi
     server.print("<META HTTP-EQUIV=refresh CONTENT=2;URL=");
      server.print(path[0]);
      server.print(">");
    }    
       //-- Foglio di stile + javascript per gestione tastiera virtuale.

  server.print("<style type=text/css>");
  server.print("body{background:#0259A1;text-align:center;margin-top:20px;font-family:sans-serif;font-size:70px;font-weight:bold;color:#FFF;}");
  server.print("input{padding:20px 15px;width:47%;margin:15px 1%;font-family:sans-serif;font-size:70px;font-weight:bold;color:#000;}");
  server.print("</style>");
  server.print("<script type=text/javascript>function accoda(b){b.form.p.value+=b.value}</script>");
  server.print("</head>");
   server.print("<body>");
    if (nPorta > 2 and nPorta < 9 and strcmp(pwd, password[0]) == 0) {  //--  Se porta e chiave sono validi, notifica avvenuta apertura
        Serial.println("*** Apertura ***");  //-- Debug in seriale
        server.print("<div>");
        server.print("Attivato");
        server.print("</div>");
        server.print("<div style=font-size:50px;>Pin digitale ");
        server.print(nPorta, DEC);
        server.print("</div>");
        }
      else {  //-- Pagina web default
        Serial.println("*** DefaultWebPage ***");  //-- Debug in seriale
        server.print("<form method=GET>");
       // server.print("<form name='apriporte' action='' enctype='text/plain' method='get'>"); // non si aggiorna automaticamente
        server.print("<input style=background:#000;width:50%;color:#FFF;text-align:center;border:2px solid #57AEF6; type=tex' name=p>");
        server.print("
<div style=height:15px;></div>");
         //-- Crea i bottoni di apertura
         for (int conta = 0; conta < 6; conta++) {
           if (tasti[conta] != "") {  //-- Crea solo i bottoni a cui è associata una descrizione ( vedi array: tasti[] )
             server.print("<input type=submit name=");
             server.print(conta + 3);
             server.print(" value=");
             server.print(tasti[conta]);
             server.print(">");
             }}
      server.print("
<div style=height:30px;></div>");
         //-- crea la tastiera numerica
         for (int conta = 0; conta < 10; conta++) {
             server.print("<input style=width:24%;margin:3px;background:#000;color:#FFF;' type=button value=");
             server.print(conta);
             server.print(" onclick=accoda(this)>");
         }
       server.print("<input style=width:48.5%;margin:3px;background:#8F0000;color:FFF; type=reset value=Canc>");
       server.print("</form>");
       }
  server.print("</body></html>");
}
void RemoteDigitalWrite()
{
  digitalWrite(nPorta, HIGH);  //-- Attivo l'uscita digitale
  delay(500);
  digitalWrite(nPorta, LOW);
  
  Serial.println("RemoteDigitalWrite");
  PrintNumber("Porta", nPorta);
}
void PrintString(char* label, char* str)
{
  Serial.print(label);
  Serial.print("=");
  Serial.println(str);
}
void PrintNumber(char* label, int number)
{
  Serial.print(label);
  Serial.print("=");
  Serial.println(number, DEC);
}

Ragazzi un aiuto XD
Faccio una faticaccia a trovare il relè che ha utilizzato nella foto dr4gone =(
Conoscete per favore delle alternative da consigliarmi?

Grazie

giga:
Ragazzi un aiuto XD
Faccio una faticaccia a trovare il relè che ha utilizzato nella foto dr4gone =(
Conoscete per favore delle alternative da consigliarmi?

Grazie

Leggi qua

Ciao scusate se scrivo su un post vecchio.
Volevo però chiedere se era possibile avere lo schema del circuito del relè con stadio pilota mostrato nella figura, in cui sono indicati i dettagli dei componenti utilizzati

grazie mille anticipatamente

michele