Arduino Secret Box

Placing objects within this box opens a hidden trapdoor...

arduino,physical computing

3/16/2015

I've been looking for a way to improve my skills with circuits and arduino, and figured a surprise box for my girlfriend would force me to learn. I had a simple idea - items placed in the box would activate a secret door in the box with a special surprise inside...

I thought I'd share a little of my process so that anyone who's interested can avoid making the same mistakes I did, and hopefully learn a few things too.

My initial attempts were way too overblown for my skill level. I wanted to have five items go into pre-cut compartments in the box. Each would have a photocell sensor to detect whether it had been covered up with the appropriate object, and each would have an LED that would light up when that was done. When all objects had been placed inside, a push of a button would open a servo-controlled door cut out of the box, revealing the secret compartment.

The problem with this was that there were way too many wires to stuff into such a tight space. Since this was going to be a one-off project and my knowledge of creating PCBs was limited, I kept everything on the breadboard. But wires were always getting disconnected and or shorting, and it was hard to troubleshoot where the problem was occurring.

Because of this, I learned a lot about soldering, using a multimeter, using different wire connectors, and the magic of shrink wrap. I also decided that, with a short deadline and a desire to keep the project fun and not frustrating, I'd scale back to just one sensor, one button, and one servo.

I had enough programming knowledge, but not a ton of fabrication knowledge. I first tried ordered some very cushy foam from Zoro but it was too thick and not nearly dense enough to cut into. I kept getting these very ragged edges. To avoid paying $5 every time I wanted a few squares of foam shipped to me, I realized I had to go somewhere I could actually touch the materials.

At JoAnn's I found these foamies - which worked out perfect. They're thin, stretchable enough to be forgiving when you have to jam a wire or sensor through, a nice dark black, and cheap ($12 for 10). I needed one layer under them though that was a little more rigid so that pressing the button would have a better tactile response, so I got some foam board from office depot which was far more expensive, and mounted the button to that.

I originally tried cutting everything with an exacto, but either it's really hard to get nice edges, or I just need to sharpen my knife / knife skills, because I kept getting ragged edges. This was finally the impetus I needed to join a maker space in albany called Tech Valley. The one they had there was in sort of rough shape, and usage directions were sparse, plus it couldn't cut anything much thicker than the foamies I'd purchased. Alone in the shop learning to use it, I learned the value of careful planning and measuring by almost starting a couple small fires due to improper calibration.

A non-powerful laser doesn't make a sharp line as it cuts - it burns away, so you lose some material in the process. The further the laser is from the surface, the more you seem to lose. But getting too close to the surface can cause too much heat / fire. As a result, the secret door for my box wasn't so "secret" - the line is clearly visible, but without any method of opening it from the outside without tools, I figured it'd do the job.

The box itself I ordered off of etsy - as were all of the objects that would need to be placed in the box. I made rough traces of the objects on paper, brought them into illustrator to refine, and then output those to the laser cutting software as svg files.

The foam layers sit above the bottom of the box by way of a couple wood blocks. It was easy enough to just set those into place and glue the foam layers to them. I kept the cushy foam squares from zoro for the bottom of the box so that the arduino and protoboard wouldn't get messed up when hauling the box around. That actually worked nicely, as the solder holes tended to snag in the foam, keeping everything in place without the need to anchor it with something more formal. If I did it all over again, I'd make compartments for everything though.

The project was powered off of 4 AAs, though I don't know why I didn't just use a 9V - would have saved space and been cheaper, and probably had more battery life (can anyone verify this?). The motor had its own power source, a 9V, because the arduino sucked away just enough power that I was getting some functional aberrations. I used a little hobby motor from adafruit. I couldn't decide if it was embarassing or endearing how weak this thing was. When it activates the door it sounds like it's dying - but if it can't reach its prescribed angle of rotation, it's amazing how persistent it is! It keeps trying to get there, which resulted in me bending the arm attached to the servo a few times. I recommend getting your angles worked out before putting everything into the box. If anyone has a recommendation for a nice, fast motor that doesn't cost an arm and a leg and is small / doesn't consume too much power, I'd love to hear about it.

For the servo arm, I just used round lollipop sticks. There were a bunch of wooden dowels and things I could've bought, but the lollipop sticks were way cheaper and way stronger. Plus they're hollow inside, so if you needed to, you could run wire through them!

The hinge I got from Lowe's. I wasn't happy with how I handled the door itself. The hinge should have been on the inside, but that would've meant more cutting away at the door and the box, and I didn't have time. So I just slapped some model paint on it and put it on top of the box.

