Un semplice antifurto: salvare i codici sensori tramite interfaccia web

Non ci posso credere! E’ quasi Natale!! Sono troppo contento…finalmente un po di relax!

Torniamo al nostro arduino…come detto la volta scorsa voglio fare in modo che i codici sensori possano essere memorizzati nelle EEPROM, il tutto da interfaccia web!
Ecco il codice che esegue questa cosa:

#include <String.h>
#include <Time.h>
#include <SPI.h>
#include <Ethernet.h>
#include <EEPROM.h>
#include <RCSwitch.h>

byte mac[] = {
  0x00, 0xAA, 0xBB, 0xCC, 0xDE, 0x02 };
int SERIAL_BAUD        = 9600;
EthernetServer server(8081);
RCSwitch mySwitch = RCSwitch();
int RECEIVE_PIN       = 0;
int nSensori = 5;

void setup() {
  Serial.begin(SERIAL_BAUD);
  setupComm();
  mySwitch.enableReceive(RECEIVE_PIN);
}

void loop() {
  getClientConnection();
}

void getClientConnection(){

  EthernetClient client = server.available();
  if (client) {
    String postString ="";
    Serial.println("nuova richiesta");
    boolean currentLineIsBlank = true;
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        if(postString.length()<15){
          postString +=c;
        }

        if (c == 'n' && currentLineIsBlank) {
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println("Connection: close");  // the connection will be closed after completion of the response
          client.println();
          client.println("<!DOCTYPE HTML>");
          client.println("<html>");
          client.println("<h1>Configurazione</h1>");
          client.print("<br>");

          for (int i=0; i<nSensori; i++)
          {
            String linkCompleto = "";
            linkCompleto = "<a href="./?save"+ String(i);
            linkCompleto +="">Salva Sensore " + String(i);
            linkCompleto += "</a><br/>";
            client.println(linkCompleto);
            Serial.println(linkCompleto);
            //client.println("<a href="./?save1">Salva Sensore 1</a>");
          }

          client.println("<br/>");
          client.println("<a href="./?elenco">Visualizza dati sensori</a>");
          client.println("</html>");
          break;
          //}
        }

        if (c == 'n') {
          // you're starting a new line
          currentLineIsBlank = true;
        }
        else if (c != 'r') {
          // you've gotten a character on the current line
          currentLineIsBlank = false;
        }

      }
    }  //fine client.connected 

    Serial.println("-------------");
    Serial.println(postString);
    Serial.println("-------------");

    if(postString.indexOf("?save") > 0){ 

      int indexSave = postString.indexOf("?save");
      Serial.println("indexOf");
      Serial.println(indexSave);
      //cerco valore del sensore
      String sSensore = postString.substring(indexSave+5 ,indexSave+6);
      Serial.println("Sensore");
      Serial.println(sSensore);
      int iSensore = sSensore.toInt();
      long valore = salvaSensore(iSensore);
      client.println("<br/>");
      client.println("<p>Salvataggio sensore effettuato</p>");
      client.println("<br/>");
      client.println("Codice sensore " + sSensore);
      client.print(valore);
    }   

    if(postString.indexOf("?elenco") > 0){
      for (int i=0; i<nSensori; i++)
      {
        client.println("<p>Sensore " + String(i)+" : </p>");
        client.print(String(EEPROMReadlong(i*4)));
        Serial.println(EEPROMReadlong(i*4));
      }
    }

    delay(1);
    // close the connection:
    client.stop();
    Serial.println("client disonnected");
  }
}

long salvaSensore(int iSensore)
{
  int addressTosSave = iSensore*4;
  long valore = 0;
  Serial.println("salvaSensore");
  if (mySwitch.available()) {
    Serial.println("mySwitch.available");
    valore = mySwitch.getReceivedValue();
    Serial.println("valore ");
    Serial.print(valore);
    EEPROMWritelong(addressTosSave,valore);
  }
  delay(1000);
  return valore;
} 

void EEPROMWritelong(int address, long value)
{
  //Decomposition from a long to 4 bytes by using bitshift.
  //One = Most significant -> Four = Least significant byte
  byte four = (value & 0xFF);
  byte three = ((value >> 8) & 0xFF);
  byte two = ((value >> 16) & 0xFF);
  byte one = ((value >> 24) & 0xFF);

  //Write the 4 bytes into the eeprom memory.
  EEPROM.write(address, four);
  EEPROM.write(address + 1, three);
  EEPROM.write(address + 2, two);
  EEPROM.write(address + 3, one);
}

void setupComm()
{
  Serial.println("Trying to connect");
  Serial.print("n");
  if (!Ethernet.begin(mac)){
    Serial.println("Failed to DHCP");
    // no point in carrying on, so do nothing forevermore:
    while(true);
  }

  // print your local IP address:
  Serial.print("My IP address: ");
  for (byte thisByte = 0; thisByte < 4; thisByte++) {
    // print the value of each byte of the IP address:
    Serial.print(Ethernet.localIP()[thisByte], DEC);
    Serial.print(".");
  }
  Serial.println("fine");
}

long EEPROMReadlong(long address)
{
  //Read the 4 bytes from the eeprom memory.
  long four = EEPROM.read(address);
  long three = EEPROM.read(address + 1);
  long two = EEPROM.read(address + 2);
  long one = EEPROM.read(address + 3);

  //Return the recomposed long by using bitshift.
  return ((four << 0) & 0xFF) + ((three << 8) & 0xFFFF) + ((two << 16) & 0xFFFFFF) + ((one << 24) & 0xFFFFFFFF);
}

L’interfaccia risultante su web è la seguente: (evitate commenti 🙂 )

Ricordo che per accedere alla pagina internet è necessario scrivere nel browser l’indirizzo ip che viene stampato nella console di arduino, specificando inoltre la porta 8081.
Nel mio caso, ad esempio: 192.168.1.136:8081

Sono presenti 5 link che permettono di salvare i dati di 5 sensori: premendo il link “Salva sensore 0” ed azionando il sensore (aprendo la porta per esempio) viene memorizzato il dato nella eeprom.

Schermata 2014-12-17 alle 22.31.29

Una volta salvati i dati è possibile visualizzare un elenco riepilogativo di quanto è presente nella EEPROM, cliccando “Visualizza dati sensori”.
Schermata 2014-12-17 alle 22.31.01

Se riesco in serata posto un video dove si vede meglio il funzionamento.
Il codice è relativamente semplice.
Tralasciando la parte di collegamento alla ethernet shield (già spiegata nei precedenti articoli) passiamo a come vengono generati i link e la loro gestione.

riga 14: viene dichiarato nSensori, cioè il numero di sensori che voglio gestire
riga 53-61: viene creato il link in modo dinamico secondo la sintassi html. Il link che viene richiamato sarà del tipo save0, save1, save2..., a seconda del link che si vuole premere.
riga 63-65: creazione del link per elenco dei sensori memorizzati
riga 81-97: gestione del salvataggio del codice sensore.
Nel dettaglio:
riga 81: nella querystring è presente “salva”, quindi è stato richiesto un salvataggio
riga 87: ricavo quale sensore deve essere salvato (sensore0, sensore1, sensore2..)
riga 91: chiamo la funzione salvaSensore: attiva la funzione mySwitch.getReceivedValue() per stabilire il codice del sensore per poi salvarlo nelle EEPROM
riga 92-96: stampa del codice sensore salvato
riga 100-107: viene visualizzalo l’elenco dei sensori salvati; è un semplice ciclo for che va a leggere con la funzione EEPROMReadlong ogni singolo sensore.
A questo punto, nel prossimo articolo, implementeremo quanto visto oggi nel nostro antifurto!

Dai divertente no???? 🙂

Parliamo di cose più serie ora…che dirvi…

BUON NATALE!!!!!!!!!