Skip to content

Instantly share code, notes, and snippets.

@ramboldio
Created August 9, 2016 22:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ramboldio/12496834a78be2fefdb0e2751ecd3943 to your computer and use it in GitHub Desktop.
Save ramboldio/12496834a78be2fefdb0e2751ecd3943 to your computer and use it in GitHub Desktop.
MysteryBox Arduino Sketch - Sketching with Hardware 2016 @ LMU
// libs import
#include <Adafruit_NeoPixel.h>
#include <Servo.h>
#define DEBOUNCE_COUNT 5
#define DURATION 650
#define PAUSE 150
#define SPEAKER_PIN 6
#define STATUS_LED_PIN 5
#define CEILING_LED_PIN 4
#define BOTTOM_LED_PIN 8
#define SERVO_PIN 9
#define TRIGGER_PIN 2 // Arduino pin tied to trigger pin on the ultrasonic sensor.
#define ECHO_PIN 3 // Arduino pin tied to echo pin on the ultrasonic sensor.
#define MAX_DISTANCE 200 // Maximum distance we want to ping for (in centimeters). Maximum sensor distance is rated at 400-500cm.
Adafruit_NeoPixel status_leds = Adafruit_NeoPixel(4, STATUS_LED_PIN);
Adafruit_NeoPixel ceiling_led = Adafruit_NeoPixel(1, CEILING_LED_PIN);
Adafruit_NeoPixel bottom_leds = Adafruit_NeoPixel(3, BOTTOM_LED_PIN);
Servo door_opener;
String melody[]{"G", "Bb", "A", "D"};
const int melody_len = 4;
double melodyFreq[melody_len]{392.00, 466.16, 392.00, 293.66}; // rendered at setup()
int duration[]{8,8,8,8};
// String notes[]{"C", "C#/Db", "D ", "D#/Eb ", "E ", "F ", "F#/Gb ", "G ", "G#/Ab ", "A ", "A#/Bb ", "B "};
// String notes[]{"C", "C#/Db", "D ", "D#/Eb ", "E ", "F ", "F#/Gb ", "G ", "G#/Ab ", "A ", "Bb ", "B "};
// double noteFreq[]{261.63, 277.18, 293.66, 311.13, 329.63, 349.23, 369.99, 392.00, 415.30, 440.00, 466.16, 493.88};
String notes[]{"D ", "G ", "A ", "Bb "};
double noteFreq[]{293.66, 392.00, 440.00, 466.16};
int note_len = 4;
int currentNoteId = 0;
int newNoteId = 0;
int currentFailRate = 0;
int last_val;
int correctTones = 0;
boolean victory = false;
void setup() {
// init Distance Sensor
pinMode(A0, INPUT);
// init LEDs
status_leds.begin();
status_leds.setBrightness(100);
status_leds.show();
bottom_leds.begin();
bottom_leds.setBrightness(60);
bottom_leds.show();
setAllLedsTo(bottom_leds, 0, 150, 60);
ceiling_led.begin();
ceiling_led.setBrightness(100);
ceiling_led.show();
resetServo();
// init ultra sonic sensor
pinMode(TRIGGER_PIN, OUTPUT);
pinMode(ECHO_PIN, INPUT);
Serial.begin(9600);
// renderSong();
playSound();
}
long last_event = 0;
void loop() {
status_leds.setPixelColor(1, 255, 255, 255);
status_leds.show();
digitalWrite(TRIGGER_PIN, LOW);
delay(5);
digitalWrite(TRIGGER_PIN, HIGH);
delay(10);
digitalWrite(TRIGGER_PIN, LOW);
long dauer = pulseIn(ECHO_PIN, HIGH);
int a = (dauer/2) / 29.1;
Serial.println(a);
// int a = analogRead(A0);
// if (a > 150 && a < 500){
if(a == 1){
fake();
}
if (a > 0 && a < 20){
// readSensorVal_sharpp(a);
readSensorVal_sonic(a);
if (millis() - last_event > 800 && currentNoteId <= note_len -1){
saveTone(noteFreq[currentNoteId]);
last_event = millis();
tone(SPEAKER_PIN, noteFreq[currentNoteId], 650);
}
} else {
noTone(SPEAKER_PIN);
}
//Serial.println(noteFreq[currentNoteId]);
// Serial.println(a);
// delay(100);
}
void fake(){
playSound();
celebrate();
}
void saveTone(double freq){
double nextCorrectNote = melodyFreq[correctTones];
if(abs(freq - nextCorrectNote) < 0.1){
correctTones++;
Serial.println("SAVED!");
Serial.print(freq);
Serial.print(" | ");
Serial.println(nextCorrectNote);
Serial.println(correctTones);
} else {
correctTones = 0;
}
victory = (correctTones == melody_len);
updateStatus();
}
void updateStatus(){
for (int i = 0; i < correctTones; i++){
Serial.println("switch LED on");
Serial.println(i);
status_leds.setPixelColor(i, 120, 8, 42);
delay(100);
Serial.println("Color set");
status_leds.show();
delay(100);
Serial.println("show()");
}
}
void celebrate(){
for(int i = 0; i < 3; i++){
setAllLedsTo(status_leds, 255, 0, 255);
delay(500);
resetLeds(status_leds);
}
ceiling_led.setPixelColor(0, 255, 255, 255);
ceiling_led.show();
openDoor();
whiteOverRainbow(100, 0, 0);
}
void resetEverything(){
// TODO
// reset status (saved tones)
resetLeds(status_leds);
}
void resetServo(){
door_opener.attach(SERVO_PIN);
delay(15);
door_opener.write(155);
delay(150);
door_opener.detach();
}
void openDoor(){
door_opener.attach(SERVO_PIN);
delay(15);
door_opener.write(100);
delay(500);
door_opener.write(155);
delay(150);
door_opener.detach();
}
double roundToNote(int freq){
for(int i = 0; i < note_len; i++){
if (noteFreq[i] > freq){
return noteFreq[i];
}
}
return 0.0;
}
void renderSong(){
Serial.print("Song: ");
for(int i = 0; i < melody_len; i++){
melodyFreq[i] = getFreq(melody[i]);
Serial.print(melodyFreq[i]);
Serial.print(" (");
Serial.print(melody[i]);
Serial.print("), ");
}
Serial.println();
}
void readSensorVal_sharpp(double val){
int incomingNoteId = - (((val-150)/(300/note_len)) - note_len);
readSensorNote(incomingNoteId);
}
void readSensorVal_sonic(int distance){
int incomingNoteId = map(distance, 0, 20, 0, note_len +1);
readSensorNote(incomingNoteId);
}
void readSensorNote(int incomingNoteId){
if(incomingNoteId == currentNoteId){
if (currentFailRate > 0){
currentFailRate--;
}
return;
}
if (incomingNoteId == newNoteId){
currentFailRate++;
if (currentFailRate > DEBOUNCE_COUNT){
currentNoteId = newNoteId;
}
} else {
if (currentFailRate > 0){
currentFailRate--;
} else {
newNoteId = incomingNoteId;
}
}
}
double getFreq(String note){
Serial.print("getFreq(");
Serial.print(note);
Serial.print(") ");
for(int i = 0; i < note_len; i++){
Serial.print(notes[i]);
String compNote = notes[i];
if (note == compNote) {
Serial.println("got note");
return noteFreq[i];
}
}
return 0;
}
int playSound() {
for (int i = 0; i < melody_len; i++) {
Serial.println(melodyFreq[i]);
tone(SPEAKER_PIN, melodyFreq[i], 650);
status_leds.setPixelColor(i, 255, 0, 255);
status_leds.show();
delay(800);
noTone(SPEAKER_PIN);
}
resetLeds(status_leds);
}
void resetLeds(Adafruit_NeoPixel leds){
setAllLedsTo(leds, 0,0,0);
}
void setAllLedsTo(Adafruit_NeoPixel leds, int r, int g, int b){
for(int i = 0; i < leds.numPixels(); i++){
leds.setPixelColor(i,r,g,b);
}
leds.show();
}
void whiteOverRainbow(uint8_t wait, uint8_t whiteSpeed, uint8_t whiteLength ) {
if(whiteLength >= bottom_leds.numPixels()) whiteLength = bottom_leds.numPixels() - 1;
int head = whiteLength - 1;
int tail = 0;
int loops = 3;
int loopNum = 0;
static unsigned long lastTime = 0;
while(true){
for(int j=0; j<256; j++) {
for(uint16_t i=0; i<bottom_leds.numPixels(); i++) {
if((i >= tail && i <= head) || (tail > head && i >= tail) || (tail > head && i <= head) ){
bottom_leds.setPixelColor(i, bottom_leds.Color(0,0,0, 255 ) );
}
}
if(millis() - lastTime > whiteSpeed) {
head++;
tail++;
if(head == bottom_leds.numPixels()){
loopNum++;
}
lastTime = millis();
}
if(loopNum == loops) return;
head%=bottom_leds.numPixels();
tail%=bottom_leds.numPixels();
bottom_leds.show();
delay(wait);
}
}
}
double min;
double max;
boolean undefined = false;
void printRange(double val){
if (undefined){
min = val;
max = val;
}
if (val > max){
max = val;
}
if(val < min){
min = val;
}
Serial.print("Value from ");
Serial.print(min);
Serial.print(" until ");
Serial.println(max);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment