Shahariar
Published © CC BY-NC

Secure Package Reception Box

An IoT smart mailbox for securely receiving parcels and getting notification on app without being present at home.

IntermediateFull instructions providedOver 1 day7,818

Things used in this project

Hardware components

Argon
Particle Argon
×1
Arduino UNO
Arduino UNO
×1
Speaker: 0.25W, 8 ohms
Speaker: 0.25W, 8 ohms
×1
SG90 Micro-servo motor
SG90 Micro-servo motor
×1
SparkFun 4x4 Keypad
×1
Alphanumeric LCD, 20 x 4
Alphanumeric LCD, 20 x 4
×1
ISD1820 Voice Recording IC
×1
Adafruit Li Ion 3.7 V battery 18650 (generic)
×1
ATmega328
Microchip ATmega328
×1
LDR, 5 Mohm
LDR, 5 Mohm
×5
Battery Holder, 18650 x 2
Battery Holder, 18650 x 2
×1
Breadboard (generic)
Breadboard (generic)
×1
Perma-Proto Breadboard Half Size
Perma-Proto Breadboard Half Size
×1
SMD LED 0505 RED
×3
SMD LED 0505 GREEN
×3
SMD LED 0505 BLUE
×3
High Brightness LED, White
High Brightness LED, White
×1
Resistor 1k ohm
Resistor 1k ohm
×2
Resistor 10k ohm
Resistor 10k ohm
×1
Resistor 220 ohm
Resistor 220 ohm
×1
Capacitor 100 µF
Capacitor 100 µF
×3
WPC Board 4
×1
Iron Hinge 2 inch x 1 inch
×1
Metal Angle Bracket (4 holes)
×10
3.5 mm Screw
×24

Software apps and online services

Particle Build Web IDE
Particle Build Web IDE
Text to Speech Online
Blynk
Blynk
Maker service
IFTTT Maker service

Hand tools and fabrication machines

Soldering iron (generic)
Soldering iron (generic)
Hot glue gun (generic)
Hot glue gun (generic)
Tape, Electrical
Tape, Electrical
Tape, Double Sided
Tape, Double Sided
Tape, Velcro® Stick On Tape/Strip
Tape, Velcro® Stick On Tape/Strip
Tape, Gaffer / Duct / Cloth
Tape, Gaffer / Duct / Cloth
Super Glue (generic)
Epoxy Glue (generic)
Weller Hot Knife
DC motor Mini Saw

Story

Read more

Schematics

Schematic

Code

Particle Argon Code

C/C++
https://go.particle.io/shared_apps/5d7401570e69780005199a01
#include "Keypad_Particle.h"
#include "Arduino_KeyPadLCD_Shield.h"
#include <blynk.h>

// auth token send from blynk
char auth[] = "your auth token sent by Blynk to your email";


const byte ROWS = 4;
const byte COLS = 3;
char keys[ROWS][COLS] = 
{
  {'1','2','3'},
  {'4','5','6'},
  {'7','8','9'},
  {'*','0','#'}
};

byte rowPins[ROWS] = { D9, D10, D11, D12 }; // rows of keypad
byte colPins[COLS] = { D13, A5, A4 }; // cols of keypad
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
LiquidCrystal lcd(D8, D7, D6, D5, D4, D3); // pin - rs en d4 d5 d6 d7



int pkg_flag = 0;  
int door_flag = 0;  
int lock_flag = 0;
int auth_flag = 0;

int cursor = 0;
int loopcount = 0;
char numberKeypad[20];
String trackingnumber;

// periodic timer for blynk
BlynkTimer t1;
BlynkTimer t2;
BlynkTimer t3;

// virtual status LEDs on Blynk app
WidgetLED led0(V0); // door close position
WidgetLED led1(V1); // mail/package  received
WidgetLED led2(V2); // no mail/package
WidgetLED led3(V3); // door open
WidgetLED led4(V4); // no mail/package
WidgetLED led5(V5); // door open
WidgetLED led6(V6); // auth fail
WidgetLED led7(V7); // auth success

// input terminal on blynk app
WidgetTerminal terminal(V10); 

