Project showcase
Suicide Prevention Gun Safe Locking System

Suicide Prevention Gun Safe Locking System © GPL3+

An IoT device that helps prevent gun suicides through safe monitoring, only allowing access to a safe through a request/approval process.

  • 7,165 views
  • 10 comments
  • 14 respects

Components and supplies

Necessary tools and machines

Drill Press
Hand Saw
Screw Driver
Wire Stripper
Wire Crimper

Apps and online services

Microsoft azure logo 7qghkhuibq
Microsoft Azure
ASP.net Core
SendGrid

About this project

Suicide is a tragedy

Project Summary

Our hope for this project is to help families with concerns for suicide’s or domestic disputes, keep firearms in their home with an extra layer of security. Many families have firearms and could benefit from a secondary locking system controlled by an App remotely. So we have designed and created version 1.0 of our lock and app system.

The Center' for Disease Control claim's, “[t]he two major component causes of firearm injury deaths in 2014 were suicide (63.7%) and homicide (32.8%).”

This system will help with suicide prevention in the sense that no person can open the safe without reaching out to another person. This extra step can encourage and enforce house rules such as, calling the individual requesting the safe to be open, having the ability to control the safe remotely, and do all of this on your cell phone or computer. If you talk to the individual requesting the safe be opened and you feel they are at risk you have the ability to talk to them and help them make the choice of life!

How it works:

The system uses a magnetic lock manipulated by the app. Each person allowed in the household to use the firearms would have an account. When they were in need of the firearm they would use the app to request the safe be opened. The "unlock" option will be accessible only by those receiving the request. Never to the user that is requesting. This way there is no option to simply log into the app and press the unlock button without alerting another user. You must send a request and a different user must "unlock" the safe. The lock also has an anti-tamper feature, if someone tries to remove the lock from the safe an alert is emailed to the users via the web app.

Hardware in Detail:

The main hardware components of this device are the following; Aduino 101, Arduio MKR1000, MKR1000 Relay Shield, LCD Screen, Switchable Magnets, Electro-Magnet, and a Project Box.

The Arduino 101 is used because it has built in accelerometers which we use to monitor tampering with the safe lock. We are also using the Arduino 101 to control the LCD Screen, which displays the state of the locking device, "LOCKED" or "UNLOCKED". The LCD screen simply shows the lock status as well as alarms when the accelerometers eperience excessive movement. The Adruino MKR1000 makes requests for lock status to the server and then decides whether or not to open the electro magnet based on whether or not a request has been granted by another user. The Relay Shield allows the arduino to control when the elctro magnet has power, which is how the safe can be locked or unlocked.

There are three magnets used in this project; two switchable magnets that strongly secure the device to the front of a safe, and one electro magnet that holds the door closed when prompted to do so by the Arduino. The switchable magnets ensure that the device cannot be removed.

Last but not least we have a metal seamless project box to hold all of the electronics and magnets. This project box does not have any screws on the outside to prevent any tampering.

Software in Detail:

The software is written in ASP.NETCore C# on Visual Studio 2017. The Web App receives requests from the locking device and responds with which state the lock should be in (locked or unlocked). The web app also receives alarm updates from the device and emails out connected users right away.

The front end of the app is accessible from any internet device at www.cowincrafted.com feel free to check it out. Once logged in users will be able to make and approve requests. Once a user makes a request, they are not able to approve requests until the lock goes through a cycle. When a request is made, an email is sent out to the other users. All emails are sent using an HTTP request to SendGrid, an email sending service.

Working on the project:

Code

Arduino 101 CodeArduino
This code allows the Arduino 101 to use its accelerometers to measure tampering and this code also controls an LCD screen which displays the different locking states of the device.
/*
 Demonstration sketch for Adafruit i2c/SPI LCD backpack
 using 74HC595 SPI expander
 ( http://www.ladyada.net/products/i2cspilcdbackpack/index.html )

 This sketch prints "Hello World!" to the LCD
 and shows the time.
 
  The circuit:
 * 5V to Arduino 5V pin
 * GND to Arduino GND pin
 * CLK to Digital 2
 * DAT to Digital 3
 * LAT to Digital 4
*/


// include the library code:
#include "Wire.h"
#include "Adafruit_LiquidCrystal.h"
#include "CurieIMU.h"

int RxPin = 5;
int RxValue = 0;
int TxPin = 6;
int Lockout = 0;

// Connect via SPI. Data pin is #3, Clock is #2 and Latch is #4
Adafruit_LiquidCrystal lcd(3, 2, 4);

void setup() {
  // set up the LCD's number of rows and columns: 
  lcd.begin(16, 2);
  pinMode(RxPin, INPUT);
  Serial.begin(9600);
  CurieIMU.begin();

  // Set the accelerometer range to 2G
  CurieIMU.setAccelerometerRange(2);
}

