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.
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
µ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;}}
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
Arduino Code
/************************************************** 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 #define PUSH_PERIOD_MS 30000 // min allowed interval [ms] between two push 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 LastPush_Time = 0x0FFFFFFF; unsigned long TriggerAlarm_Time = 0; unsigned long CurrentTime =0; unsigned char hours; unsigned char minutes; unsigned char seconds; unsigned char days; unsigned char months; unsigned int years; String Msg; time_t rtc_time = 0; time_t old_rtc_time = 0; 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 SendPanel(); // 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("#C4:s~2:z1d0"); Serial1.println("#C5:s~3:z1d0"); } else if (Msg.substring(0,4).equals("#W10")){ // Disable ALARM alarm_set = 0; Serial1.println("#C4:s~2:z-1d0"); Serial1.println("#C5:s~3:z-1d0"); digitalWrite(BUZZER_PIN, LOW); // Secure quite buzzer } 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("#W31")){ // Enable BUZZER buzzer_set = 1; } else if (Msg.substring(0,4).equals("#W30")){ // Disable BUZZER buzzer_set = 0; digitalWrite(BUZZER_PIN, LOW); // Secure quite buzzer } 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(); } else if (Msg.equals("$RES")){ // WiFi Module unwanted RESET >>>>>>> send panel again SendPanel(); } Msg = ""; // Clean message string } // check in polling if (flag_alarm == 1) // During a detected alarm { // 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 (buzzer_set == 1) digitalWrite(BUZZER_PIN, HIGH); if (push_set == 1) { CurrentTime = millis(); if (CurrentTime - LastPush_Time >= (unsigned long)PUSH_PERIOD_MS ){ Serial1.println("$CLOUD SEND:PUSH: ALARM Detected!"); LastPush_Time = CurrentTime; // save sending instant } } } if (lamp_set == 1) digitalWrite(LAMP_PIN, HIGH); } } //---------------------------------------------------------------- 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"); } } //-------------------------------------------------------- void SendPanel(void) { 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;|z-1d0~2>W2F:0;}{%90,y5}{m<%90T*15:Buzzer;|z-1d0~3>W3F:0;}{%90,y5}=S1!AAA%32,10^fb;{m%95,y20B1s1:TEST PUSH;|B2s1:SYNC TIME;|B3s1:TEST BUZZER;}{m<%90T*15:Lamp: ;M5*15:10;T*15:s;|%60R1:0:60:1:10:100;}}"); // Check the status of all the panel objects (useful in case of unwanted RESET of the wifi module only) if (lamp_set == 1) Serial1.println("#W01"); if (push_set == 1) Serial1.println("#W21"); if (buzzer_set == 1) Serial1.println("#W31"); if (alarm_set == 1){ Serial1.println("#W11"); Serial1.println("#C4:s~2:z1d0"); Serial1.println("#C5:s~3:z1d0"); } Serial1.print("#M5"); Serial1.println(lamp_timer_ms, DEC); // Update message DisplayClock(); // Display time }