Alarm with Push Notification


In this example the Arduino compatible Wi-Fi board TOP03  is used to build a simple antitheft station using a PIR module to detect a movement.

When the movement is detected, is possible to comand a lamp (in the example is a white LED) and an active piezo buzzer.
Moreover, the Arduino can be set to send a PUSH notification to all the mobile devices in which that miuPanel module is registered. The push notifications will be received in real time even when the app is closed.

The time and date are syncronized automatically with the smarphone: a specific panel command permit to Arduino to ask this info directly to smartphone.

Of course, you can use a different detection module (like a magnetic door sensor, a tilt sensor...).
With little changes in the sketch, you could use a ARDUINO UNO with SCF-01 module instead of TOP03.

 

http://www.miupanel.com/Portals/0/Projects/pir.png

Concept of detection station 

Hardware

  • TOP03 Arduino Compatible Wi-Fi Board
  • Power supply (for example a 5V smartphone charger with micro-USB jack)
  • PIR Module (detection sensor)
  • Active piezo Buzzer (3-5V,  max 25 mA)
  • n.2 LED and n.2 Resistors (>= 150 ohm)
  • wires for connections

http://www.miupanel.com/Portals/0/Projects/pir_circuit.JPG 

Supply the TOP03 Board from its usb connector  OR  the RAW pin (5 Volt)

 

 

    µPanel definition 

    Using the Online Panel Simulator you can easily design and check the panel layout before loading it on Arduino.


    Dw!FFF;-0{%100,y6!062Tf*15d2:µPanel Alarm;}{~1^%100,y25!9E6#333{%50,y60M1*40fb:00:00;_M2*15:12/05/2015;}|{%35,y60T*12fb:Last Alarm:;_M3*15:-;_M4*15:-;}}{%100,y2!FFF}{%100,y0.1!FFF}{^t%100,y66!DDD#333{%90,y5}{m<%90T*15:LAMP;|>W0F:0;}{%90,y5}{m<%90T*15:ALARM;|>W1F:0;}{%90,y5}{m<%90T*15:Notification;|~2>o20W2F:0;}{%90,y5}{m<%90T*15:Buzzer;|~3>o20W3F:0;}{%90,y5}={m%90,y20B1!AAA%22,15r10-20^fb:TEST PUSH;|B2!AAA%22,15r10-20^fb:SYNC TIME;|B3!AAA%22,15r10-20^fb:TEST BUZZER;}{m<%90T*15:Lamp: ;M5*15:10;T*15:s;|%60R1:0:60:1:10:100;}}


    http://www.miupanel.com/Portals/0/Projects/example_alarm_panel.JPG 

    Single Panel layout

     

    Arduino will change dinamically the style "opacity" of the two switch "notification" and "buzzer" depending if the alarm is set. Moreover, arduino will change the color of the green container dinamically when the alarm is detected. To do this, the "panel commands" object have been used.  

     

    TOP03 code (Arduino Lilypad USB)

    To build in Arduino IDE this project, you have to install the Time.zip library. This library is compatible also for the precise external DS1307 real time clock chip. In this example, we use the internal clock of Arduino (less precise). See the details of the library here:  http://playground.arduino.cc/Code/Time

    You can find both library and complete sketch for TOP03 in the following zipped folder:


    IMPORTANT: before loading your sketch, please select the board "LilyPad Arduino USB" in the boards menu.
    If you have accidentally selected another board, and already tried loading your sketch, read here: 
    www.arduino.cc/en/Guide/ArduinoLilyPadUSB



    /**************************************************
    
     Used Time Library to calculate data and time:  http://playground.arduino.cc/Code/Time
    
    
     --- IMPORTANT ---: before to load your sketch, please select the board "LilyPad Arduino USB" in the boards menu.
     If you have accidentally select another board, and load your sketch, read here:
     www.arduino.cc/en/Guide/ArduinoLilyPadUSB
      
     Connection table:
     
     * ESP8266  Cactus Micro Rev2
     * GPIO0    12
     * ENABLE   13
     * RX       TX
     * TX       RX
     * GND      GND
     
    
     About Serial
     The "Lilypad USB" (and the board derived from it) use "Serial1" to communicate via TTL serial on pins 0 (RX) and 1 (TX). 
     "Serial" is reserved for USB CDC communication.
    
     ***************************************************/
    
    #include <Time.h>
    
    #define ESP_PROGRAM_PIN  12
    #define ESP_ENABLE_PIN  13
    #define LAMP_PIN 21
    #define BUZZER_PIN 20
    
    unsigned char lamp_set = 0;
    unsigned char alarm_set = 0;
    unsigned char push_set = 0;
    unsigned char buzzer_set = 0;
    unsigned char clock_sync = 0;
    unsigned char flag_alarm = 0;
    
    unsigned int lamp_timer_ms = 10; // timer in seconds
    unsigned int counter_test_push = 1;
    
    unsigned long TriggerAlarm_Time = 0; 
    
    unsigned char hours;
    unsigned char minutes;
    unsigned char seconds;
    unsigned char days;
    unsigned char months;
    unsigned int years;
    
    time_t rtc_time = 0;
    time_t old_rtc_time = 0;
    
    String Msg;
    
    
    
    void setup() {
    
      Serial1.begin(57600);        // Initialise serial 1 (WiFi Module)
       
      pinMode(ESP_ENABLE_PIN, OUTPUT);
      pinMode(ESP_PROGRAM_PIN, OUTPUT);
      pinMode(LAMP_PIN, OUTPUT);
      pinMode(BUZZER_PIN, OUTPUT);
      
      // Set ESP module in RUN mode on reset 
      digitalWrite(ESP_PROGRAM_PIN, HIGH);  
      digitalWrite(ESP_ENABLE_PIN, HIGH);
    
      delay(5000);                 // Let's the module start
      
      // Discharge old partial messages
      Serial1.println("");
      
      // Send Panel discharging old partial messages
       Serial1.println("\n$P:Dw!FFF;-0{%100,y6!062Tf*15d2:µPanel Alarm;}{~1^%100,y25!9E6#333{%50,y60M1*40fb:--:--;_M2*15:--/--/----;}|{%35,y60T*12fb:Last Alarm:;_M3*15:-;_M4*15:-;}}{%100,y2!FFF}{%100,y0.1!FFF}{^t%100,y66!DDD#333{%90,y5}{m<%90T*15:LAMP;|>W0F:0;}{%90,y5}{m<%90T*15:ALARM;|>W1F:0;}{%90,y5}{m<%90T*15:Notification;|~2>o20W2F:0;}{%90,y5}{m<%90T*15:Buzzer;|~3>o20W3F:0;}{%90,y5}={m%90,y20B1!AAA%22,10r10-20^fb:TEST PUSH;|B2!AAA%22,10r10-20^fb:SYNC TIME;|B3!AAA%22,10r10-20^fb:TEST BUZZER;}{m<%90T*15:Lamp: ;M5*15:10;T*15:s;|%60R1:0:60:1:10:100;}}");
    
    
      // Interrupt on PIN 7 (will be called the function "IsrAlarm()" )
      attachInterrupt(digitalPinToInterrupt(7), IsrAlarm, RISING); 
    }
    
    
    void loop() {
      
      int c;
      while ((c = Serial1.read()) > '\n') Msg += (char) c;  // Read incoming chars, if any, until new line
      
      if (c == '\n')  // is message complete?
      { 
        // has the slider been moved? 
        if (Msg.substring(0,4).equals("#R1:") || Msg.substring(0,4).equals("#r1:")){                  
            lamp_timer_ms = (int) Msg.substring(4).toInt();              // Read 
            Serial1.print("#M5"); Serial1.println(lamp_timer_ms, DEC);   // Update message   
          }
    
       else if (Msg.substring(0,4).equals("#W01")){ // Enable LAMP
          lamp_set = 1;
       }
       else if (Msg.substring(0,4).equals("#W00")){  // Disable LAMP
         lamp_set = 0;
       }  
    
       else if (Msg.substring(0,4).equals("#W11")){ // Enable ALARM
          alarm_set = 1;
          Serial1.println("#C3:s~2:o100");
          Serial1.println("#C4:s~3:o100");
       }
       else if (Msg.substring(0,4).equals("#W10")){  // Disable ALARM
         alarm_set = 0;
         
         Serial1.println("#C4:s~2:o0");
         Serial1.println("#C5:s~3:o0");     
       }
    
       else if (Msg.substring(0,4).equals("#W21")){  // Enable PUSH
         push_set =1;
       }
       else if (Msg.substring(0,4).equals("#W20")){  // Disable PUSH
       
        push_set =0;
       }
       else if (Msg.substring(0,4).equals("#W21")){  // Enable BUZZER
         buzzer_set =1;
       }
       else if (Msg.substring(0,4).equals("#W20")){  // Disable BUZZER
        buzzer_set =0;
       }
    
       else if (Msg.substring(0,4).equals("#B1P"))   // TEST PUSH
       {
           Serial1.print("$CLOUD SEND:PUSH: Test Push n."); Serial1.println(counter_test_push, DEC);
           counter_test_push ++;
       }
       else if (Msg.substring(0,4).equals("#B2P")) // SYNC TIME
       {
          // "ask date and time to smartphone" (using the virtual object "panel command")
          Serial1.println("#C9:S:_da(1);;"); 
       }
        else if (Msg.substring(0,4).equals("#B3P")) // TEST BUZZER
        {
          digitalWrite(BUZZER_PIN, HIGH);
          delay (2000);
          digitalWrite(BUZZER_PIN, LOW);  
        }
        else if (Msg.substring(0,7).equals("#:DATE:"))
        {
        // the entire message received has the form: 
        // #:DATE:1453635745818:2016:01:24:12:42:25:818
        // where the fields are: Java Time, year, month, day, hour, minute, second, millisecond 
        
          years = Msg.substring(21,25).toInt();
          months = Msg.substring(26,28).toInt();
          days = Msg.substring(29,31).toInt();
          hours = Msg.substring(32,34).toInt();
          minutes = Msg.substring(35,37).toInt();
          seconds = Msg.substring(38,40).toInt();
          
          setTime(hours, minutes, seconds, days, months, years); // Method of library "Time"
          
          old_rtc_time = now(); // Reads the current time, as a time_t number. 
          clock_sync = 1;  
          DisplayClock();
        }
        
        Msg = "";
      } 
    
    
      // check in polling
      
      if (flag_alarm == 1)
      {
         // Switch off alarm
         if (millis() - TriggerAlarm_Time >= (unsigned long)(lamp_timer_ms *1000)) {  
           flag_alarm = 0;
           Serial1.println("#C3:s~1:!9E6");
           digitalWrite(LAMP_PIN, LOW);
           digitalWrite(BUZZER_PIN, LOW);     
         }
      }
      CheckClock();
    }
    
    
    // ----------------------------------------------------------------
    
    // Interrupt Service Routine function (called when PIR detected an alarm)
    
    void IsrAlarm (void){
      
      if (flag_alarm ==0){ // NOT Retriggering Mode 
        TriggerAlarm_Time = millis();
        flag_alarm = 1;
    
        if (alarm_set == 1){
          Serial1.println("#C3:s~1:!F55");
          DisplayAlarm();  
        }
        if (lamp_set == 1) 
          digitalWrite(LAMP_PIN, HIGH);
        if (buzzer_set == 1) 
          digitalWrite(BUZZER_PIN, HIGH);   
        if (push_set == 1)     
           Serial1.println("$CLOUD SEND:PUSH: ALARM Detected!");  
    
     
      }
    }
    
    //----------------------------------------------------------------
    
    
    void CheckClock(void){
      
        rtc_time = now(); // Store the current time in time 
          
        if ( rtc_time - old_rtc_time >= 60)   // Sync each 60 seconds
        { 
          old_rtc_time = rtc_time;
              
          years = year(rtc_time);
          months = month (rtc_time);
          days = day(rtc_time);
          hours = hour(rtc_time);
          minutes = minute(rtc_time);
          seconds = second(rtc_time);
         
          DisplayClock();
        }
    }
    
    
    //-------------------------------------------------------------
    
    
     void DisplayClock(void)
     {
        if (clock_sync == 1)
        {
    
         Serial1.print("#M1");
         if (hours < 10) Serial1.print('0'); 
         Serial1.print(String(hours) + ":");
         if (minutes < 10) Serial1.print('0'); 
         Serial1.println(String(minutes));
    
    
         Serial1.print("#M2");
         if (days < 10) Serial1.print('0'); 
         Serial1.print(String(days) + "/");
         if (months < 10) Serial1.print('0'); 
         Serial1.print(String(months) + "/");
         Serial1.println(String(years));
    
        }
        else
        {
         Serial1.println("#M1--:--"); 
         Serial1.println("#M2--/--/--");   
         }
     }
    
    //-----------------------------------------------------------
    
    
     void DisplayAlarm(void)
     {
         if (clock_sync == 1)
        {
         Serial1.print("#M3");
         if (hours < 10) Serial1.print('0'); 
         Serial1.print(String(hours) + ":");
         if (minutes < 10) Serial1.print('0'); 
         Serial1.println(String(minutes));
    
    
         Serial1.print("#M4");
         if (days < 10) Serial1.print('0'); 
         Serial1.print(String(days) + "/");
         if (months < 10) Serial1.print('0'); 
         Serial1.print(String(months) + "/");
         Serial1.println(String(years));
    
        }
        else
        {
          Serial1.println("#M3Alarm detected!");
          Serial1.println("#M4Time not available");
        }
     }
    
    //--------------------------------------------------------