void loop() {
  float ax, ay, az;   //scaled accelerometer values

  // read accelerometer measurements from device, scaled to the configured range
  CurieIMU.readAccelerometerScaled(ax, ay, az);
  /*lcd.setCursor(0, 1);
  lcd.print ("x: ");
  lcd.print (ax,4, " ","y: ",  ay, " ","z: ",  az);*/
  
  if (ax > 1.25 || ay > 1.25 || az > 1.25 || ax < -1.25 || ay < -1.25 || az < -1.25 ){
    digitalWrite (TxPin, HIGH);
    lcd.setCursor(11, 0);
    lcd.print("Alarm");
    delay(5000);
    digitalWrite (TxPin, LOW);
    lcd.setCursor(11, 1);
    lcd.print("Reset");
    delay(2000);
    lcd.setCursor(11, 0);
    lcd.print("     ");
    lcd.setCursor(11, 1);
    lcd.print("     ");
  }
  
  RxValue = digitalRead(RxPin);
  Serial.print(RxValue);
  if (RxValue == 0)
  {
  lcd.setCursor(0, 0);
  lcd.print("Locked  ");

  // set the cursor to column 0, line 1
  // (note: line 1 is the second row, since counting begins with 0):
  }
  else{
  lcd.setCursor(0, 0);
  lcd.print("Unlocked");
  digitalWrite(TxPin, LOW);
  //lcd.setCursor(0, 1);
  //lcd.print("        ");
  }
  
}
Arduino MKR1000 CodeArduino
This code allows the MKR1000 to connect to the internet and send a request to the server to get the lock status. This code also receives alarm information from the Arduino 101 and then sends the alarm info to the server so the server can send email alerts to the users. This code communicates the lock status to the Arduino 101 and this code turns the electro magnet off and on using the Arduino Relay shield.
/*
  Web client

 This sketch connects to a website (http://www.google.com)
 using a WiFi shield.

 This example is written for a network using WPA encryption. For
 WEP or WPA, change the WiFi.begin() call accordingly.

 This example is written for a network using WPA encryption. For
 WEP or WPA, change the WiFi.begin() call accordingly.

 Circuit:
 * WiFi shield attached

 created 13 July 2010
 by dlf (Metodo2 srl)
 modified 31 May 2012
 by Tom Igoe
 */


#include <SPI.h>
#include <WiFi101.h>

int EmagPin = 1;
int LcdPin = 2;
int AlrmPin = 6;
int AlrmValue = 0;

char ssid[] = "STANTON-2.4"; //  your network SSID (name)
char pass[] = "STAnton7860";    // your network password (use for WPA, or use as key for WEP)
int keyIndex = 0;            // your network key Index number (needed only for WEP)
const unsigned long HTTP_TIMEOUT = 10000;  // max respone time from server

int status = WL_IDLE_STATUS;
// if you don't want to use DNS (and reduce your sketch size)
// use the numeric IP instead of the name for the server:
//IPAddress server(74,125,232,128);  // numeric IP for Google (no DNS)
char server[] = "www.cowincrafted.com";    // name address for Google (using DNS)

// Initialize the Ethernet client library
// with the IP address and port of the server
// that you want to connect to (port 80 is default for HTTP):
WiFiClient client;

char a = 'a';
char b = 'b';
char c = 'c';
char z = 'z';

unsigned long lastConnectionTime = 0;            // last time you connected to the server, in milliseconds
const unsigned long postingInterval = 5000; // delay between updates, in milliseconds


void setup() {
  //Initialize serial and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }

  // check for the presence of the shield:
  if (WiFi.status() == WL_NO_SHIELD) {
    Serial.println("WiFi shield not present");
    // don't continue:
    while (true);
  }

  // attempt to connect to WiFi network:
  while (status != WL_CONNECTED) {
    Serial.print("Attempting to connect to SSID: ");
    Serial.println(ssid);
    // Connect to WPA/WPA2 network. Change this line if using open or WEP network:
    status = WiFi.begin(ssid, pass);

    // wait 10 seconds for connection:
    delay(10000);
  }
  Serial.println("Connected to wifi");
  printWiFiStatus();

  Serial.println("\nStarting connection to server...");
  // if you get a connection, report back via serial:
  
}

