Our birdhouse has two doors, and the project has a series of surprises. When a user comes close enough to the birdhouse,  the “bird” in the birdhouse starts singing. Then when the user interacts with the bird vocally, the lower door opens to reveal an egg. Then if the user tries to reach for the egg, the upper doors open, the lower door closes, and a “scare bird” appears.

Functionalities and design are depicted as follows:

A front view of the birdhouse.

Side and base detailing of the birdhouse.

A front view of the birdhouse with all doors open at the same time (this doesn’t actually happen, but is instead set up here for demonstration’s sake)

Interior detailing of our birdhouse (the bird lives downstairs).

The magic in our doors was in these cardboard hinges (and the servos, but more on that later).

Below is a 2-part demo of each of the surprises in succession:

The design phase of our project took the longest, but gave us the clearest idea on how to proceed. During this time, we planned out the overall layout of our house, including dimensions for laser cutting, wiring, and placement of each of our surprises.

Whiteboarding the birdhouse- surprisingly for us, the ideation wasn’t nearly as tough as the execution.

One of the biggest challenges we ran into was opening the doors. While we knew servo motors were the best way to go about this, the actual placement and execution required a great deal of thought. Eventually, we decided on the top door’s opening to be a combination of a cardboard hinge, some carefully planned degree measurements for opening, and a servo mounting right next to the door.

Our initial door opening idea- we used a very similar concept for the final version, but made slight modifications to how the servo motor was mounted to maintain stability.

The size of the egg proved to be a large impediment in trying to open the bottom door. Since both the egg and the door’s radius were too large, it was not feasible to open the bottom door in the same way as the top door. One idea we tried was a revolving door with the egg on the other side, but the servo motor’s range and the egg’s size made this difficult. Hence, we decided on a simpler approach: that the egg itself would have a dowel attached to it, which would push aside a curtain every time the egg was to reveal itself.

The egg-door design before the curtains.

Overall, this project challenged our design skills, creativity, and technical knowledge on multiple fronts. While it was fairly easy to design the schematic, and put wires up (we had 3 inputs- switch, sound sensor, ultrasonic ranger- and 4 outputs- speaker and 3 servo motors), it was much tougher to find the right angles to open the door while ensuring it wouldn’t stick to the door frames, causing the glue to come off, as well as connect the servo motor to the door at the correct angle. 

We learned that mechanics (especially opening the door) should be considered more thoroughly while designing any moving parts in a project, and that a sound threshold is typically hard to set considering the development and production environments are very different. 

Given more time, we would have used an ultrasonic ranger better than the ones we had on hand, especially since it would have saved time trying to optimize the distance thresholds. In addition, if the lower door had been laser cut into two pieces, the servomotors could have been attached the same way as the upper doors, which may have reduced the difficulty involved with the mechanics of the lower door, though the egg may have still posed a very similar problem.

Arduino code:

#include<Servo.h>
#include <Chirp.h>

Servo topLeft;
Servo topRight;
Servo bot;

const int TOPLEFTPIN = 7;
const int TOPRIGHTPIN = 8;
const int BOTPIN = 9;
const int SOUNDSENSORPIN = A0;
const int SPEAKERPIN = 3;
const int CHIRPERTRIGGERPIN = A1;
const int CHIRPERECHOPIN = A2;
const int SWITCHERPIN = 2;
const int SOUNDTHRESHOLD = 40;
Chirp chirp;

void setup() {
  topLeft.attach(TOPLEFTPIN);
  topRight.attach(TOPRIGHTPIN);
  bot.attach(BOTPIN);
  pinMode(CHIRPERTRIGGERPIN, OUTPUT);
  pinMode(CHIRPERECHOPIN, INPUT);
  pinMode(SOUNDSENSORPIN, INPUT); //analog
  pinMode(SPEAKERPIN, OUTPUT); //digital
  pinMode(SWITCHERPIN,INPUT); //digital
  Serial.begin(9600);
  bot.write(170);
  topLeft.write(45);
  topRight.write(100);
}

bool within5m = false;
bool soundSensed = false;
bool within10cm = false;

int get_distance(){
  Serial.print("calling&returing: ");
  unsigned long duration;
  int distance;
  digitalWrite(CHIRPERTRIGGERPIN, HIGH);
  delay(1);
  digitalWrite(CHIRPERTRIGGERPIN, LOW);
  duration = pulseIn(CHIRPERECHOPIN, HIGH, 20000);
  distance = duration / 57;  // Divide by round-trip microseconds per cm to get cm
  return distance;
}


void loop() {
  if(digitalRead(SWITCHERPIN)==0){
    int distance = get_distance();
    int soundLevel = analogRead(SOUNDSENSORPIN);
    Serial.print(soundLevel>=SOUNDTHRESHOLD);
    Serial.print("loop: within5m:");
    Serial.print(within5m);
    Serial.print(" ,soundSensed:");
    Serial.print(soundSensed);
    Serial.print(" ,within10cm:");
    Serial.print(soundSensed);
    Serial.print(" distance:");
    Serial.print(distance);
    Serial.print(" SoundLevel:");
    Serial.println(soundLevel);
    //within5m: bird sings
    if(within5m && soundSensed && within10cm){
      /*two resetting states:
        1. when chirper no longer within 5m
        2. end of cycle(all triggers are triggered)*/
      Serial.print("Resetting due to: ");
      if(distance> 40){
        Serial.println("distance greater than 5m; ");
      }
      else{
        Serial.println("end of cycle; ");
      }
      within5m = false;
      soundSensed = false;
      within10cm = false;
      bot.write(180);
      topLeft.write(45);
      topRight.write(100);
    }
    else if(distance<=40 && distance>15 && !within5m && !within10cm && !soundSensed){
      /*Bird starts singing when chirper detecte within 5m*/
      /*NOTE: WE REQUIRE THE DISTANCE TO BE BETWEEN 10CM AND 5M*/
      //TODO: singing
      Serial.println("Within 5m");
      chirp.chirp("parrotbilllllahcm4");
      delay(500);  
      within5m = true;
    }
    else if(within5m && !soundSensed && soundLevel>=SOUNDTHRESHOLD && !within10cm){
      /*After bird starts singing, when sound is sensed, lower doors open*/
      Serial.println("Sound triggered");
      bot.write(100);
      soundSensed = true;
    }
    //within10cm: top doors open and bird yells
    else if(within5m && soundSensed && distance<=15){
       /*after sound triggered, when chirper detects within10cm: top doors open and bird yells*/
      //TODO: yelling
      Serial.println("Within 10cm");
      topLeft.write(160);
      topRight.write(45);
      bot.write(180);
      //chirp.chirp("parrotbilllllahcm4");
      chirp.chirp("birdhouseplzworkty");
      within10cm = true;
      delay(3000);
    }
  }

A schematic is available here.