Timothy Woo
Published © CC BY-NC-SA

LTE Cellular Burglar Alert (aka "Burgalert 7000")

Keep unwanted visitors off your premises without relying on WiFi, and get a text message whenever a threat has presented itself!

BeginnerFull instructions provided15 minutes5,085
LTE Cellular Burglar Alert (aka "Burgalert 7000")

Things used in this project

Hardware components

Elegoo Mega 2560
You can get just the Mega 2560 board but this kit literally includes a ton of stuff to get started with and is a great option for beginners.
×1
PIR Motion Sensor
The kit comes with a motion sensor so I just used it!
×1
Botletics SIM7000 LTE CAT-M/NB-IoT Shield
This is the piece that gives you cellular connectivity (and GPS if you need it!)
×1
Hologram Global IoT SIM Card
Hologram Global IoT SIM Card
This SIM card works the best and supports LTE CAT-M nation-wide in the USA for both Verizon and AT&T!
×1
Adafruit 3.7V/1200mAH LiPo Battery
Feel free to use a larger battery! I already had this so I used it.
×1

Software apps and online services

Arduino IDE
Arduino IDE

Story

Read more

Code

Burgalert 7000 Arduino Code

C/C++
Upload this to your board and start testing!
 /*  This sketch puts the microcontroller board to sleep and wakes up via the
 *  interrupt pin of a motion detector and sends you a text to alert you
 *  of unwanted visitors (parents, siblings, friends, child predators,
 *  burglars, raccoons, you name it!). I'll affectionately call this
 *  project the "Burgalert 7000". This project also compiles for the Uno!
 *  
 *  Feel free to make modifications and add temperature and GPS (built in
 *  to the Botletics SIM7000 shield), battery level, and perhaps a siren
 *  to alert bystanders of an unauthorized presence! You can also easily
 *  implement an HTTP request to send to a server instead of a text if you
 *  are of a more refined palette.
 *  
 *  Electrical connections:
 *  - Solder headers to the SIM7000 shield and snap it onto the Uno/Mega board
 *  - Connect the antenna that comes with the shield
 *  - Connect the LiPo battery to the JST connector on the shield
 *  - PIR sensor middle pin (output pin) to pin 2 of Uno/Mega
 *  - PIR sensor VCC and GND pins (see tutorial pic) to 5V and GND of Uno/Mega
 *  - Power the Uno/Mega via 9V battery or USB
 *  
 *  NOTE: This project does not fully minimize power consumption but only provides
 *  the general approach to sleeping the device. To truly minimize power consumption
 *  while sleeping you can replace the Uno/Mega with a stripped-down 3.3V MCU board
 *  and power it with the 3.7V battery, but this is outside the scope of this tutorial.
 *  
 *  How to use:
 *  - Change the phone number on line to your actual phone number
 *  - Upload the code, wave your hand on it, and it should send you a text!
 *  - Feel free to improve hardware and add things in software as needed
 *  
 *  Check out the tutorial: https://www.hackster.io/botletics/lte-cellular-burglar-alert-aka-burgalert-7000-b8c675
 *  
 *  Author: Timothy Woo (www.botletics.com)
 *  Last Updated: 7/21/2020
*/

// For SIM7000 cellular shield
#include "Adafruit_FONA.h" // https://github.com/botletics/SIM7000-LTE-Shield/tree/master/Code
#include <SoftwareSerial.h>

// For sleeping the MCU
#include "LowPower.h" // https://github.com/rocketscream/Low-Power

// For SIM7000 shield
#define FONA_PWRKEY 6
#define FONA_RST 7
//#define FONA_DTR 8 // Connect with solder jumper
//#define FONA_RI 9 // Need to enable via AT commands
#define FONA_TX 10 // Microcontroller RX
#define FONA_RX 11 // Microcontroller TX
//#define T_ALERT 12 // Connect with solder jumper

// Using SoftwareSerial
SoftwareSerial fonaSS = SoftwareSerial(FONA_TX, FONA_RX);
SoftwareSerial *fonaSerial = &fonaSS;

// Hardware serial is also possible!
//  HardwareSerial *fonaSerial = &Serial1;