// remote lock button on blynk app 
BLYNK_WRITE(V8) 
{
  int pinData = param.asInt(); 
  if (pinData == 1)  door_lock();
}


// remote unlock button on blynk app 
BLYNK_WRITE(V9) 
{
   int pinData = param.asInt(); 
  if (pinData == 1)  door_unlock();
}

// receives tracking number from blynk app
BLYNK_WRITE(V10) 
{
   trackingnumber = param.asStr(); 
 
}
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
void setup() 
{
  lcd.begin(20,4);
  lcd_menu0();
  Wire.begin();  
  LED_ctrl_over_i2c (11); // test all status LEDs 
  delay(5000);
  LED_ctrl_over_i2c (0); // test all status LEDs 
  
  delay(5000);
  LED_ctrl_over_i2c (0); // test all status LEDs 
  
  pinMode(D2, OUTPUT);     // output for Servo for lock control 
  analogWriteResolution(D2, 12); // sets analogWrite resolution to 12 bits
  door_lock();

  pinMode(A0,OUTPUT); // voice msg playback control pin
  digitalWrite(A0,LOW); // active high pin
  
   Blynk.begin(auth); // start Blynk
   t1.setInterval(5000L, updateMailbox); //timer will run every 5 sec 
   t2.setInterval(3000L, updateApp); // timer will send data to app every 3 sec
   t3.setInterval(50L,updateKeypad);//timer will run every 30 msec 
  
}


// blynk app update function
void updateApp()
{
if(pkg_flag==0)
{led1.off();led2.on();}
if(pkg_flag==1)
{led1.on();led2.off();}

if (sense_door() == 1)
{led0.on();led3.off();}
else
{led0.off();led3.on();}

if (lock_flag == 1)
{{led4.on();led5.off();}}
else
{{led4.off();led5.on();}}

if (auth_flag == 1)
{{led7.on();led6.off();}}
if (auth_flag == 2)
{{led7.off();led6.on();}}
}


// mailbox control function
void updateMailbox()
{
   sense_package();
   sense_connectivity();
   sense_vbatt();
   sense_wifi_quality();
   
   if(pkg_flag==1&&sense_door() == 1) // auto lock when pkg received and door closed
   {delay(200);door_lock();}
}

// UI (keypad+LCD) control
void updateKeypad ()
{
       scan_keypad_update_display();
}
///////////////////////////////////////////////////////
///////////////////////////////////////////////////////
void loop() 
{
    Blynk.run();
    t1.run(); 
    t2.run(); 
    t3.run();
}// end of main loop

////////////////////////////////////////////////////
 ///////////////////////////////////////////////
 /// SEE Fucntions Below to Understand in details ///
 ///////////// user define functions ///////////
 
 void lcd_menu0(void)
 {
    // print instruction on LCD
    lcd.setCursor(0, 0);
    lcd.print("To Open The Mailbox");
    lcd.setCursor(0, 1);
    lcd.print("Type Tracking Number");
    lcd.setCursor(0, 3);
    lcd.print("'*'= OK, '#'= Clear");
 }

void LED_ctrl_over_i2c (int x)
{
    Wire.beginTransmission(9); // transmit to slave device #9
    Wire.write(x);             // sends one byte
    Wire.endTransmission();    // stop transmitting
  // see arduino code for details (attached below)
}

void sense_package(void)
{
    int val = analogRead(A1);
    if(val<1350) {LED_ctrl_over_i2c (5); pkg_flag =0;}
    // when no package on LDR
    if(val>1500) {LED_ctrl_over_i2c (6);pkg_flag =1;} 
    // when package blocks light on ldr
    //if(val>1500 && pkg_flag ==0) 
    //{Particle.publish("mailbox info", "Package Received", PUBLIC); pkg_flag =1;}
   // Particle.publish("Mail Received")
}


// sense door position photointerrupt
int sense_door(void)
{
   int x = analogRead(A2);
    if(x>4000)
    return 1; // when door closed
    else return 0; // when door lifted/opened
}

// check particle cloud connectivity
void sense_connectivity(void)
{
    if(Particle.connected()) {LED_ctrl_over_i2c (3);}
}

