Reverse Caroling

Description

We were inspired by the music of people going caroling from house to house where the visitor is the one that does the singing. But, what if we reverse who does the singing and instead have the house and person’s home do the caroling? Furthermore, what if the person who visits starts a song and then the person who’s home it is (who is answering the door) adds to that song in a duet or collaborative way? That’s what our caroling house does.

How it works:

  • A visitor walks up to the beginning of the path
  • The christmas lights light up the path
  • The visitor steps on the welcome mat
  • A song begins playing
  • The visitor presses the door bell
  • Snow falls from the gutter to create a wintery environment
  • The person who lives at the house answers the door. When they turn the doorknob, the song changes to a different octave adding to the duet.

Inputs used:

  • FSR (x3)
  • Potentiometer

Outputs used:

  • 6 LEDs
  • piezo speaker
  • servo motor to dump snow from the gutter

Materials used

  • FSR (x3)
  • Potentiometer
  • 6 LEDs
  • Piezo speaker
  • Servo motor
  • 3 Arduinos
  • 4 breadboards
  • 6 220k ohm resistors
  • 4 10k ohm resistor

Doorknob and Welcome Mat Code

// TONES ========================================== // Start by defining the relationship between
 // note, period, & frequency.
 #define C 523
 #define Db 554
 #define D 587 
 #define Eb 622
 #define E 659
 #define f 698 // Does not seem to like capital F
 #define Gb 740
 #define G 783
 #define Ab 830 
 #define A 880
 #define Bb 932
 #define B 988
 #define c_ 1046
 #define dd 1109
 #define d 1175
 #define eb 1244
 #define e 1318
 #define ff 1397
 #define gb 1480
 #define g 1568 
 // Define a special note, 'R', to represent a rest
 #define R 0
 // SETUP ============================================
 // Set up speaker on a PWM pin (digital 9, 10 or 11)
 int speakerOut = 9;
 int FSRPin = A0;
 int potPin = A1;
 int valFSR = 0;
 int valPot = 0;
 int i = 0;
 // Do we want debugging on serial out? 1 for yes, 0 for no
 int DEBUG = 1;
 void setup() {
 pinMode(speakerOut, OUTPUT);
 if (DEBUG) {
 Serial.begin(9600); // Set serial out if we want debugging
 }
 }
 // MELODY and TIMING =======================================
 // melody[] is an array of notes, accompanied by beats[],
 // which sets each note's relative length (higher #, longer note)
 int melody1a[] = {E, E, E,R,
 E, E, E,R,
 E, G, C, D, E, R,
 f, f, f,f, f, E, E,E, E, D ,D,E, D, R, G ,R,
 E, E, E,R,
 E, E, E,R,
 E, G, C, D, E, R,
 f, f, f,f, f, E, E, E, G,G, f, D, C,R, G, R }; 
 
 int melody1b[] = {B, B, B,R,
 B, B, B,R,
 B, D, G, A, B, R,
 C, C, C,C, C, B, B,B, B, D ,D,C, A, R, G ,R,
 B, B, B,R,
 B, B, B,R,
 B, D, G, A, B, R,
 C, C, C,C, C, B, B,B, B, D ,D,C, A, R, G ,R };
 
 //put melody 2a and 2b here 
 int melody2a[] = {E,R, R, R,
 f, E, Eb, E, 
 f, R, R, R, 
 Gb, G, R, R,
 R, A, B, c_, 
 d, c_, B, A, 
 G,R, R, R,
 E,R, R, R,
 f, E, Eb, E, 
 f, R, R, R, 
 Gb, G, R, R,
 R, A, B, c_, 
 d, c_, B, A, 
 G,R, R, R};
 
 int melody2b[] = {A, R, R, R,
 B, A, Ab, A,
 Bb, R, R, R, 
 B, c_, R, R,
 R, d, e, f, 
 g, f, e, d,
 c_, R, R, R,
 A, R, R, R,
 B, A, Ab, A,
 Bb, R, R, R, 
 B, c_, R, R,
 R, d, e, ff, 
 g, ff, e, d,
 c_, R, R, R};
 
// int MAX_COUNT1 = sizeof(melody1) / 2; // Melody length, for looping.
// int MAX_COUNT2 = sizeof(melody2) / 2;
 // Set overall tempo
 long tempo = 10000;
 // Set length of pause between notes
 int pause = 1000;
 // Loop variable to increase Rest length
 int rest_count = 100; //<-BLETCHEROUS HACK; See NOTES
 // Initialize core variables
 int tone_ = 0;
 int beat = 0;
 long duration = 0;
 // PLAY TONE ==============================================
 // Pulse the speaker to play a tone for a particular duration
 void playTone() {
 long elapsed_time = 0;
 if (tone_ > 0) { // if this isn't a Rest beat, while the tone has
 // played less long than 'duration', pulse speaker HIGH and LOW
 while (elapsed_time < duration) {
 digitalWrite(speakerOut,HIGH);
 delayMicroseconds(tone_ / 2);
 // DOWN
 digitalWrite(speakerOut, LOW);
 delayMicroseconds(tone_ / 2);
 // Keep track of how long we pulsed
 elapsed_time += (tone_);
 }
 }
 else { // Rest beat; loop times delay
 for (int j = 0; j < rest_count; j++) { // See NOTE on rest_count
 delayMicroseconds(duration); 
 } 
 } 
 }
 
 void playNote(int melody[]) {
 tone_ = melody[i];
 beat = 50;
 duration = beat * tempo;
 playTone();
 delayMicroseconds(pause);
 }
 
 // LET THE WILD RUMPUS BEGIN =============================
 
 void loop() {
 valFSR = analogRead(FSRPin); // read value from the sensor
 valPot = analogRead(potPin);
// int *melody = melody1; ///fix later
 if (valFSR >= 10 && valFSR < 500 ){ 
 Serial.println(valFSR);
 Serial.println(valPot);
 if (valPot < 10) {
 int *melody = melody1a;
 playNote(melody);
 } else {
 int *melody = melody1b; //move to duet
 playNote(melody);
 }
 }
 if (valFSR >= 500 ){ 
 Serial.println(valFSR);
 Serial.println(valPot);
 if (valPot < 10) {
 int *melody = melody2a;
 playNote(melody);
 } else {
 int *melody = melody2b; //move to duet
 playNote(melody);
 }
 }
// playNote(melody);
 i++;
}
// if (valFSR >= 500) { //second song
// Serial.println(valFSR);
// int *melody = melody1a;
// playNote(melody);
// i++;
// }
// if (i%60 == 0) {
// i = 0;
// }
//}