Adafruit_FONA_LTE fona = Adafruit_FONA_LTE();

uint8_t readline(char *buff, uint8_t maxbuff, uint16_t timeout = 0);
char imei[16] = {0}; // Use this for device ID
char replybuffer[255]; // Large buffer for replies
uint8_t type;
uint8_t counter = 0;

// NOTE: Keep the buffer sizes as small as possible, especially on
// Arduino Uno which doesn't have much computing power to handle
// large buffers. On Arduino Mega you shouldn't have to worry much.
char URL[100]; // Make sure this is long enough for your request URL
//char body[100]; // Only need this is you're doing an HTTP POST request

const int wakeUpPin = 2; // Use pin 2 to wake up the Uno/Mega

const char * phone_number = "12223334567"; // Include country code, only numbers
const char * text_message = "UNINVITED GUEST!"; // Change to suit your needs

void setup() {
  Serial.begin(115200);
//  while (!Serial) delay(1); // Wait for serial, for debug
  Serial.println(F("*** Burgalert 7000 ***"));

  pinMode(wakeUpPin, INPUT); // For the interrupt wake-up to work
  pinMode(FONA_RST, OUTPUT);
  digitalWrite(FONA_RST, HIGH); // Default state
  pinMode(FONA_PWRKEY, OUTPUT);

  // Set the APN of the SIM card you're using. You may need to enable data connection
  // for the first time for it to take effect and connect to the network if you're having
  // issues.
  fona.setNetworkSettings(F("hologram")); // For Hologram SIM card, change appropriately
  fona.setFunctionality(1); // AT+CFUN=1
}

void loop() {
  // Our goal is to wake up whenever the motion detector tells us to,
  // then go back to sleep after sending a message or HTTP request.
  
  // Disable external pin interrupt until we finishd doing stuff, then sleep afterward
  detachInterrupt(digitalPinToInterrupt(wakeUpPin));
  
  powerOn(true); // Power on the module
  moduleSetup(); // Establish first-time serial comm and print IMEI
  
  // First connect to the cell network and verify connection
  // If unsuccessful, keep retrying every 2s until a connection is made
  while (!netStatus()) {
    Serial.println(F("Failed to connect to cell network, retrying..."));
    delay(2000); // Retry every 2s
  }
  Serial.println(F("Connected to cell network!"));

  // Send a text to your phone!
  if (!fona.sendSMS(phone_number, text_message)) {
    Serial.println(F("Failed to send text!"));
  }
  else {
    Serial.println(F("Sent text alert!"));
  }

  // Uncomment the section below if you are doing an HTTP request!
  /*
  // Disable data connection before attempting to enable
  if (!fona.enableGPRS(false)) {
    Serial.println(F("Failed to turn off"));
  }

  // Turn on data connection after connecting to network
  while (!fona.enableGPRS(true)) {
    Serial.println(F("Failed to enable GPRS, retrying..."));
    delay(2000); // Retry every 2s
  }
  Serial.println(F("Enabled GPRS!"));

  // Do an HTTP GET request
  // By posting to the web you can link it to things like IFTTT to get
  // email notifications, keep track of any extra data you might add
  // (temperature, GPS, door state, etc) and have fun with it!
  
  counter = 0; // This counts the number of failed attempts tries
  
  sprintf(URL, "http://dweet.io/dweet/for/%s?burglar=true", imei); // Check https://dweet.io/get/latest/dweet/for/{IMEI} to see it!
  
  while (counter < 3 && !fona.postData("GET", URL)) {
    Serial.println(F("Failed to post data, retrying..."));
    counter++; // Increment counter
    delay(1000);
  }
  */

  // Or do an HTTP POST request instead!
  /*
  sprintf(URL, "http://dweet.io/dweet/for/%s", imei);
  body = "{burglar: true}"; // We're keeping it super simple for now!
//  sprintf(body, "{\"burglar\":true,\"temperature\":%s, tempBuff); // HTTP POST JSON body, feel free to add stuff!
  
  while (counter < 3 && !fona.postData("POST", URL, body)) {
    Serial.println(F("Failed to complete HTTP POST..."));
    counter++;
    delay(1000);
  }
  */
  
  sleepDevice(); // Put the MCU and SIM7000 shield to sleep until more motion is detected!
}