// check battery voltage level
void sense_vbatt(void)
{
    if(analogRead(BATT) * 0.0011224>3.5) {LED_ctrl_over_i2c (7);} 
    else  {LED_ctrl_over_i2c (8);}
}

// check wifi signal quality
void sense_wifi_quality(void)
{
    WiFiSignal sig = WiFi.RSSI();
    float quality = sig.getQuality();
    if (quality>25.0) {LED_ctrl_over_i2c (9);} else {LED_ctrl_over_i2c (10);}
}

 

void door_unlock(void)
{
    analogWrite(D2,120, 50); //  activate servo to unlock  
    lock_flag = 0;
    LED_ctrl_over_i2c (2); // door unlock led
     Particle.publish("mailbox info", "door unlocked", PUBLIC);
}


void door_lock(void)
{
    analogWrite(D2, 320, 50); // activate servo to lock 
    lock_flag = 1;
    LED_ctrl_over_i2c (1); // door lock led
     Particle.publish("mailbox info", "door locked", PUBLIC);
   // char *message = " door locked";
    //Particle.variable("mailbox info", message, STRING);
}


void play_msg(void)
{
    digitalWrite(A0,HIGH); // activate audio on ISD1820 chip
    delay(100);
    digitalWrite(A0,LOW);
    delay(10000);
    

}


void scan_keypad_update_display(void)
{
  char key = keypad.getKey();

// check user input to authenticate and unlock   
  if(key == '*')
  {
      lcd.clear(); 
      lcd.setCursor(0, 0);lcd.print(" You have entered: "); 
      lcd.setCursor(0, 1);lcd.print(String(numberKeypad));
     // if(String(numberUserIn) == String(numberKeypad)) 
       if(trackingnumber  == String(numberKeypad)) 
      {
          lcd.setCursor(0, 2);lcd.print("Authentication Ok !");
          lcd.setCursor(0, 3);lcd.print("  Unlocking Door");
          Particle.publish("mailbox info", "Authentication Success", PUBLIC);
          auth_flag = 1;
         // Particle.publish("Failed Attempt to unlock mailbox");
          LED_ctrl_over_i2c (4);
          door_unlock();
          play_msg();
      }
      else 
      {
          lcd.setCursor(0, 2);lcd.print("Authentication Fail");
          lcd.setCursor(0, 3);lcd.print(" Please Try Again...");
          Particle.publish("mailbox info", "Authentication Failed !!", PUBLIC);
          auth_flag = 2;
         // Particle.publish("Failed Attempt to unlock mailbox");
          
          for(int i = 0; i<20; i++) {numberKeypad[i]='\0';}
          LED_ctrl_over_i2c (0);
          door_lock();
          
      }
    
    delay(1500);
    cursor = 0;
    key = '\0';
    lcd.clear(); lcd_menu0();
        
  }
  // clear typing mistakes (both array and display)
  if(key == '#')
  {
    lcd.clear(); lcd_menu0();
    cursor = 0;
  }
 // read numeric input from keypad  
   else if(key)
  {
    lcd.setCursor(cursor, 2);
    lcd.print(key);
    numberKeypad[cursor] = key;
    cursor++;
  }
}