void loop() {
  AlrmValue = digitalRead(AlrmPin);
  if (AlrmValue == 1)
  {
    Serial.println("Alarm");
    if (client.connect(server, 80)) {
    Serial.println("connected to server");
    // Make a HTTP request:
    client.println("GET /api/locksapi/1/1 HTTP/1.1");
    client.println("Host: www.cowincrafted.com");
    client.println("Connection: close");
    client.println();
    Serial.println("alarm sent");
    }

    delay(5000);

    Serial.println("Alarm Off");

    if (client.connect(server, 80)) {
    Serial.println("connected to server");
    // Make a HTTP request:
    client.println("GET /api/locksapi/1/0 HTTP/1.1");
    client.println("Host: www.cowincrafted.com");
    client.println("Connection: close");
    client.println();
    Serial.println("alarm off sent");
    }
  }
  
  //Serial.println("in void loop");
  
  // if there are incoming bytes available
  // from the server, read them and print them:
  while (client.available()) {

     z = a;
     a = b;
     b = c;
     c = client.read();
    
    if(c == ']' && b == '0' )
    {
      Serial.println();
      Serial.println("Unlocked");
      digitalWrite (EmagPin, HIGH);
      digitalWrite (LcdPin, HIGH);
    }
    if(c == ']' && b == '1' )
    {
      Serial.println();
      Serial.println("Locked");
      digitalWrite (EmagPin, LOW);
      digitalWrite (LcdPin, LOW);
    }
    Serial.write(c);
    
  }

  if (millis() - lastConnectionTime > postingInterval) {
    httpRequest();
  }
  //delay(30000);

  // if the server's disconnected, stop the client:
  /*if (!client.connected()) {
    Serial.println();
    Serial.println("disconnecting from server.");
    client.stop();

    // do nothing forevermore:
    while (true);
  }*/
}

  // this method makes a HTTP connection to the server:
void httpRequest() {
  // close any connection before send a new request.
  // This will free the socket on the WiFi shield
  client.stop();

  // if there's a successful connection:
  Serial.println("httprequest");

  if (client.connect(server, 80)) {
    Serial.println("connected to server");
    // Make a HTTP request:
    client.println("GET /api/locksapi/1 HTTP/1.1");
    client.println("Host: www.cowincrafted.com");
    client.println("Connection: close");
    client.println();
    //lastConnectionTime = millis();
  }
  lastConnectionTime = millis();
}

void printWiFiStatus() {
  // print the SSID of the network you're attached to:
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());

  // print your WiFi shield's IP address:
  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  Serial.println(ip);

  // print the received signal strength:
  long rssi = WiFi.RSSI();
  Serial.print("signal strength (RSSI):");
  Serial.print(rssi);
  Serial.println(" dBm");
}

// Skip HTTP headers so that we are at the beginning of the response's body
bool skipResponseHeaders() {
  // HTTP headers end with an empty line
  char endOfHeaders[] = "\r\n\r\n";

  client.setTimeout(HTTP_TIMEOUT);
  bool ok = client.find(endOfHeaders);

  if (!ok) {
    Serial.println("No response or invalid response!");
  }

  return ok;
}
Web App Code
This is a ASP.Net Core project created in Visual Studio 2017. It needs to be deployed on a service like Azure and must have a connected SQL Database.

Schematics

Smart Lock Flow Diagram
This flow diagram helps to visualize all the components of the project and shows how they interact with each other.
Img 20170623 231509 41hfh3gx5j
Wiring Diagram
Hya 75 dfpp6lgzdj

Comments

Submitted to Contest

Win an all-expenses-paid trip to Beijing for the final competition along with other amazing Makers!

2017 Co-Making the Future

Team members

Profile picture
Jason Cowin
  • 4 projects
  • 8 followers
Amanda headshot (1 of 1) gktvfakxrp
Amanda Cowin
  • 1 project
  • 2 followers
Rampage cuteness2013 xmfnxzk8br
Jordan Stanton
  • 2 projects
  • 3 followers
Default
Brittany K Stanton
  • 1 project
  • 2 followers
Default
David Peterson
  • 1 project
  • 1 follower
Alex ross hanqcxeuhu
Alex Cowin
  • 1 project
  • 1 follower

Published on

June 24, 2017

Members who respect this project

16298750 10212310007534226 7844224033334417454 nPhotoImg 4181 f2gqobidmhDefaultDirtguitar2Chauhannaman9816996300 673566447080 3302330539634597840 nJohan34

and 7 others

See similar projects
you might like

Similar projects you might like

Arduino Bluetooth Basic Tutorial

by Mayoogh Girish

  • 457,201 views
  • 44 comments
  • 244 respects

Home Automation Using Raspberry Pi 2 And Windows 10 IoT

Project tutorial by Anurag S. Vasanwala

  • 285,648 views
  • 95 comments
  • 672 respects

Security Access Using RFID Reader

by Aritro Mukherjee

  • 230,804 views
  • 38 comments
  • 240 respects

OpenCat

Project in progress by Team Petoi

  • 196,617 views
  • 154 comments
  • 1,366 respects
Add projectSign up / Login