49-713 Designing for the Internet of Things
· 26 members
A hands-on introductory course exploring the Internet of Things and connected product experiences.
Distract my roommate from noises in my bedroom
INTRODUCTION
Things can get noisy in my bedroom - there’s music, clanking radiators, you name it. So I originally wanted to build a white noise machine to help my roommate Stephanie ignore those sounds. Unfortunately, the necessary parts didn’t arrive in time, so instead I built the Cinco Dream Machine - an animatronic nightmare fuel IoT device. Basically, it plays the theme from Mario Kart, while a Mario character (powered off a servo) diabolically waves. The effect is so disturbing that Stephanie is sure to forget about whatever’s happening in my room whenever the din rises above 50 decibels.
Inspired by the bestselling Cinco B'ougar (www.youtube.com/watch?v=dYbiwFpqA4s_)
GOAL
I wished to create a fully integrated IoT device with outputs along as many modalities as possible. The piezo makes music. The servo drives the animatronic Mario. IFTTT serves up the Justin Bieber song “Sorry” (though only once per disturbance).
PROCESS
I began the project by thinking of a simple MVP: make the piezo emit sound once the audio sensor is triggered, then send a text. Seeing as this was solved (using provided code and peripherals - thank you Joseph) more quickly than expected, I started to add functionality. First, I tracked down longer tunes. One source on Instructables included the notes to the Mario Kart video game, so I integrated this code and library into my sketch.
Next, I added in the servo motor using our DIoT tutorial as a reference. Taking the obvious next step, I used the servo arm’s motion to drive a small figure. As I’ve never done anything mechanical before, I had to wrack my brain for a long time before I could figure out a gear arrangement that would translate 180’ circular oscillations into human-like motion. Once this architecture made sense in my head, I mocked it up in Rhino, then 3D-printed the resulting parts.
I tried but failed to make all these functions run at the same time.
OUTCOME
The Cinco Dream Machine works exactly as intended. Stephanie finds it horrific and will certainly be distracted by this device as soon as it’s triggered. Between the Mario melody, the figure, and the texted Bieber video, her attention will inevitably be drawn away from the din in my room.
BOM
-Photon
-Audio sensor
-Breadboard, wires
-Servo
-Piezo
-3D-printed gears and housing
REFLECTION
Everything I encountered in this project was entirely new to me (apart from the 3D-printing). The DIoT labs were quite helpful, as was the Arduino forum. Joseph’s initial advice over the weekend jumpstarted everything, so I owe him a big debt of gratitude. I’m still disappointed that my alarm clock peripherals didn’t arrive in time to add to the mayhem.
/*
CINCO DREAM MACHINE
(C) 2017 Reggie Raye
*/
#include "captouch.h"
#include "pitches.h"
//#include "Servo.h"
#define CAPTOUCH_DEBUG
int numLeds = 5;
int ledPins[5] = {D0,D1,D2,D3,D4};
int touchLed = D7;
//servo shit
int servoPin = A5;
Servo servo;
int angle = 0; // servo position in degrees
int oscillation = 0;
int max_osc = 3;
//the following are from piezo
int speakerPin = D0;
int melody[] = {262,196,196,220,196,0,247,262};
int noteDurations[] = {4,8,8,4,4,4,4,4 };
int STFU_threshold = 500; //should be 500-600
int songDuration = 60000;
int mic_pin = A0;
int noise_level = 0;
int Mario_melody[] = {
NOTE_E4, NOTE_E4, REST, NOTE_E4,
REST, NOTE_C4, NOTE_E4, REST,
NOTE_G4, REST, REST, NOTE_G3, REST,
NOTE_C4, REST, REST, NOTE_G3,
REST, NOTE_E3, REST,
REST, NOTE_A3, REST, NOTE_B3,
REST, NOTE_AS3, NOTE_A3, REST,
NOTE_G3, NOTE_E4, NOTE_G4,
NOTE_A4, REST, NOTE_F4, NOTE_G4,
REST, NOTE_E4, REST, NOTE_C4,
NOTE_D4, NOTE_B3, REST
};
int Mario_Notes[] = {
4, 4, 4, 4,
4, 4, 4, 4,
4, 2, 4, 2, 2,
4, 4, 4, 4,
2, 4, 4,
4, 4, 4, 4,
4, 4, 4, 4,
4, 2, 4,
4, 4, 4, 4,
4, 4, 4, 4,
4, 4, 2
};
const int num_elements_in_arr = sizeof(Mario_Notes)/sizeof(Mario_Notes[0]);
const int sampleWindow = 50; // Sample window width in mS (50 mS = 20Hz)
// Define which pins are connected with a 1-10M resistor.
// The first pin will be connected to the touch sensor
// and *must* be D0, D1, D2, D3, D4 A0, A1, A3, A4, A5, A6, A7
// see: http://docs.spark.io/firmware/#interrupts-attachinterrupt
CapTouch Touch(A2, A4);
int presence = LOW;
// When was it last published
unsigned long lastPublishTime=0;
unsigned long combinedNoise = 0;
unsigned long numberOfReadings = 0;
void setup()
{
Serial.begin(9600);
pinMode( speakerPin, OUTPUT );
//get the servo to work
servo.attach( A5 );
// Particle.function("servo", servoControl);
// Particle.variable( "servoPos" , &servoPos , INT );
} //end setup
void loop()
{
noise_level = sampleNoise( );
Serial.print("sensorValue ");
Serial.println( noise_level );
delay( 50 );
//my play melody shit
unsigned long startMillis = millis();
if ( noise_level > STFU_threshold ){
while (millis() - startMillis < songDuration){
playNotes();
moveFigure();
}
// Particle.publish("thresh_exceeded");
delay( 60000 ); //this gives her a little respite
} //end if
} //END_LOOP
//sampleNoise---------------------
int sampleNoise( )
{
unsigned long startMillis = millis(); // Start of sample window
int highest_sample = 0;
int lowest_sample = 1000;
// collect data for 50 mS
while (millis() - startMillis < sampleWindow)
{
int sample = analogRead( mic_pin );
// invert the range, and convert it to a percent
sample = map( sample, 0, 4095, 1000, 0 );
// now see if the sample is the lowest;
if ( sample > highest_sample ){
highest_sample = sample ;
}
if ( sample < lowest_sample ){
lowest_sample = sample;
}
}
int peakToPeak = highest_sample - lowest_sample;
return peakToPeak;
} //END_SAMPLENOISE
void playNotes()
{
for (int thisNote = 0; thisNote < num_elements_in_arr; thisNote++) {
int noteDuration = 500/Mario_Notes[thisNote];
tone(speakerPin, Mario_melody[thisNote],noteDuration);
int pauseBetweenNotes = noteDuration * 1.30;
delay(pauseBetweenNotes);
noTone(speakerPin);
} //end for
}
void moveFigure()
{
for (int oscillation = 0; oscillation <= max_osc; oscillation++) {
// oscillate servo
for(angle = 0; angle < 50; angle++)
{
servo.write(angle);
delay(30);
}
delay(333);
for(angle = 15; angle > 0; angle--)
{
servo.write(angle);
delay(30);
}
}
}
void publishValues()
{
if(millis()-lastPublishTime>10000)
{
long avgNoise = combinedNoise/numberOfReadings;
String information = String(avgNoise) + "," + String(presence);
Particle.publish("diot2017/wrkshop/info", information );
lastPublishTime = millis();
combinedNoise = 0;
numberOfReadings = 0;
}
}
Click to Expand
A hands-on introductory course exploring the Internet of Things and connected product experiences.
Distract my roommate from noises in my bedroom
February 1st, 2017