Un semplice antifurto: collegamento ethernet shield

The estimated reading time for this post is 329 seconds

Ciao di nuovo, mi è arrivata finalmente a casa l’ethernet shield ed è ora di studiarla un po!
Quello che voglio capire è come inviare una mail al mio indirizzo di posta.

Il collegamento ad Arduino UNO è semplicissimo, un’immagine vale più di 1000 parole!

FZ05SN7H05NT26I.MEDIUM(da instructables.com)

Quindi colleghiamo la presa RJ45 al nostro router e il cavo USB di alimentazione alla presa di alimentazione di Arduino UNO (vedi figura).

FDP0VOXH05NHCWO.MEDIUM(da instructables.com)

Le informazioni fondamentali per procedere sono:

  1. impostazione ip della ethernet shield
  2. impostazione mac address della ethernet shield
  3. impostazioni del server SMTP per invio della mail

Il mio router è in DHCP, quindi assegna automaticamente gli indirizzi ip.
Non ci sono problemi per il  MAC Address in quanto si può assegnare un numero in modo arbitrario.

A questo punto ho scoperto ci possono essere due strade per l’invio delle email:

1. Il servizio Temboo mette a disposizione una libreria per l’invio mail tramite gmail (qui le istruzioni)
2. il servizio SMTP2GO che permette di inviare fino a 10 email tramite il proprio SMTP gratuito (registrazione qui).

Ho optato per la seconda strada (servizio SMTP2GO)…soprattutto perche ho scoperto Temboo quando ormai avevo finito di sviluppare con SMTP2GO! Zero voglia di provare Temboo!!!!!
Anzi, se qualcuno ha effettuato delle prove sarei felice di sentire una loro opinione. Thanks

Lato codice ho utlizzato quanto scritto da Nicolaj Joergensen:

#include <SPI.h>;
#include <Ethernet.h>;
 
// Arduino network information
byte mac[] = { 0x00, 0xAA, 0xBB, 0xCC, 0xDE, 0x02 };
EthernetClient client;
char smtpServer[] = "smtpcorp.com";
 
void setup()
{
  Serial.begin(9600);  // per debug
  setupComm();
}
 
void loop()
{
  email("ciao");
  delay(1000);
}
 
// Inizializzazione connessione ethernet shield
void setupComm()
{
  Serial.println("Trying to connect");
  if (!Ethernet.begin(mac)){
    Serial.println("Failed to DHCP");
    // verifica della connessione
    while(true);
  }
  delay(10000);
 
  // individuazione dell'indirizzo IP:
  Serial.print("IP address: ");
  for (byte thisByte = 0; thisByte < 4; thisByte++) {
    Serial.print(Ethernet.localIP()[thisByte], DEC);
    Serial.print(".");
  }
  Serial.println();
}
 
// Invio effettivo della mail
bool email(char* text)
{
  bool success = false;
  Serial.println("Sending email...");
 
  if (client.connect(smtpServer, 2525)){            //2525 è la porta del SMTP Server
    Serial.println("connected");
    delay(100);
    client.println("EHLO arduino");
    for(int i=0; i<999; ++i){
      if(client.read() > 0)
        break;
    }
    Serial.println("responded");
 
    client.println("AUTH LOGIN");                     //vedi "http://base64-encoder-online.waraxe.us/"
    client.println("xxxxxxxxxx");           //Username in base 64
    client.println("yyyyyyyyyy");        //Password in base 64
 
    // Put your "from" email address here
    client.println("MAIL FROM:<dumm@gmail.com>"); //Sembra non importi molto quanto scritto qui...
    for(int i=0; i<999; ++i){
      if(client.read() > 0)
      break;
    } 
 
    // Indirizzo di destinazione
    client.println("RCPT TO:<mail@mail.com>"); 
 
    for(int i=0; i<999; ++i){
      if(client.read() > 0)
      break;
    } 
 
    client.println("DATA");
    for(int i=0; i<999; ++i){
      if(client.read() > 0)
        break;
    }
    //Sender
    client.println("from: mail@mail.com"); //Sender address visualizzato nella mail
    client.println("to: mail@mail.com");  //Receiver address visualizzato dalla mail
    client.println("SUBJECT: From your arduino");
    client.println("");
    client.println(text);
    client.println(".");
    client.println("QUIT");
    for(int i=0; i<999; ++i){
      if(i > 998){Serial.println("error: No response");}
      if(client.read() > 0)
        break;
    }
    success = true;
    client.println();
    Serial.println("end");
  } else {
    Serial.println("Failed");
    client.println("QUIT"); //Disconnessione
  }
  client.stop();
  return success;
}