// Power on/off the module
void powerOn(bool state) {
  if (state) {
    Serial.println(F("Turning on SIM7000..."));
    digitalWrite(FONA_PWRKEY, LOW);
    delay(100); // Turn on module
    digitalWrite(FONA_PWRKEY, HIGH);
    delay(4500); // Give enough time for the module to boot up before communicating with it
  }
  else {
    Serial.println(F("Turning off SIM7000..."));
    fona.powerDown(); // Turn off module
  }
}

void moduleSetup() {
  fonaSS.begin(115200); // Default SIM7000 shield baud rate
  
  Serial.println(F("Configuring to 9600 baud"));
  fonaSS.println("AT+IPR=9600"); // Set baud rate
  delay(100); // Short pause to let the command run
  fonaSS.begin(9600);
  if (! fona.begin(fonaSS)) {
    Serial.println(F("Couldn't find FONA"));
    while(1); // Don't proceed if it couldn't find the device
  }

  type = fona.type();
  Serial.println(F("FONA is OK"));
  Serial.print(F("Found "));
  switch (type) {
    case SIM7000A:
      Serial.println(F("SIM7000A (American)")); break;
    case SIM7000C:
      Serial.println(F("SIM7000C (Chinese)")); break;
    case SIM7000E:
      Serial.println(F("SIM7000E (European)")); break;
    case SIM7000G:
      Serial.println(F("SIM7000G (Global)")); break;
    default:
      Serial.println(F("???")); break;
  }
  
  // Print module IMEI number.
  uint8_t imeiLen = fona.getIMEI(imei);
  if (imeiLen > 0) {
    Serial.print("Module IMEI: "); Serial.println(imei);
  }
}

bool netStatus() {
  int n = fona.getNetworkStatus();
  
  Serial.print(F("Network status ")); Serial.print(n); Serial.print(F(": "));
  if (n == 0) Serial.println(F("Not registered"));
  if (n == 1) Serial.println(F("Registered (home)"));
  if (n == 2) Serial.println(F("Not registered (searching)"));
  if (n == 3) Serial.println(F("Denied"));
  if (n == 4) Serial.println(F("Unknown"));
  if (n == 5) Serial.println(F("Registered roaming"));

  if (!(n == 1 || n == 5)) return false;
  else return true;
}

void sleepDevice() {
  Serial.println(F("Turning off SIM7000..."));
  powerOn(false); // Turn off the SIM7000 module

  // After everything's said and done, attach the interrupt
  // Set the PIR sensor jumper to "L" for normal operation. This
  // means the output will go from LOW to HIGH when motion is detected!
  attachInterrupt(digitalPinToInterrupt(wakeUpPin), wakeUp, RISING); // When the PIR sensor pin goes low to high, MCU wakes up!

  Serial.println(F("Sleeping MCU..."));
  delay(100); // Needed for the serial print above

  // Power down MCU with ADC and BOD module disabled
  // Wake up when wake up pin is low
  LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF);
}

void wakeUp() {
  // Just a handler for the interrupt
  // This runs right after the MCU wakes up, then it goes back to loop()
}

Burgalert_7000_ButtonPress

C/C++
Want to use a pushbutton to initiate the text messages instead of a PIR motion sensor? No problem! Just upload this code and attach a button between pin 2 and GND and when you press it, you should receive a text!
/*  This sketch is the same as the "Bergalert 7000" code but uses a pushbutton
 *  switch instead of a PIR motion sensor. Once you press the button it should
 *  send you a text message!
 *  
 *  Electrical connections:
 *  - Solder headers to the SIM7000 shield and snap it onto the Uno/Mega board
 *  - Connect the antenna that comes with the shield
 *  - Connect the LiPo battery to the JST connector on the shield
 *  - Pushbutton switch between pin 2 of Uno/Mega to GND
 *  - Power the Uno/Mega via 9V battery or USB
 *  
 *  How to use:
 *  - Change the phone number on line to your actual phone number
 *  - Upload the code, let it initialize, push the button, and it should send you a text!
 *  - Feel free to improve hardware and add things in software as needed
 *  
 *  Check out the tutorial: https://www.hackster.io/botletics/lte-cellular-burglar-alert-aka-burgalert-7000-b8c675
 *  
 *  Author: Timothy Woo (www.botletics.com)
 *  Last Updated: 7/21/2020
*/

// For SIM7000 cellular shield
#include "Adafruit_FONA.h" // https://github.com/botletics/SIM7000-LTE-Shield/tree/master/Code
#include <SoftwareSerial.h>

// For SIM7000 shield
#define FONA_PWRKEY 6
#define FONA_RST 7
//#define FONA_DTR 8 // Connect with solder jumper
//#define FONA_RI 9 // Need to enable via AT commands
#define FONA_TX 10 // Microcontroller RX
#define FONA_RX 11 // Microcontroller TX
//#define T_ALERT 12 // Connect with solder jumper

#define LED 13

// Using SoftwareSerial
SoftwareSerial fonaSS = SoftwareSerial(FONA_TX, FONA_RX);
SoftwareSerial *fonaSerial = &fonaSS;

// Hardware serial is also possible!
//  HardwareSerial *fonaSerial = &Serial1;

Adafruit_FONA_LTE fona = Adafruit_FONA_LTE();

uint8_t readline(char *buff, uint8_t maxbuff, uint16_t timeout = 0);
char imei[16] = {0}; // Use this for device ID
char replybuffer[255]; // Large buffer for replies
uint8_t type;
uint8_t counter = 0;
volatile bool buttonPressed = false;

// NOTE: Keep the buffer sizes as small as possible, especially on
// Arduino Uno which doesn't have much computing power to handle
// large buffers. On Arduino Mega you shouldn't have to worry much.
char URL[100]; // Make sure this is long enough for your request URL
//char body[100]; // Only need this is you're doing an HTTP POST request

const int BUTTON = 2; // Use pin 2 to wake up the Uno/Mega

const char * phone_number = "12223334567"; // Include country code, only numbers
const char * text_message = "UNINVITED GUEST!"; // Change to suit your needs

void setup() {
  Serial.begin(115200);
//  while (!Serial) delay(1); // Wait for serial, for debug
  Serial.println(F("*** Burgalert 7000 ***"));

  pinMode(BUTTON, INPUT_PULLUP); // For the interrupt wake-up to work
  pinMode(FONA_RST, OUTPUT);
  digitalWrite(FONA_RST, HIGH); // Default state
  pinMode(FONA_PWRKEY, OUTPUT);

  powerOn(true); // Power on the module
  moduleSetup(); // Establish first-time serial comm and print IMEI

  // Set the APN of the SIM card you're using. You may need to enable data connection
  // for the first time for it to take effect and connect to the network if you're having
  // issues.
  fona.setNetworkSettings(F("hologram")); // For Hologram SIM card, change appropriately

  attachInterrupt(digitalPinToInterrupt(BUTTON), interruptHandler, FALLING); // When switch closes (goes HIGH to LOW)
}

