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 VARIABLESint potenValue = 0; // VALUE OF POTENTIOMETER OUTPUT(USED FOR SONG SELECTION)int S = 0; // SONG SELECTIONServo myServo; // SERVOint posServo = 0; // SERVO STARTING POSITIONint playServo = 0; // SERVO STATEint B = 1; // TOGGLE BEATSint Current = 0; // CURRENT STATE OF LEFT BUTTONint Previous = 0; // PREVIOUS STATE OF LEFT BUTTON//==============================================================//void setup() {// INITIALIZE CIRCUIT PLAYGROUND AND DEBUGGINGCircuitPlayground.begin();Serial.begin(9600);delay(1000);// INPUTSpinMode(4, INPUT_PULLDOWN); // Button ApinMode(5, INPUT_PULLDOWN); // Button B// SET SPEAKER VOLUME (DEFAULT WAS A LITTLE LOUD)analogWrite (A0, 200);// SERVO SETUPmyServo.attach(A7); //SERVO PIN (A7)beat();}//==============================================================//void loop() {// DEBUGGING//Serial.print(potenValue); //POTENTIOMETER VALUE//Serial.println(S);// ATTACHES POTENTIOMETER TO INPUT A3potenValue = analogRead(A3);// MAPS THE VALUE INPUT RANGE OF THE POTENTIOMETER TO AN OUTPUT VALUE OF 1-5, DETERMINES SONG SELECTIONpotenValue = 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 1Song1();}if (digitalRead(5) == 1 && S == 2) {Song2();}if (digitalRead(5) == 1 && S == 3) {Song3();}if (digitalRead(5) == 1 && S == 4) {Song4();}// TOGGLE BEATSCurrent = digitalRead(4);if(Current == 1 && Previous == 0) //1 = true, 0 = false; shorthand{// IF PRESSED, TURN ON BEATSif(B == 0) {B = 1;} else {B = 0;}delay(100);}}// SONG 1 (Guren No Yumiya by Linked Horizon from Attack on Titan) by Mattvoid 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 Mattvoid 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() {}// BEATSvoid 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.