/*


// following code receives i2c command from Argon
// to control 8 LEDs on front panel
// on 8 GPIO pins of (arduino Uno) Atmega328P

#include <Wire.h>


# define ANTENNA_LED_BLU 5
# define CLOUD_CONN_LED_BLU 6 
# define MAIL_RCV_LED_GRN 7
# define DOOR_UNLOCKED_LED_GRN 8

# define POWER_LED_GRN 9
# define AUTH_SUCC_LED_GRN 10
# define MAIL_NOT_LED_RED 11
# define DOOR_LOCKED_LED_RED 12



int i2C_data = 0;
void setup() 
{
  
  pinMode (POWER_LED_GRN, OUTPUT);
  pinMode (ANTENNA_LED_BLU, OUTPUT);
  pinMode (DOOR_LOCKED_LED_RED, OUTPUT);
  pinMode (DOOR_UNLOCKED_LED_GRN, OUTPUT);
  pinMode (MAIL_RCV_LED_GRN , OUTPUT);
  pinMode (MAIL_NOT_LED_RED , OUTPUT);
  pinMode (CLOUD_CONN_LED_BLU, OUTPUT);
  pinMode (AUTH_SUCC_LED_GRN, OUTPUT);
  
  Wire.begin(9); 
  Wire.onReceive(receiveEvent);
  reset_LED();
}


void loop() 
{
  // reset all LED
 if (i2C_data == 0)
  {
   reset_LED();
  }
  

// when door locked   
  if (i2C_data == 1) 
  {
    digitalWrite(DOOR_LOCKED_LED_RED, HIGH);
    digitalWrite(DOOR_UNLOCKED_LED_GRN,LOW);
  }
// when door unlocked
 if (i2C_data == 2) 
  {
    digitalWrite(DOOR_LOCKED_LED_RED, LOW);
    digitalWrite(DOOR_UNLOCKED_LED_GRN,HIGH);
  }
// when connection to cloud is Ok
 if (i2C_data == 3) 
  {
    digitalWrite(CLOUD_CONN_LED_BLU, HIGH);
  }
// when authentication success
 if (i2C_data == 4) 
  {
    digitalWrite(AUTH_SUCC_LED_GRN, HIGH);
   
  }
// when no mail/package
 if (i2C_data == 5) 
  {
    digitalWrite(MAIL_RCV_LED_GRN, LOW);
    digitalWrite(MAIL_NOT_LED_RED,HIGH);
  }
// when package received
 if (i2C_data == 6) 
  {
  digitalWrite(MAIL_RCV_LED_GRN, HIGH);
    digitalWrite(MAIL_NOT_LED_RED,LOW);
  }
// vbat above 3.5 v
  if (i2C_data == 7) 
  {  
    digitalWrite(POWER_LED_GRN, HIGH);
  }
// vbat below 3.5 v
  if (i2C_data == 8) 
  {  
    digitalWrite(POWER_LED_GRN, LOW);
  }
  // Wifi signal above 50 % 
  if (i2C_data == 9) 
  {  
    digitalWrite(ANTENNA_LED_BLU,HIGH);
  }
// Wifi signal below 50 % 
  if (i2C_data == 10) 
  {  
    digitalWrite(ANTENNA_LED_BLU,LOW);
  }

  if (i2C_data == 11) 
  {  
   test_LED();
  }

}///////////// end of loop////////////////
//////////////////////////////////////////
///////////////// func ///////////////////
void receiveEvent(int bytes) 
{
  i2C_data = Wire.read();    
}

void reset_LED (void)
{
  digitalWrite (POWER_LED_GRN, LOW);
  digitalWrite (ANTENNA_LED_BLU, LOW);
  digitalWrite (DOOR_LOCKED_LED_RED, LOW);
  digitalWrite (DOOR_UNLOCKED_LED_GRN, LOW);
  digitalWrite (MAIL_RCV_LED_GRN , LOW);
  digitalWrite (MAIL_NOT_LED_RED , LOW);
  digitalWrite (CLOUD_CONN_LED_BLU, LOW);
  digitalWrite (AUTH_SUCC_LED_GRN, LOW);  
}

void test_LED (void)
{
  digitalWrite (POWER_LED_GRN, LOW);
  digitalWrite (ANTENNA_LED_BLU, LOW);
  digitalWrite (DOOR_LOCKED_LED_RED, LOW);
  digitalWrite (DOOR_UNLOCKED_LED_GRN, LOW);
  digitalWrite (MAIL_RCV_LED_GRN , LOW);
  digitalWrite (MAIL_NOT_LED_RED , LOW);
  digitalWrite (CLOUD_CONN_LED_BLU, LOW);
  digitalWrite (AUTH_SUCC_LED_GRN, LOW);  
  delay(500);
  digitalWrite (POWER_LED_GRN, HIGH);
  digitalWrite (ANTENNA_LED_BLU, HIGH);
  digitalWrite (DOOR_LOCKED_LED_RED, HIGH);
  digitalWrite (DOOR_UNLOCKED_LED_GRN, HIGH);
  digitalWrite (MAIL_RCV_LED_GRN , HIGH);
  digitalWrite (MAIL_NOT_LED_RED , HIGH);
  digitalWrite (CLOUD_CONN_LED_BLU, HIGH);
  digitalWrite (AUTH_SUCC_LED_GRN, HIGH);  
  delay(500);
    digitalWrite (POWER_LED_GRN, LOW);
  digitalWrite (ANTENNA_LED_BLU, LOW);
  digitalWrite (DOOR_LOCKED_LED_RED, LOW);
  digitalWrite (DOOR_UNLOCKED_LED_GRN, LOW);
  digitalWrite (MAIL_RCV_LED_GRN , LOW);
  digitalWrite (MAIL_NOT_LED_RED , LOW);
  digitalWrite (CLOUD_CONN_LED_BLU, LOW);
  digitalWrite (AUTH_SUCC_LED_GRN, LOW);  
  delay(500);
  digitalWrite (POWER_LED_GRN, HIGH);
  digitalWrite (ANTENNA_LED_BLU, HIGH);
  digitalWrite (DOOR_LOCKED_LED_RED, HIGH);
  digitalWrite (DOOR_UNLOCKED_LED_GRN, HIGH);
  digitalWrite (MAIL_RCV_LED_GRN , HIGH);
  digitalWrite (MAIL_NOT_LED_RED , HIGH);
  digitalWrite (CLOUD_CONN_LED_BLU, HIGH);
  digitalWrite (AUTH_SUCC_LED_GRN, HIGH);  
  delay(500);
}

*/

Atmega328 (arduino uno) I2C LEDs

Arduino
LED control over I2C
// this code receives i2c command from Argon
// to control 8 LEDs on front panel
// on 8 GPIO pins of (arduino Uno) Atmega328P

#include <Wire.h>


# define ANTENNA_LED_BLU 5
# define CLOUD_CONN_LED_BLU 6 
# define MAIL_RCV_LED_GRN 7
# define DOOR_UNLOCKED_LED_GRN 8

# define POWER_LED_GRN 9
# define AUTH_SUCC_LED_GRN 10
# define MAIL_NOT_LED_RED 11
# define DOOR_LOCKED_LED_RED 12





int i2C_data = 0;
void setup() 
{
  
  pinMode (POWER_LED_GRN, OUTPUT);
  pinMode (ANTENNA_LED_BLU, OUTPUT);
  pinMode (DOOR_LOCKED_LED_RED, OUTPUT);
  pinMode (DOOR_UNLOCKED_LED_GRN, OUTPUT);
  pinMode (MAIL_RCV_LED_GRN , OUTPUT);
  pinMode (MAIL_NOT_LED_RED , OUTPUT);
  pinMode (CLOUD_CONN_LED_BLU, OUTPUT);
  pinMode (AUTH_SUCC_LED_GRN, OUTPUT);
  
  Wire.begin(9); 
  Wire.onReceive(receiveEvent);
  reset_LED();
}


void loop() 
{
  // reset all LED
 if (i2C_data == 0)
  {
   reset_LED();
  }
  

// when door locked   
  if (i2C_data == 1) 
  {
    digitalWrite(DOOR_LOCKED_LED_RED, HIGH);
    digitalWrite(DOOR_UNLOCKED_LED_GRN,LOW);
  }
// when door unlocked
 if (i2C_data == 2) 
  {
    digitalWrite(DOOR_LOCKED_LED_RED, LOW);
    digitalWrite(DOOR_UNLOCKED_LED_GRN,HIGH);
  }
// when connection to cloud is Ok
 if (i2C_data == 3) 
  {
    digitalWrite(CLOUD_CONN_LED_BLU, HIGH);
  }
// when authentication success
 if (i2C_data == 4) 
  {
    digitalWrite(AUTH_SUCC_LED_GRN, HIGH);
   
  }
// when no mail/package
 if (i2C_data == 5) 
  {
    digitalWrite(MAIL_RCV_LED_GRN, LOW);
    digitalWrite(MAIL_NOT_LED_RED,HIGH);
  }
// when package received
 if (i2C_data == 6) 
  {
  digitalWrite(MAIL_RCV_LED_GRN, HIGH);
    digitalWrite(MAIL_NOT_LED_RED,LOW);
  }
// vbat above 3.5 v
  if (i2C_data == 7) 
  {  
    digitalWrite(POWER_LED_GRN, HIGH);
  }
// vbat below 3.5 v
  if (i2C_data == 8) 
  {  
    digitalWrite(POWER_LED_GRN, LOW);
  }
  // Wifi signal above 50 % 
  if (i2C_data == 9) 
  {  
    digitalWrite(ANTENNA_LED_BLU,HIGH);
  }
// Wifi signal below 50 % 
  if (i2C_data == 10) 
  {  
    digitalWrite(ANTENNA_LED_BLU,LOW);
  }

  if (i2C_data == 11) 
  {  
   test_LED();
  }

}///////////// end of loop////////////////
//////////////////////////////////////////
///////////////// func ///////////////////
void receiveEvent(int bytes) 
{
  i2C_data = Wire.read();    
}