void loop() {
  // Closing the switch sets the "buttonPressed" flag to true, which makes the stuff
  // in loop() function run.

  // Only send SMS if the switch was closed
  if (buttonPressed) {
    buttonPressed = false; // Reset flag
    
    // First connect to the cell network and verify connection
    // If unsuccessful, keep retrying every 2s until a connection is made
    while (!netStatus()) {
      Serial.println(F("Failed to connect to cell network, retrying..."));
      delay(2000); // Retry every 2s
    }
    Serial.println(F("Connected to cell network!"));
  
    // Send a text to your phone!
    if (!fona.sendSMS(phone_number, text_message)) {
      Serial.println(F("Failed to send text!"));
    }
    else {
      Serial.println(F("Sent text alert!"));
    }
  
    // Uncomment the section below if you are doing an HTTP request!
    /*
    // Disable data connection before attempting to enable
    if (!fona.enableGPRS(false)) {
      Serial.println(F("Failed to turn off"));
    }
  
    // Turn on data connection after connecting to network
    while (!fona.enableGPRS(true)) {
      Serial.println(F("Failed to enable GPRS, retrying..."));
      delay(2000); // Retry every 2s
    }
    Serial.println(F("Enabled GPRS!"));
  
    // Do an HTTP GET request
    // By posting to the web you can link it to things like IFTTT to get
    // email notifications, keep track of any extra data you might add
    // (temperature, GPS, door state, etc) and have fun with it!
    
    counter = 0; // This counts the number of failed attempts tries
    
    sprintf(URL, "http://dweet.io/dweet/for/%s?burglar=true", imei); // Check https://dweet.io/get/latest/dweet/for/{IMEI} to see it!
    
    while (counter < 3 && !fona.postData("GET", URL)) {
      Serial.println(F("Failed to post data, retrying..."));
      counter++; // Increment counter
      delay(1000);
    }
    */
  
    // Or do an HTTP POST request instead!
    /*
    sprintf(URL, "http://dweet.io/dweet/for/%s", imei);
    body = "{burglar: true}"; // We're keeping it super simple for now!
  //  sprintf(body, "{\"burglar\":true,\"temperature\":%s, tempBuff); // HTTP POST JSON body, feel free to add stuff!
    
    while (counter < 3 && !fona.postData("POST", URL, body)) {
      Serial.println(F("Failed to complete HTTP POST..."));
      counter++;
      delay(1000);
    }
    */
  }
}

// Power on/off the module
void powerOn(bool state) {
  if (state) {
    Serial.println(F("Turning on SIM7000..."));
    digitalWrite(FONA_PWRKEY, LOW);
    delay(100); // Turn on module
    digitalWrite(FONA_PWRKEY, HIGH);
    delay(4500); // Give enough time for the module to boot up before communicating with it
  }
  else {
    Serial.println(F("Turning off SIM7000..."));
    fona.powerDown(); // Turn off module
  }
}

void moduleSetup() {
  fonaSS.begin(115200); // Default SIM7000 shield baud rate
  
  Serial.println(F("Configuring to 9600 baud"));
  fonaSS.println("AT+IPR=9600"); // Set baud rate
  delay(100); // Short pause to let the command run
  fonaSS.begin(9600);
  if (! fona.begin(fonaSS)) {
    Serial.println(F("Couldn't find FONA"));
    while(1); // Don't proceed if it couldn't find the device
  }

  type = fona.type();
  Serial.println(F("FONA is OK"));
  Serial.print(F("Found "));
  switch (type) {
    case SIM7000A:
      Serial.println(F("SIM7000A (American)")); break;
    case SIM7000C:
      Serial.println(F("SIM7000C (Chinese)")); break;
    case SIM7000E:
      Serial.println(F("SIM7000E (European)")); break;
    case SIM7000G:
      Serial.println(F("SIM7000G (Global)")); break;
    default:
      Serial.println(F("???")); break;
  }
  
  // Print module IMEI number.
  uint8_t imeiLen = fona.getIMEI(imei);
  if (imeiLen > 0) {
    Serial.print("Module IMEI: "); Serial.println(imei);
  }
}

bool netStatus() {
  int n = fona.getNetworkStatus();
  
  Serial.print(F("Network status ")); Serial.print(n); Serial.print(F(": "));
  if (n == 0) Serial.println(F("Not registered"));
  if (n == 1) Serial.println(F("Registered (home)"));
  if (n == 2) Serial.println(F("Not registered (searching)"));
  if (n == 3) Serial.println(F("Denied"));
  if (n == 4) Serial.println(F("Unknown"));
  if (n == 5) Serial.println(F("Registered roaming"));

  if (!(n == 1 || n == 5)) return false;
  else return true;
  
}

void interruptHandler() {
  delay(50); // Debouncing
  buttonPressed = true; // Set flag so code in loop() runs
}

Credits

Timothy Woo

Timothy Woo

7 projects • 171 followers
I'm a young engineer with a passion for DIY and electronics! My motto is "Learn to share, share to learn!"
Thanks to Elegoo.

Comments