20 March 2022

NIME Team 5

 

NIME Project Team 5



Our NIME project is a music box where you can choose between pre-coded songs and we wanted the functionality to be understandable with consistent feedback. The circuit playground displays a light from neopixels 1-4 to show the selected song (if you want to know the names of the songs they are commented in the code). You are able to use the potentiometer to choose between all 4 songs. The potentiometer is mapped so that it's full range is divided into 4 increments and the range is read by the code, a value of 1 is song 1, 2 is song 2, etc... In order to play the chosen song, the user just needs to press the button on the right. The songs themselves are made with two integer ranges and a for loop which plays each note and the note's length incrementally. In order to simplify note input, our custom library "notes.h" was used, it allowed us to input frequencies for the speaker as regular notes instead. For the length of the notes, we divided 60 by the tempo of the song (BPM) and times it by 1000 so we can translate note timing to milliseconds. We referenced sheet music to create the songs in code. The drum and the beats are handled in their own void function. The left button toggles whether or not the beats play for the songs. 


The overall functionality and user experience was thought over a lot. We wanted it to be intuitive and simplistic to use. What could've been added or changed, if anything, to make it more user-friendly? 


/*
 * NIME Team 5
 * Matthew Powell
 * Jermaine Pinnock
 * ---------------------------------------
 * Instructions: 
 * Use potentiometer to select song
 * Left button to toggle percussion beats
 * Right button to play selected song
 * ----------------------------------------
 */


#include <Adafruit_CircuitPlayground.h>
#include <Adafruit_Circuit_Playground.h>
#include "notes.h" // CUSTOM LIBRARY - DOWNLOAD HERE: https://bit.ly/3L8WlLr
#include <Servo.h>

  // GLOBAL VARIABLES
  int potenValue = 0; // VALUE OF POTENTIOMETER OUTPUT(USED FOR SONG SELECTION)
  int S = 0;  // SONG SELECTION
  Servo myServo; // SERVO
  int posServo = 0; // SERVO STARTING POSITION
  int playServo = 0; // SERVO STATE
  int B = 1; // TOGGLE BEATS
  int Current = 0; // CURRENT STATE OF LEFT BUTTON
  int Previous = 0; // PREVIOUS STATE OF LEFT BUTTON
  
//==============================================================//


void setup() {
  // INITIALIZE CIRCUIT PLAYGROUND AND DEBUGGING
  CircuitPlayground.begin();
  Serial.begin(9600);
  delay(1000);

  // INPUTS
  pinMode(4, INPUT_PULLDOWN); // Button A
  pinMode(5, INPUT_PULLDOWN); // Button B

  // SET SPEAKER VOLUME (DEFAULT WAS A LITTLE LOUD)
  analogWrite (A0, 200);

  // SERVO SETUP
  myServo.attach(A7); //SERVO PIN (A7)
  beat();
}

//==============================================================//


void loop() {
  
  // DEBUGGING
  //Serial.print(potenValue); //POTENTIOMETER VALUE
  //Serial.println(S);
  
  // ATTACHES POTENTIOMETER TO INPUT A3
  potenValue = analogRead(A3);

  // MAPS THE VALUE INPUT RANGE OF THE POTENTIOMETER TO AN OUTPUT VALUE OF 1-5, DETERMINES SONG SELECTION
  potenValue = map(potenValue, 0, 1023, 1, 3);

  // IF THE POTENTIOMETER EQUALS 1, SET SONG SELECTION TO 1 & TURN NEOPIXELS ON/OFF, ETC...
  if (potenValue == 1) {
    S = 1;    
    CircuitPlayground.setPixelColor(0, 200, 200, 200);
    CircuitPlayground.setPixelColor(1, 0, 0, 0);
    CircuitPlayground.setPixelColor(2, 0, 0, 0);
    CircuitPlayground.setPixelColor(3, 0, 0, 0);
  }
  if (potenValue == 2) {
    S = 2;
    CircuitPlayground.setPixelColor(0, 0, 0, 0);
    CircuitPlayground.setPixelColor(1, 200, 200, 200);
    CircuitPlayground.setPixelColor(2, 0, 0, 0);
    CircuitPlayground.setPixelColor(3, 0, 0, 0);
  }

  // SONG SELECTION
  // IF RIGHT BUTTON IS PUSHED AND SONG SELECTION IS SET TO 1, PLAY SONG 1, ETC...
   if (digitalRead(5) == 1 && S == 1) {
    //PLAYS FUNCTION FOR SONG 1
    Song1();
    }
  if (digitalRead(5) == 1 && S == 2) {
    Song2();
    }
  if (digitalRead(5) == 1 && S == 3) {
    Song3();
    }
  if (digitalRead(5) == 1 && S == 4) {
    Song4();
    }
    // TOGGLE BEATS
      Current = digitalRead(4);
  if(Current == 1 && Previous == 0) //1 = true, 0 = false; shorthand
  {
    // IF PRESSED, TURN ON BEATS
    if(B == 0) {
    B = 1;
    } else {
     B = 0;
    }
    delay(100);
 }
}