Spiegazione del codice:

riga  5: impostazione del MAC Address: potete scrivere quello il numero che preferite!
riga  7: indirizzo del server SMTP
riga 17:chiamata alla funzione effettiva di invio email. Verrà inviata una mail con testo ciao
riga 25: inizializzazione della scheda ethernet
riga 34-35: visualizzazione dell’indirizzo IP assegnato in DHCP da mio router. Utile se vogliamo fare in modo che la scheda ethernet possa essere utilizzata come webserver e quindi richiamata da un browser.
riga 42: vengono inviati al server SMTP i comandi per l’invio della mail.
riga 58:  username del servizio SMTP2GO in base 64.
riga 59: password del servizio SMTP2GO in base 64.
E’ comodo utilizzare questo servizio per trasformare in base 64: http://base64-encoder-online.waraxe.us/
Per esempio la username CICCIO diventa Q0lDQ0lP

Caricato il programma ed uploadato su Arduino UNO ho ricevuto la mia prima mail!
Ho messo un delay alla riga 18, quindi ogni 10 secondi viene inviata una mail! Prestate attenzione con le prove perchè SMTP2GO mette a disposizione (nella versione free) solo l’invio di 10 mail giornaliere

Ho finito con la sperimentazione della ethernet shield per oggi…ho ottenuto quello che volevo.

Lo step successivo è di inviare una mail personalizzata nel momento in cui un sensore dell’antifurto riceve un segnale: la mail dovrà indicarmi quale sensore ha fatto scattare l’allarme (sensore porta, finestra, rumore) con relativa ora.

Ci vediamo alla prossima! (spero presto…)

Ps. Nel frattempo mi è arrivato arduino nano… 🙂 🙂

