A simple arduino burglar alarm: save sensor codes via web interface

As mentioned last time I want to make sure that the codes sensors can be stored in the EEPROM , all from a web interface !
Here’s the code that does this thing :

#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 +="">Save Sensor " + 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">Sensors list</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>Sensor" + 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);
}

The resulting web interface is as follow : (avoid comments 🙂 )

You must write in the browser the IP address that is printed in the Arduino console and also specifying port 8081 .
In my case , for example : 192.168.1.136:8081
There are 5 links that allow you to save the data sensors : pressing the button ” Save sensor 0 ” and pressing the sensor ( opening the door for example ) is stored the data in the EEPROM .

Schermata 2014-12-17 alle 22.31.29

Once data is saved , clicking ” View data sensors .”, you can view a summary list of what is saved in the EEPROM.

Schermata 2014-12-17 alle 22.31.01

Thie evening if I’ll have time I’ll make a video where you can see better storing operations.
The code is relatively simple.
I now try to explain how this links are done and their management.

line 14: Declaring variable nSensori: the number of sensors that I want to manage
line 53-57: Links are created dynamically according to the html syntax.
Links have this format: save0 , SAVE1 , SAVE2 . .. , depending on the link you want to press .
line 62: link to view stored code sensors.
riga 86-99: I save codes sensor
In detail:
line 84: I received “save” in the querystring, I know I need to save a sensor code…which one?
line 90: now i know the sensor code number!
line 94: I call salvaSensore: function: this function use mySwitch.getReceivedValue() function to save code sensor in the EEPROM.
line 95-99: I write in the HTML page the code sensor just saved
line 102-109: I write in HTML page the saved sensor list.it’s a simple for cycle that use  EEPROMReadlong to read each sensor code.
At this point , in the next article , we will implement what we saw today in our anti-theft !

So funny!!!!

See you soon!

A simple burglar: code explanation

As told last week I want to comment the code.

For convenience I copy it again:

/*
 Ricezione dai sensori porte
 Trasmissione verso telecamera
 rivelazione rumore
 http://code.google.com/p/rc-switch/
 Need help? http://forum.ardumote.com
 */

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

/* Informazioni Ethernet*/

byte mac[] = {
  0x00, 0xAA, 0xBB, 0xCC, 0xDE, 0x02 };
int SERIAL_BAUD        = 9600;
int TRASMIT_PIN       = 9;
int RECEIVE_PIN       = 0;
int NOISE_DIGITAL_PIN =    5;
//Sensori
long PORTA_INGRESSO_SENSORE  = 3557625;
long PORTA_CUCINA_SENSORE = 10521177;
long SEGNALE_ACCENZIONE_WEBCAM = 1394001;
long SEGNALE_SPEGNIMENTO_WEBCAM= 1394004;

EthernetClient client;
EthernetServer server(8081);
char smtpServer[] = "smtpcorp.com";
RCSwitch mySwitch = RCSwitch();

void setup() {
  Serial.begin(SERIAL_BAUD);
  pinMode(SERIAL_BAUD, INPUT);
  mySwitch.enableReceive(RECEIVE_PIN);
  mySwitch.enableTransmit(TRASMIT_PIN);
  setupComm();
}

void loop() {

  getClientConnection();
  if (detectNoise()){
    Serial.print("Rumore");
    email("Waring, noise in the house!");
    accendiCam(SEGNALE_ACCENZIONE_WEBCAM) ;
  }

  if (mySwitch.available()) {

    int value = mySwitch.getReceivedValue();

    Serial.print(value);
    if (value == 0) {
      Serial.print("Unknown encoding");
      Serial.print("n");
    }
    else {
      long receivedValue = mySwitch.getReceivedValue();
      if (receivedValue == PORTA_INGRESSO_SENSORE) {
        Serial.print("Warning! Door open!");
        Serial.print("n");
        email("Warning, Door open!");
        accendiCam(SEGNALE_ACCENZIONE_WEBCAM) ;
        delay(1000);
      }
      else if(receivedValue == PORTA_CUCINA_SENSORE) {
        Serial.print("Warning! Porta cucina aperta!");
        Serial.print("n");
        email("Attenzione, porta cucina aperta!");
        accendiCam(SEGNALE_ACCENZIONE_WEBCAM) ;
        delay(1000);
      }  

      Serial.print("Received ");
      Serial.print( receivedValue);
      Serial.print(" / ");
      Serial.print( mySwitch.getReceivedBitlength() );
      Serial.print("bit ");
      Serial.print("Protocol: ");
      Serial.println( mySwitch.getReceivedProtocol() );
    }

    mySwitch.resetAvailable();
  }

}

