White-board box that unlocks through a 3×3 button pattern.

Decisions

A major decision I had to make was what enclosure to make for my password box. I could have gone the easy route and just purchased a box at a store, but I wanted to use the resources available through this course to create one myself, so I decided to laser cut one out of white board material. Another decision I had to make was how to make the box lock. There were difficulties because I had to implement the mechanism on the top half of the box, but the top half of the box was only a little over an inch in thickness, so it didn’t give me a lot of room to work with. I was able to mock up a mechanism that rotates a servo motor under a ledge on the lower half of the box so that when the user tries to open it while it was locked, the ledge blocks the servo motor from moving upwards which “locks” the box. When the password is entered, the servo motor rotates allowing the box to open up freely.

Self-Critique

For Project 1, I made a very simple box that lights up in one mode, and plays music in another mode and was very simple in both software and mechanically, so I wanted to challenge myself in Project 2 to make something more complicated in both of those aspects. However, during the brainstorming phase it was very difficult to come up with an idea since I wasn’t sure of any assistive devices I needed. After browsing through the different equipment in the IDeATe classroom, I discovered the 4×4 Adafruit Trellis keypad and decided to make a password box for myself to keep my items safe. I was content with how my project turned out because It was fully functional and also looked intricate because it was cut through the laser cutter. It was also sophisticated in software because I coded it from scratch from techniques I learned through class. The project also required me to learn a new piece of technology, the trellis keypad, which was difficult at first to learn how to utilize. One aspect I wish I could have improved my project in was by adding more functionality with the keypad by adding a reset password option where it allows the user to set their own unique passcode. However, because of issues with time, I was unable to fully implement that by the time of the deadline.

The trellis keypad with soldered in LEDS (Red – Password, Blue – Reset, Green – Enter)

Surprises

One aspect in my project I was concerned about after deciding on the idea was what I wanted to use for my enclosure. However, I discovered that I could create boxes using the laser cutter that don’t require any adhesive, like glue or tape, to keep it assembled. It even had a rotating mechanism on the corners that allows it to open and close smoothly, so being able to create my enclosure with a laser cutter was the most surprising aspect for me through this project, and it turned out very well. An aspect that did not work as well as expected was the mechanism I had in place for to lock the box. I had Styrofoam super-glued onto a servo motor that caused it to lock when the servo motor was rotated at a certain angle. However, it wasn’t the wisest choice to use Styrofoam cause it is not very sturdy and caused a few issues. First, when it was locked, the box would open with a little force despite being locked, and also the Styrofoam would also break if enough strength was used to try and open the box. I decided to use Styrofoam to save time, but the outcome wasn’t as expected.

Initial cardboard mock up of box

Laser-cut whiteboard pieces of final box

What I Learned

I was surprised in my ability with being able to code the passcode box within the time that it took me because this class is my first time coding in Arduino and I had no prior knowledge on how to use arrays, use modules like the trellis library, etc. However with a bit of research and prior experience with coding in Python and C, I was able to figure out how to implement more complicated methods with arrays. I had to sort the arrays so that the order that the user inputs the password does not matter. I also had to learn how to compare whether arrays were equal because there was no simple way of doing so in Arduino. Through this project I learned how to use an important data type. Something I also learned about myself through this project was how I can improve in my creativity skills. I struggled a lot through the brainstorming phase and all of my initial ideas weren’t very possible because it was too simple or too difficult mechanically to create. I was only able to think of my idea for this password box because I discovered the keypad in the classroom.

Inside of the box with the servo-motor locking mechanism shown

Next Steps

If I were to build another iteration of this project, I would first create a sturdier box by super gluing the entire box together, so it would be a lot more difficult to break into it. The purpose of the box was to keep things safe, but with the current version, a side could pretty easily be taken off, and the intruder has easy access to the belongings inside. Another improvement I would make is to replace the Styrofoam with wood to make the lock more sturdy. The Styrofoam lock can be easily broken if enough force is applied in trying to open the box. Lastly, I would also add a password reset button where the user can make their own passcode because leaving it at a default passcode would make it too easy to break into.

Schematic

Code


#include <Wire.h>
#include "Adafruit_Trellis.h"
#include <Servo.h>

#define MOMENTARY 0
#define LATCHING 1
#define MODE LATCHING

Adafruit_Trellis matrix0 = Adafruit_Trellis();
Adafruit_TrellisSet trellis =  Adafruit_TrellisSet(&matrix0);

Servo servo;
int servoPin = 3;

#define NUMTRELLIS 1
#define numKeys (NUMTRELLIS * 16)

#define INTPIN A2

int passcode[] = {0, 2, 8, 10};
int userpass[] = { -1, -1, -1, -1};
int passi = 0;
int counter = 0;
int enter = 0;

void setup() {
  Serial.begin(9600);
  pinMode(INTPIN, INPUT);
  digitalWrite(INTPIN, HIGH);

  trellis.begin(0x70);

  for (uint8_t i = 0; i < numKeys; i++) {
    if (!checknum(i)) {
      trellis.setLED(i);
      trellis.writeDisplay();
      delay(50);
    }
  }
  servo.attach(servoPin);
  servo.write(170);
}