31 thoughts to “Un semplice antifurto: collegamento ethernet shield”

  1. complimenti per tutto quello che hai fatto seguo con interesse, ho copiato il codice sopra mi da errore, risulta?

    1. Ciao!
      Hai ragione!!!!!

      Nel copiare ed incollare ho creato qualche problema! 🙁
      Modifico l’articolo con le dovute correzioni.

      Grazie per avermi fatto notare la cosa, buona giornata.

      Giuseppe

    2. ecco gli errori
      Arduino:1.6.2 (Windows 8.1), Scheda:”Arduino Uno”

      sketch_jun11a.ino: In function ‘void setupComm()’:

      sketch_jun11a.ino:26:36: error: expected ‘)’ before ‘;’ token

      sketch_jun11a.ino:26:37: error: expected primary-expression before ‘)’ token

      sketch_jun11a.ino:26:37: error: expected ‘;’ before ‘)’ token

      sketch_jun11a.ino: In function ‘bool email(char*)’:

      sketch_jun11a.ino:62:48: error: expected ‘)’ before ‘;’ token

      sketch_jun11a.ino:62:49: error: expected primary-expression before ‘)’ token

      sketch_jun11a.ino:62:49: error: expected ‘;’ before ‘)’ token

      sketch_jun11a.ino:83:39: error: expected ‘)’ before ‘;’ token

      sketch_jun11a.ino:83:40: error: expected primary-expression before ‘)’ token

      sketch_jun11a.ino:83:40: error: expected ‘;’ before ‘)’ token

      sketch_jun11a.ino:89:24: error: expected primary-expression before ‘;’ token

      sketch_jun11a.ino:89:29: error: expected ‘)’ before ‘;’ token

      sketch_jun11a.ino:89:33: error: name lookup of ‘i’ changed for ISO ‘for’ scoping [-fpermissive]

      sketch_jun11a.ino:89:33: note: (if you use ‘-fpermissive’ G++ will accept your code)

      sketch_jun11a.ino:89:34: error: expected ‘;’ before ‘)’ token

      sketch_jun11a.ino:105:1: error: expected ‘}’ at end of input

      sketch_jun11a.ino:105:1: error: expected ‘}’ at end of input

      Errore durante la compilazione

        1. errori non ne da piu ma non si connette “failed to DHCP”
          ho inserito mio user e password alle rige 58 e 59 e non ho fatto altro, ho dimenticato qualcosa?

          1. enable dhcp server yes
            dhcp ip address range da xxx.xxx.x.2 a xxx.xxx.x.254

  2. prova a forzare l’ip, mettendono uno nel range che mi hai indicato.
    Dichiara:
    byte ip[] = { xxx, xxx, xxx, xxx }; //setta l’ip

    poi, invece della funzione Ethernet.begin(mac) usa : Ethernet.begin(mac, ip);

    fammi sapere

  3. Arduino:1.6.2 (Windows 8.1), Scheda:”Arduino Uno”

    sketch_jun11a.ino: In function ‘void setupComm()’:

    sketch_jun11a.ino:26:30: error: could not convert ‘Ethernet.EthernetClass::begin(((byte*)(& mac)), IPAddress(((const uint8_t*)(& ip))))’ from ‘void’ to ‘bool’

    sketch_jun11a.ino:26:30: error: in argument to unary !

    Errore durante la compilazione

    Questo report potrebbe essere più ricco
    di informazioni con
    “Mostra un output dettagliato durante la compilazione”
    abilitato in “File > Impostazioni”

  4. Prova cosi:

    void setupComm()
    {
    Serial.println(“Trying to connect”);
    Ethernet.begin(mac, ip);
    Serial.println(“Collegato”);
    delay(1000);

    // individuazione dell’indirizzo IP:
    Serial.print(“IP address: “);
    for (byte thisByte = 0; thisByte < 4; thisByte++) { Serial.print(Ethernet.localIP()[thisByte], DEC); Serial.print("."); } }

  5. nulla :
    Arduino:1.6.2 (Windows 8.1), Scheda:”Arduino Uno”

    sketch_jun11a.ino:25:3: error: stray ‘\’ in program

    sketch_jun11a.ino:25:3: error: stray ‘\’ in program

    sketch_jun11a.ino:27:3: error: stray ‘\’ in program

    sketch_jun11a.ino:27:3: error: stray ‘\’ in program

    sketch_jun11a.ino:31:3: error: stray ‘\’ in program

    sketch_jun11a.ino:31:3: error: stray ‘\’ in program

    sketch_jun11a.ino:34:5: error: stray ‘\’ in program

    sketch_jun11a.ino:34:5: error: stray ‘\’ in program

    sketch_jun11a.ino: In function ‘void setupComm()’:

    sketch_jun11a.ino:25:19: error: ‘u201cTrying’ was not declared in this scope

    sketch_jun11a.ino:27:19: error: ‘u201cCollegato’ was not declared in this scope

    sketch_jun11a.ino:31:17: error: ‘u201cIP’ was not declared in this scope

    sketch_jun11a.ino:34:19: error: ‘u201c’ was not declared in this scope

    Errore durante la compilazione

  6. Ciao, copia questo:

    #include <SPI.h>;
    #include <Ethernet.h>;
      
    // Arduino network information
    byte mac[] = { 0x00, 0xAA, 0xBB, 0xCC, 0xDE, 0x02 };
    byte ip[] = { 10, 0, 0, 177 };
    EthernetClient client;
    char smtpServer[] = "smtpcorp.com";
      
    void setup()
    {
      Serial.begin(9600);  // per debug
      setupComm();
    }
      
    void loop()
    {
      email("ciao");
      delay(1000);
    }
      
    // Inizializzazione connessione ethernet shield
    void setupComm()
    {
      Serial.println("Trying to connect");
      Ethernet.begin(mac, ip);
      Serial.println("Collegato");  
      delay(1000);
      
      // individuazione dell'indirizzo IP:
      Serial.print("IP address: ");
      for (byte thisByte = 0; thisByte < 4; thisByte++) {
        Serial.print(Ethernet.localIP()[thisByte], DEC);
        Serial.print(".");
      }
    
    }
      
    // Invio effettivo della mail
    bool email(char* text)
    {
      bool success = false;
      Serial.println("Sending email...");
      
      if (client.connect(smtpServer, 2525)){            //2525 è la porta del SMTP Server
        Serial.println("connected");
        delay(100);
        client.println("EHLO arduino");
        for(int i=0; i<999; ++i){
          if(client.read() > 0)
            break;
        }
        Serial.println("responded");
      
        client.println("AUTH LOGIN");                     //vedi "http://base64-encoder-online.waraxe.us/"
        client.println("xxxxxxxxxx");           //Username in base 64
        client.println("yyyyyyyyyy");        //Password in base 64
      
        // Put your "from" email address here
        client.println("MAIL FROM:<dumm@gmail.com>"); //Sembra non importi molto quanto scritto qui...
        for(int i=0; i<999; ++i){
          if(client.read() > 0)
          break;
        } 
      
        // Indirizzo di destinazione
        client.println("RCPT TO:<mail@mail.com>"); 
      
        for(int i=0; i<999; ++i){
          if(client.read() > 0)
          break;
        } 
      
        client.println("DATA");
        for(int i=0; i<999; ++i){
          if(client.read() > 0)
            break;
        }
        //Sender
        client.println("from: mail@mail.com"); //Sender address visualizzato nella mail
        client.println("to: mail@mail.com");  //Receiver address visualizzato dalla mail
        client.println("SUBJECT: From your arduino");
        client.println("");
        client.println(text);
        client.println(".");
        client.println("QUIT");
        for(int i=0; i<999; ++i){
          if(i > 998){Serial.println("error: No response");}
          if(client.read() > 0)
            break;
        }
        success = true;
        client.println();
        Serial.println("end");
      } else {
        Serial.println("Failed");
        client.println("QUIT"); //Disconnessione
      }
      client.stop();
      return success;
    }
    

    Ho provato ora e lo compila senza errori.

  7. ora compila non riconosceva le virgolette (“) si connette
    mi dice collegato
    ip address 192.xxx.xxx.xxx (che ho messo nel codice
    sending mail….
    Failed

  8. Hai creato l’account su smtpcorp.com?
    Se si, verifica sul sito se è stato fatto un tentativo di accesso (ci dovrebbe essere nel pannello iniziale una dicitura del tipo “Emails Sent Today”)

  9. I dati di username e password, come quello del server smtp, devono essere di smtpcorp, non so se nell’articolo sono stato chiaro

  10. Devi utilizzare l’autenticazione.

    nel mio caso:

    EHLO giuseppe.scola

    AUTH LOGIN (e qui copi username in base64 e premi invio, poi password in base64 e premi invio)

    il server a questo punto dovrebbe risponderti con un:
    235 Authentication succeeded

    a questo punto prosegui con mail from: e rcpt to: come hai fatto tu.

    Fammi sapere

    1. Ciao Leonardo, scusa ho letto solo ora il tuo commento!
      In effetti in questo codice viene inviata una mail ogni secondo.
      Questo codice è solo per verificare se i parametri e settaggi sono corretti.
      Potresti far partire la mail solo se determinati eventi avvengono, quindi puoi metterci una “if” all’interno del codice.
      Per esempio potresti aggiungere un bottone e se viene premuto viene inviata la mail.
      Se hai bisogno di ulteriori dettagli o se non sono stato chiaro sono qui!

      Ciao!

      1. Ciao GiuseppeScola! Non mi è chiaro il metodo dell’if… non saprei dove inserirlo nel codice che hai postato! il mio progetto sarebbe quello di inserire il tuo intero progetto in una VOID e richiamarla solamente quando si verifica una condizione (per esempio se scatta un ipotetico allarme), quindi mi servirebbe che inviasse una sola e-mail! Non so se mi sono spiegato… Aspetto tue notizie e grazie per l’aiuto!

        Ciao!!

        1. Ciao,

          La if la dovresti inserire in questo ciclo:

          void loop()
          {
            email("ciao");
            delay(1000);
          }
          

          quindi:

          void loop()
          {
          	if (evento == true) {
          		email("ciao");
          		delay(1000);
          	}
          }
          

          L’evento lo decidi tu.
          Comunque se leggi l’articolo successivo a questo vedrai che è spiegato.
          Nel prossimo articolo infatti la mail viene inviata solo se viene rilevato un rumore o viene attivato un antifurto.
          Fammi sapere se è più chiaro.

          Giuseppe

  11. Ciao, grazie mille per la dritta! Ora funziona perfettamente inviando una sola email! Ho bisogno, però, di eliminare tutti i delay in quanto è fondamentale, in questo mio progetto, che il processore non sia interrotto. Uso spesso la funzione millis, ma in questo esempio non so come utilizzarla! Avresti gentilmente qualche suggerimento?

    Grazie in anticipo!
    Leonardo

Rispondi