<img class="alignnone size-medium wp-image-2088" src="http://blogs.ischool.berkeley.edu/i262/files/2016/11/IMG_7584-300x225.jpg" alt="img_7584" width="300" height="225" />

Spookoo Clock

Video:  https://youtu.be/ukvsB9rwcKE

 

Our group’s ideas ranged far and wide for this one, but after considerable debate we realized we wanted to create a project with at least the following characteristics:

  1. Halloween themed, with a
  2. Nontraditional door, and which
  3. Respects the cuckoo-clock MO

With these parameters in mind our project became clear to all of us all at once: an egg that hatches a skeleton cuckoo bird through an egg shell door.

We started with a cardboard model, which we then measured and recreated in Fusion 360. For our hinge and door mechanism we decided to employ a “living hinge” design that we laser cut from plywood. We actuated the door with a gear and crank glued to the inside of the box, and added a second gear to drive a rack at the base of our bird design. As the gears turn the bird is propelled upwards and the lid opens.

We had some ideas about how to give the bird some personality, too, by having it “peep” when it reached the top of its stroke. We were able to do this on a timer, and had plans to incorporate a microphone so that a loud noise would startle the bird out of its shell. While we did include the mic in our schematic, a little more work is needed on the code to get that particular functionality set up.

Materials:

Plywood, 1/8″

Small servo motor

Wires

Arduino Uno

Wood glue

Machine screws

SparkFun Mic

Breadboard

Piezo Speaker

 

Code:

/* Sweep
by BARRAGAN <http://barraganstudio.com>
This example code is in the public domain.

modified 8 Nov 2013
by Scott Fitzgerald
http://www.arduino.cc/en/Tutorial/Sweep
*/

#include <Servo.h>

Servo myservo; // create servo object to control a servo
// twelve servo objects can be created on most boards

int pos = 0; // variable to store the servo position
const int sampleWindow = 250; //250 MS sample width
unsigned int loudNoise;
int speakerPin = 7;
int val = 0;
int orig = 0;
int potPin = 0;
void setup()
{
pinMode(speakerPin, OUTPUT);
Serial.begin(9600);
Serial.println(“ready”);
myservo.attach(9); // attaches the servo on pin 9 to the servo object
}

void loop() {
unsigned long start= millis(); // start of sample window
unsigned int peakToPeak = 0; // peak-to-peak level
unsigned int signalMax = 0;
unsigned int signalMin = 1024;
Serial.print(“loudNoise”);
Serial.print(loudNoise);
Serial.println();

while (millis() – start < sampleWindow) // collecting data for 250 MS (can be changed)
{
loudNoise = analogRead(0);
if (loudNoise < 1024) //
{
if (loudNoise > signalMax) // if there’s a loud noise, save the loud value
{
signalMax = loudNoise;
}
else if (loudNoise < signalMin) // if there’s not a loud noise, don’t save the loud value
{
signalMin = loudNoise;
}
}
}

peakToPeak = signalMax – signalMin; // max – min = peak-peak amplitude
double volts = (peakToPeak * 3.3) / 1024; // convert to volts
Serial.println(volts); // to know if the mic is working

// digitalWrite(speakerPin, LOW);
//myservo.write(180);

//val = analogRead(potPin); // read value from the sensor
//val = val*30; // process the value a little
//val = val/2; // process the value a little

if (volts >=1.0){
for( int i=0; i<50; i++ ) { // play it for 50 cycles
for(pos = 180; pos>=0; pos-=9) // goes from 180 degrees to 0 degrees
{
myservo.write(pos); // tell servo to go to position in variable ‘pos’
delay(15); // waits 15ms for the servo to reach the position

};
delay(6000);
for(pos = 0; pos <= 180; pos += 3) // goes from 0 degrees to 180 degrees
{ // in steps of 1 degree
myservo.write(pos); // tell servo to go to position in variable ‘pos’
delay(80); // waits 15ms for the servo to reach the position
};
delay(500);
for(int j=0; j<50; j++){

digitalWrite(speakerPin, HIGH);
delayMicroseconds(800);
digitalWrite(speakerPin, LOW);
delayMicroseconds(800);
};

};
}
//if (volts >=1.0) {

// delay(2000); // for a certain amount of time (though this could be modified for more expressive behavior)
// Serial.println(“YELLING AT US”);
// }
// else {
// digitalWrite(12, LOW);
// digitalWrite(2, LOW); //not yetlling at us
// };
else {
myservo.write(0);
delay(1000);
}
};

 

20161026_040041 20161026_040150 20161026_040154 20161026_040113 20161021_192202 20161021_181655