void reset_LED (void)
{
  digitalWrite (POWER_LED_GRN, LOW);
  digitalWrite (ANTENNA_LED_BLU, LOW);
  digitalWrite (DOOR_LOCKED_LED_RED, LOW);
  digitalWrite (DOOR_UNLOCKED_LED_GRN, LOW);
  digitalWrite (MAIL_RCV_LED_GRN , LOW);
  digitalWrite (MAIL_NOT_LED_RED , LOW);
  digitalWrite (CLOUD_CONN_LED_BLU, LOW);
  digitalWrite (AUTH_SUCC_LED_GRN, LOW);  
}

void test_LED (void)
{
  digitalWrite (POWER_LED_GRN, LOW);
  digitalWrite (ANTENNA_LED_BLU, LOW);
  digitalWrite (DOOR_LOCKED_LED_RED, LOW);
  digitalWrite (DOOR_UNLOCKED_LED_GRN, LOW);
  digitalWrite (MAIL_RCV_LED_GRN , LOW);
  digitalWrite (MAIL_NOT_LED_RED , LOW);
  digitalWrite (CLOUD_CONN_LED_BLU, LOW);
  digitalWrite (AUTH_SUCC_LED_GRN, LOW);  
  delay(500);
  digitalWrite (POWER_LED_GRN, HIGH);
  digitalWrite (ANTENNA_LED_BLU, HIGH);
  digitalWrite (DOOR_LOCKED_LED_RED, HIGH);
  digitalWrite (DOOR_UNLOCKED_LED_GRN, HIGH);
  digitalWrite (MAIL_RCV_LED_GRN , HIGH);
  digitalWrite (MAIL_NOT_LED_RED , HIGH);
  digitalWrite (CLOUD_CONN_LED_BLU, HIGH);
  digitalWrite (AUTH_SUCC_LED_GRN, HIGH);  
  delay(500);
    digitalWrite (POWER_LED_GRN, LOW);
  digitalWrite (ANTENNA_LED_BLU, LOW);
  digitalWrite (DOOR_LOCKED_LED_RED, LOW);
  digitalWrite (DOOR_UNLOCKED_LED_GRN, LOW);
  digitalWrite (MAIL_RCV_LED_GRN , LOW);
  digitalWrite (MAIL_NOT_LED_RED , LOW);
  digitalWrite (CLOUD_CONN_LED_BLU, LOW);
  digitalWrite (AUTH_SUCC_LED_GRN, LOW);  
  delay(500);
  digitalWrite (POWER_LED_GRN, HIGH);
  digitalWrite (ANTENNA_LED_BLU, HIGH);
  digitalWrite (DOOR_LOCKED_LED_RED, HIGH);
  digitalWrite (DOOR_UNLOCKED_LED_GRN, HIGH);
  digitalWrite (MAIL_RCV_LED_GRN , HIGH);
  digitalWrite (MAIL_NOT_LED_RED , HIGH);
  digitalWrite (CLOUD_CONN_LED_BLU, HIGH);
  digitalWrite (AUTH_SUCC_LED_GRN, HIGH);  
  delay(500);
}

Credits

Shahariar

Shahariar

74 projects • 265 followers
"What Kills a 'Great life' is a 'Good Life', which is Living a Life Inside While Loop"

Comments