// SONG 1 (Guren No Yumiya by Linked Horizon from Attack on Titan) by Matt
void Song1() {
beat();  
CircuitPlayground.playTone(Db5, 80);
CircuitPlayground.playTone(Db5, 80);
beat();
CircuitPlayground.playTone(E5, 80);
beat();
CircuitPlayground.playTone(Eb5, 160);
beat(); 
CircuitPlayground.playTone(B4, 80);
beat(); 
CircuitPlayground.playTone(B4, 80);
beat();
CircuitPlayground.playTone(Db5, 160);
beat(); 
CircuitPlayground.playTone(Db5, 80);
beat(); 
CircuitPlayground.playTone(E5, 80);
beat();
CircuitPlayground.playTone(Eb5, 160);
beat(); 
CircuitPlayground.playTone(B4, 240);
}

// SONG 2 (Memoria by Aoi Eir from Fate/Zero) by Matt
void Song2() {
CircuitPlayground.playTone(Eb5, 120);
CircuitPlayground.playTone(Eb5, 120);
beat();
CircuitPlayground.playTone(B5, 360);
CircuitPlayground.playTone(B5, 120);
CircuitPlayground.playTone(B5, 240);
CircuitPlayground.playTone(Bb5, 120);
CircuitPlayground.playTone(Ab5, 120);
beat();
CircuitPlayground.playTone(Gb5, 600);
CircuitPlayground.playTone(0, 120);
CircuitPlayground.playTone(Eb5, 120);
CircuitPlayground.playTone(E5, 120);
CircuitPlayground.playTone(Gb5, 120);
beat();
CircuitPlayground.playTone(E5, 360);
beat();
CircuitPlayground.playTone(Ab5, 240);
CircuitPlayground.playTone(Gb5, 120);
CircuitPlayground.playTone(E5, 120);
beat();
CircuitPlayground.playTone(Eb5, 600);
CircuitPlayground.playTone(Eb5, 120);
CircuitPlayground.playTone(Db5, 120);
beat();
CircuitPlayground.playTone(B4, 600);
beat();
CircuitPlayground.playTone(B4, 240);
beat();
CircuitPlayground.playTone(Ab5, 240);
beat();
CircuitPlayground.playTone(Gb5, 600);
CircuitPlayground.playTone(0, 120);
CircuitPlayground.playTone(Eb5, 120);
CircuitPlayground.playTone(E5, 120);
CircuitPlayground.playTone(Gb5, 120);
beat();
CircuitPlayground.playTone(E5, 360);
beat();
CircuitPlayground.playTone(Gb5, 240);
beat();
CircuitPlayground.playTone(Eb5, 240);
beat();
CircuitPlayground.playTone(Ab5, 720);
}

void Song3() {

}

void Song4() {

}

// BEATS
void beat() {
  if (B == 1) {
  if (playServo == 0) {
    posServo += 70;
    myServo.write(posServo);
  }
  if (playServo == 1) {
    posServo -= 70;
    myServo.write(posServo);
  }
  if (posServo == 70) playServo = 1;
  if (posServo == 0) playServo = 0;
 }
}












No comments:

Post a Comment

Note: Only a member of this blog may post a comment.