boolean array_cmp(int *a, int *b, int len_a, int len_b) {
  int n;
  if (len_a != len_b) return False;
  for (n = 0; n < len_a; n++) if (a[n] != b[n]) return False; return True; } int sort_desc(const void *cmp1, const void *cmp2) { int a = *((int *)cmp1); int b = *((int *)cmp2); return a > b ? -1 : (a < b ? 1 : 0);
}

void printpass(int userpass[]) {
  Serial.print(userpass[0]);
  Serial.print(" ");
  Serial.print(userpass[1]);
  Serial.print(" ");
  Serial.print(userpass[2]);
  Serial.print(" ");
  Serial.print(userpass[3]);
  Serial.print(" \n");
}

void clearkeypad() {
  trellis.clrLED(0);
  trellis.clrLED(1);
  trellis.clrLED(2);
  trellis.clrLED(4);
  trellis.clrLED(5);
  trellis.clrLED(6);
  trellis.clrLED(8);
  trellis.clrLED(9);
  trellis.clrLED(10);
  trellis.writeDisplay();
}

void lightkeypad() {
  trellis.setLED(0);
  trellis.setLED(1);
  trellis.setLED(2);
  trellis.setLED(4);
  trellis.setLED(5);
  trellis.setLED(6);
  trellis.setLED(8);
  trellis.setLED(9);
  trellis.setLED(10);
  trellis.writeDisplay();
}

void resetpass(int userpass[]) {
  userpass[0] = -1;
  userpass[1] = -1;
  userpass[2] = -1;
  userpass[3] = -1;
}

int checknum(int i) {
  if (i == 0) {
    return 1;
  }
  else if (i == 1) {
    return 1;
  }
  else if (i == 2) {
    return 1;
  }
  else if (i == 4) {
    return 1;
  }
  else if (i == 5) {
    return 1;
  }
  else if (i == 6) {
    return 1;
  }
  else if (i == 8) {
    return 1;
  }
  else if (i == 9) {
    return 1;
  }
  else if (i == 10) {
    return 1;
  }
  else {
    return 0;
  }
}

int checkinarray(int i, int userpass[], int len) {
  int x;
  for (x = 0; x < len; x++) {
    if (userpass[x] == i) {
      return 1;
    }
  }
  return 0;
}

void blinkkey(int i, int j, int k, int l) {
  delay(500);
  trellis.clrLED(i);
  trellis.clrLED(j);
  trellis.clrLED(k);
  trellis.clrLED(l);
  trellis.writeDisplay();
  delay(500);
  trellis.setLED(i);
  trellis.setLED(j);
  trellis.setLED(k);
  trellis.setLED(l);
  trellis.writeDisplay();
  delay(500);
  trellis.clrLED(i);
  trellis.clrLED(j);
  trellis.clrLED(k);
  trellis.clrLED(l);
  trellis.writeDisplay();
  delay(500);
  trellis.setLED(i);
  trellis.setLED(j);
  trellis.setLED(k);
  trellis.setLED(l);
  trellis.writeDisplay();
  delay(500);
  trellis.clrLED(i);
  trellis.clrLED(j);
  trellis.clrLED(k);
  trellis.clrLED(l);
  trellis.writeDisplay();
}

void loop() {
  delay(30);

  if (trellis.readSwitches()) {
    // go through every button
    for (uint8_t i = 0; i < numKeys; i++) {
      // if it was pressed...
      if (trellis.justPressed(i)) {
        // Alternate the LED
        if (checknum(i)) {
          if (counter < 4) {
            if (!checkinarray(i, userpass, 4)) {
              userpass[passi] = i;
              passi += 1;
              counter += 1;
              if (trellis.isLED(i))
                trellis.clrLED(i);
              else
                trellis.setLED(i);
            }
          }
        }
        else if (i == 3) {
          resetpass(userpass);
          clearkeypad();
          passi = 0;
          counter = 0;
          servo.write(170);
        }
        else if (i == 11) {
          if (counter == 4) {
            enter = 1;
          }
        }
      }
    }
    // tell the trellis to set the LEDs we requested
    trellis.writeDisplay();
  }

  qsort(userpass, 4, sizeof(userpass[0]), sort_desc);
  qsort(passcode, 4, sizeof(passcode[0]), sort_desc);

  Serial.print(counter);
  Serial.print(" ");
  printpass(userpass);

  if ((counter == 4) && enter) {
    if (array_cmp(passcode, userpass, 4, 4)) {
      Serial.print("Correct");
      lightkeypad();
      enter = 0;
      servo.write(80);
    }
    else {
      Serial.print("Incorrect");
      blinkkey(userpass[0], userpass[1], userpass[2], userpass[3]);
      resetpass(userpass);
      passi = 0;
      clearkeypad();
      counter = 0;
      enter = 0;
    }
  }

}