bool detectNoise ()
{
  bool rit = false;
  if (digitalRead(NOISE_DIGITAL_PIN) == HIGH)
  {
    rit = true;
  }
  return rit;
} 

void accendiCam(long value)
{
  mySwitch.send(value, 24);
  mySwitch.send(value, 24);
  mySwitch.send(value, 24);
  mySwitch.send(value, 24);
  mySwitch.send(value, 24);
} 

void setupComm()
{
  Serial.println("Trying to connect");
  Serial.print("n");
  if (!Ethernet.begin(mac)){
    Serial.println("Failed to DHCP");
    while(true);
  }

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

// Call to send an email.
bool email(char* text)
{
  bool success = false;
  Serial.println("Sending email...");
  Serial.print("n");
  Serial.println("SMTP server...");
  Serial.print(smtpServer); 

  if (client.connect(smtpServer, 2525)){
    Serial.println("connected");
    delay(100);
    client.println("EHLO arduino");
    for(int i=0; i<999; ++i){
      if(client.read() > 0)
        break;
    }
    Serial.println("responded");
    Serial.print("n");
    client.println("AUTH LOGIN");
    client.println("xxxxxxx");           //vedi precedente post per la spiegazione
    client.println("yyyyyy");   //vedi precedenti post per la spiegazione     

    client.println("MAIL FROM:<dumm@gmail.com>");
    for(int i=0; i<999; ++i){
      if(client.read() > 0)
        break;
    } 

    client.println("RCPT TO:<giuseppe.scola@gmail.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;
    }

    client.println("from: giuseppe.scola@gmail.com");
    client.println("to: giuseppe.scola@gmail.com");
    client.println("SUBJECT: ArduAlarm");
    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");
    Serial.print("n");
  }
  else {
    Serial.println("Failed");
    Serial.print("n");
    client.println("QUIT");
  }
  client.stop();
  return success;
}

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();
        //postString.concat(c);
        if(postString.length()<10){
          postString +=c;
        }
        // Serial.write(c);
        if (c == 'n' && currentLineIsBlank) {
          //if(readString.indexOf("id=1") > 0){
          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("Refresh: 5");  // refresh the page automatically every 5 sec
          client.println();
          client.println("<!DOCTYPE HTML>");
          client.println("<html>");
          //client.println("<h1>Settaggi</h1><br>");
          client.println("<h1>AllarDuino</h1>");
          client.print("<br>");
          client.println("<a href="./?on">Accendi CAM</a>");
          client.println("<a href="./?off">Spegni CAM</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("?on") > 0){
      Serial.println("accendi CAM");
      accendiCam(SEGNALE_ACCENZIONE_WEBCAM);
      client.println("<br/>");
      client.println("<p>Cam accesa</p>");

    }
    if(postString.indexOf("?off") > 0){
      accendiCam(SEGNALE_SPEGNIMENTO_WEBCAM);
      client.println("<br/>");
      client.println("<p>Cam spenta</p>");
    } 

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

The “new” code is to power on/off the webcam from a client/browser.

This new feature allows you to manage calls coming from browser to Arduino, acting as a server.
In our case Arduino will listen incoming request at 8081 port as specified at line 32  EthernetServer server(8081);

At line 116 I start the server  with setupComm function (I set MAC code in the begin function).
In the loop funcion I call getClientConnection:

  • line 201: Checking if a client is sending a new request to the Arduino server.
  • line 202: if a request is incoming…
  • line 207: if client is reacheble….
  • line 298->231: I read the data sent from the client until I reach the end line (\n) and line empty: now I know I received all the datas from the client and the server (Arduino) can send the answer. Arduino send HTTP/1.1 200 OK status, all is ok! and an html page like the image :
    paginaAllarmDuino(I know..it’s an ugly page…)
    Pressing Accendi Cam (Power on Cam) I call server with the ?on paramenter in the query string while pressing Spegni Cam (Power off Cam) I call the server with ?off paramenter.
  • line 249 and line 256: I check which of the two parameters was sent to server and I act accordingly: I turn on or off the cam.
  • I finally close the connection

Well…I hope I was clear, let me know please…
I’d like to have feedbacks and comments!

The next step is to write code more customize.
I want to save the sensor code in the EEPROM and read when I need.

I have to study Arduino memory!

Have a good day!

A simple burglar Alarm: motion sensor, noise sensor and ethernet shield all together

I’m back … forced home by the Seveso  flood (a river here in Milan) I take this opportunity to update the blog.

In previous post we have :

  • read motion sensors data
  • read sensor noise data
  • connected the ethernet shield and sent an email

At this point we can put all together.

But i want also to use the webcam I have at home (model D-Link DCS-930L).

I don’t want to let on the webcam the whole day, I want to turn on only if a movement/noise is detected and I want to be able to turn on or off  from intenet.

I decided to buy a wireless power strip like this.
I can connect webcam to power strip and turn or/off the power strip (and then the webcam) with Arduino.
I have only to know the power strip sensor code as done in the previous post with the movement sensor.

Using the power strip remote I read this codes:

power strip turn on code power strip turn off code
1394001 1394004

Now I have all the codes I need. Now I have to connect wireless trasmitter to Arduino.

Here is the final result:

I had to modify the connections made in the previous posts because ethernet shield use exclusively pin 10,11,12 and 13 .

Here we are the new connections between arduino and trasmitter and receiver modules.

 

Noise sensor

Vcc 5 V
GND GND
SNG Pin 5 (digital)

 

Receiver sensor at  433 Mhz

Receiver  Pin Pin Arduino
Vcc 5 V
GND GND
DATA Pin 2 (digital)

 

Trasmitter Sensor 433 Mhz

Trasmitter Pin Pin Arduino
Vcc 5 V
GND GND
DATA Pin 9 (digital)

 

Here comes the complete code :



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

/* Informazioni Ethernet*/

byte mac[] = {
  0x00, 0xAA, 0xBB, 0xCC, 0xDE, 0x02 };
int SERIAL_BAUD        = 9600;
int TRASMIT_PIN       = 9;
int RECEIVE_PIN       = 0;
int NOISE_DIGITAL_PIN =    5;
//Sensori
long CODE_DOOR_SENSOR  = 3557625;	//sendor code
long CODE_KITCHEN_SENSOR = 10521177;
long CODE_WEBCAM_ON_SENSOR = 1394001;
long CODE_WEBCAM_OFF_SENSOR= 1394004;

EthernetClient client;
EthernetServer server(8081);
char smtpServer[] = "smtpcorp.com";
RCSwitch mySwitch = RCSwitch();

void setup() {
  Serial.begin(SERIAL_BAUD);
  pinMode(SERIAL_BAUD, INPUT);
  mySwitch.enableReceive(RECEIVE_PIN);
  mySwitch.enableTransmit(TRASMIT_PIN);
  setupComm();
}

void loop() {

  getClientConnection();
  if (detectNoise()){
    Serial.print("Noise detected");
    email("Attention, noise at home!");
    accendiCam(CODE_WEBCAM_ON_SENSOR) ;
  }

  if (mySwitch.available()) {

    int value = mySwitch.getReceivedValue();

    Serial.print(value);
    if (value == 0) {
      Serial.print("Unknown encoding");
      Serial.print("n");
    }
    else {
      long receivedValue = mySwitch.getReceivedValue();
      if (receivedValue == CODE_DOOR_SENSOR) {
        Serial.print("Attention! Door sensor activated!");
        Serial.print("n");
        email("Attention, Door sensor activated!");
        accendiCam(CODE_WEBCAM_ON_SENSOR) ;
        delay(1000);
      }
      else if(receivedValue == CODE_KITCHEN_SENSOR) {
        Serial.print("Attenzione! kitchen sensor activated!");
        Serial.print("n");
        email("Attenzione, kitchen sensor activated!");
        accendiCam(CODE_WEBCAM_ON_SENSOR) ;
        delay(1000);
      }  

      Serial.print("Received ");
      Serial.print( receivedValue);
      Serial.print(" / ");
      Serial.print( mySwitch.getReceivedBitlength() );
      Serial.print("bit ");
      Serial.print("Protocol: ");
      Serial.println( mySwitch.getReceivedProtocol() );
    }

    mySwitch.resetAvailable();
  }

}

bool detectNoise ()
{
  bool rit = false;
  if (digitalRead(NOISE_DIGITAL_PIN) == HIGH)
  {
    rit = true;
  }
  return rit;
} 

void accendiCam(long value)
{
  mySwitch.send(value, 24);
  mySwitch.send(value, 24);
  mySwitch.send(value, 24);
  mySwitch.send(value, 24);
  mySwitch.send(value, 24);
} 

void setupComm()
{
  Serial.println("Trying to connect");
  Serial.print("n");
  if (!Ethernet.begin(mac)){
    Serial.println("Failed to DHCP");
    while(true);
  }

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

// Call to send an email.
bool email(char* text)
{
  bool success = false;
  Serial.println("Sending email...");
  Serial.print("n");
  Serial.println("SMTP server...");
  Serial.print(smtpServer); 

  if (client.connect(smtpServer, 2525)){
    Serial.println("connected");
    delay(100);
    client.println("EHLO arduino");
    for(int i=0; i<999; ++i){
      if(client.read() > 0)
        break;
    }
    Serial.println("responded");
    Serial.print("n");
    client.println("AUTH LOGIN");
    client.println("xxxxxxx");           //see explanation on last post 
    client.println("yyyyyy");   //see explanation on last post 

    client.println("MAIL FROM:<dumm@gmail.com>");
    for(int i=0; i<999; ++i){
      if(client.read() > 0)
        break;
    } 

    client.println("RCPT TO:<giuseppe.scola@gmail.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;
    }

    client.println("from: giuseppe.scola@gmail.com");
    client.println("to: giuseppe.scola@gmail.com");
    client.println("SUBJECT: ArduAlarm");
    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");
    Serial.print("n");
  }
  else {
    Serial.println("Failed");
    Serial.print("n");
    client.println("QUIT");
  }
  client.stop();
  return success;
}

void getClientConnection(){

  EthernetClient client = server.available();
  if (client) {
    String postString ="";
    Serial.println("new request");
    boolean currentLineIsBlank = true;
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        //postString.concat(c);
        if(postString.length()<10){
          postString +=c;
        }
        // Serial.write(c);
        if (c == 'n' && currentLineIsBlank) {
          //if(readString.indexOf("id=1") > 0){
          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("Refresh: 5");  // refresh the page automatically every 5 sec
          client.println();
          client.println("<!DOCTYPE HTML>");
          client.println("<html>");
          //client.println("<h1>Settaggi</h1><br>");
          client.println("<h1>AllarDuino</h1>");
          client.print("<br>");
          client.println("<a href=\"./?on\">CAM On</a>");
          client.println("<a href=\"./?off\">CAM Off</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("?on") > 0){
      Serial.println("CAM On");
      accendiCam(CODE_WEBCAM_ON_SENSOR);
      client.println("<br/>");
      client.println("<p>Cam On</p>");

    }
    if(postString.indexOf("?off") > 0){
      accendiCam(CODE_WEBCAM_OFF_SENSOR);
      client.println("<br/>");
      client.println("<p>Cam Off</p>");
    } 

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

In the next days I’ll try to have time to comment the code expecially the html generation.