When it came to the protoboard - I jumped on this waaay too early. This should be the last thing you do. Make sure everything works on a breadboard first - and then move one component at a time to the protoboard and solder. Then test. I can't stress this enough. Unless you're good with a multimeter in testing where a problem is, it's infinitely easier to solder something, then test it, then solder another, then test. The slightest short or bad solder joint and you will be scratching your head and having to desolder and pull out wires, wasting money and materials.

Also, get a third hand. It is unbelievable how much I use this, and how impossible everything seems when I don't. Only $6! Your solder joints will be way cleaner. Also, speaking of soldering, make sure you use shrink wrap over exposed wire, unless you're using some other kind of connector. Since power and ground wires often run together, it's easy to get shorts unless they are protected. Just get in the habit of sliding a little bit on one side of the wire before you solder, then slide it over the exposed wire when you're done, and heat it with the base of your soldering iron closest to the handle quickly to get a nice tight seal. You'll save a lot of frustration, especially when working in a tight space like a little tin box.

As for the other components, I recommend these for buttons. I find that the smallest buttons on the market are a little too cheap, but going one size up eliminates a lot of the falling apart and jankiness, plus they have a better feel. I did a crappy job of cutting the hole for my push button - there was a lot of gap around it, some of which is caused by the way that the pins emerge from the button at the outsides, rather than straight below. I filled the gaps with sugru, which is really versatile putty that dries hard after about 30 minutes of being exposed to air, and which we'll probably some day find gives you cancer. It hid my janky cuts nicely, and kept things in place.

These photocells worked like a charm. They consume very little power and are amazingly reliable on the readouts. As for LEDs, just your run of the mill 10mm green LED is fine, though I highly recommend these LED holders to keep everything in place. The LED sort of snaps in to these, and they look good resting in your project surface, covering up any gaps you may have nicely. They have a tendency to slide back down, but you can put a little bit of glue inside if you're ready to commit to keeping them in the holder.

I've included the fritzing diagram for the project layout, and below is the arduino code:


#include <Servo.h>

const int buttonPin = 2;     // the number of the pushbutton pin
boolean buttonPushed = false;

const int ledPin =  13;      // the number of the LED pin


const int servoPin = 9;
Servo servo;
int angle = 0;
int servoStartAngle = 90;
int servoEndAngle = 10;

boolean servoActivated = false;

// variables will change:
int buttonState = 0;         // variable for reading the pushbutton status

int photoCellPin = 2;
int photoCellThreshold = 500;
int photoCellActivated = false;


void setup() {
  Serial.begin(9600);
  // initialize the LED pin as an output:
  pinMode(ledPin, OUTPUT);
  // initialize the pushbutton pin as an input:
  pinMode(buttonPin, INPUT);

  servo.attach(servoPin);
  servo.write(servoStartAngle);

}

void loop(){
  // read the state of the pushbutton value:
  buttonState = digitalRead(buttonPin);

  int photoCellVal = analogRead(photoCellPin);

  if (photoCellVal < photoCellThreshold){
   photoCellActivated = true;
  } else {
   photoCellActivated = false;
  }

  // check if the pushbutton is pressed.
  // if it is, the buttonState is HIGH:
  if (buttonState == LOW && buttonPushed == false) {
    // turn LED on:
    buttonPushed = true;
    Serial.println("button pushed");
  } else if (buttonState == LOW && buttonPushed == true){
   buttonPushed = false;
   Serial.println('deactivate');
  }



  if (buttonPushed == true){
   digitalWrite(ledPin, HIGH);
  } else {
   digitalWrite(ledPin, LOW);
  }

  if (buttonPushed && servoActivated == false && photoCellActivated == true){
    servoActivated = true;
    Serial.println("activate motor");

    for(angle = servoStartAngle; angle > servoEndAngle; angle--){
      servo.write(angle);
      Serial.println(angle);
      delay(15);
    }
  } else if (buttonPushed == false && servoActivated == true){ //deactivate
    for(angle = servoEndAngle; angle < servoStartAngle; angle++){
      servo.write(angle);
      Serial.println(angle);
      delay(15);
    }
    delay(200);
    servoActivated = false;

  }

  delay(200);
}

Far and away the biggest improvement I would make next time around is to be smarter about how I used power. I asked this question at the very end of building everything, realizing that the box would have to stay powered for an indeterminate amount of time, and realized the project wouldn't last long on a few batteries at all.

I haven't had a chance to implement these, but I got some outstanding answers on Stack Exchange about estimating battery run time, troubleshooting power issues, and moving your project off the breadboard and onto a PCB / protoboard.

Lastly, here's a few amazing links I discovered in the process of building: