Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f34e785131 | |||
| 6f9ab1d3bb | |||
| bd49e8758a | |||
| 619eaa12d9 | |||
| 75cdda61df | |||
| 9c6faddf30 |
+117
-13
@@ -9,21 +9,125 @@
|
|||||||
|
|
||||||
void setup()
|
void setup()
|
||||||
{
|
{
|
||||||
// initialize serial comms
|
// Communication with the computer is not needed in this project.
|
||||||
Serial.begin(9600);
|
//Serial.begin(9600);
|
||||||
|
// Set digital pins as inputs ready to read incoming data from buttons.
|
||||||
|
for(int i = 5; i < 13; ++i) {
|
||||||
|
pinMode(i, INPUT);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Class to handle output of a melody on a note by note basis and in full.
|
||||||
|
class TunePlayer {
|
||||||
|
private:
|
||||||
|
// Arrays of values relating to the pitch, order and duration (in quavers) of the melody.
|
||||||
|
const int tetrisNotes[8] = {1760, 1975, 2093, 2349, 2637, 2793, 3135, 3520};
|
||||||
|
const int tetrisOrder[38] = {4, 1, 2, 3, 2, 1, 0, 0, 2, 4, 3, 2, 1, 1, 2, 3, 4, 2, 0, 0, 3, 5, 7, 6, 5, 4, 2, 4, 3, 2, 1, 1, 2, 3, 4, 2, 0, 0};
|
||||||
|
const int tetrisDurations[38] = {2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 2, 2, 2, 4, 3, 1, 2, 1, 1, 3, 1, 2, 1, 1, 2, 1, 1, 2, 2, 2, 2, 3};
|
||||||
|
// Integer to store the current position in the melody.
|
||||||
|
int tunePosition = 0;
|
||||||
|
// Boolean value to store the state of the individual note-playing button.
|
||||||
|
bool buttonPressed = false;
|
||||||
|
|
||||||
|
public:
|
||||||
|
void playTune() {
|
||||||
|
// This was created out of misreading the bonus step... Enjoy!
|
||||||
|
// Declare static arrays holding frequency, note duration and note order data for a tune.
|
||||||
|
// Iterate over arrays, playing notes with durations specified as multiples of quavers at 144bpm
|
||||||
|
for(int i = 0; i < 38; ++i)
|
||||||
|
{
|
||||||
|
tone(13,tetrisNotes[tetrisOrder[i]],tetrisDurations[i]*206);
|
||||||
|
delay(tetrisDurations[i]*206);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void playTuneNote() {
|
||||||
|
// Begin playing a note from the melody if one is not already playing.
|
||||||
|
if(!buttonPressed) {
|
||||||
|
tone(13,tetrisNotes[tetrisOrder[tunePosition]]);
|
||||||
|
// Increment the position ready for the next note to be played
|
||||||
|
incrementPosition();
|
||||||
|
// Set the button state as true so that further calls to the
|
||||||
|
// function from the current press do nothing until it is
|
||||||
|
// released.
|
||||||
|
buttonPressed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void buttonInactive() {
|
||||||
|
// Public method for declaring the button as released.
|
||||||
|
buttonPressed = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int incrementPosition() {
|
||||||
|
// Mthod for incrementing the tune position without exceeding the
|
||||||
|
// number of positions available.
|
||||||
|
++tunePosition;
|
||||||
|
if(tunePosition > 37) {
|
||||||
|
tunePosition = 0;
|
||||||
|
}
|
||||||
|
return tunePosition;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Define integer frequencies in hertz from A (440hz) chromatically.
|
||||||
|
int notes[8] = {440, 466, 493, 523, 554, 587, 622, 659};
|
||||||
|
// Define a a global variable for pitch.
|
||||||
|
int pitch;
|
||||||
|
|
||||||
|
|
||||||
|
// Create a global player object instance.
|
||||||
|
TunePlayer player = TunePlayer();
|
||||||
|
|
||||||
void loop()
|
void loop()
|
||||||
{
|
{
|
||||||
// read A0
|
// Declare a bool for testing if button is active.
|
||||||
int val1 = analogRead(0);
|
bool active = false;
|
||||||
// read A1
|
|
||||||
int val2 = analogRead(1);
|
// For each button index, check if button is currently pressed...
|
||||||
// print to serial
|
int j = 0;
|
||||||
Serial.print(val1);
|
for(int i = 5; i < 13; ++i) {
|
||||||
Serial.print(" ");
|
active = digitalRead(i);
|
||||||
Serial.print(val2);
|
// If it is, set the output pitch to the frequency stored in the notes
|
||||||
Serial.print("\n");
|
// variable at the index of the button pressed
|
||||||
// wait
|
if(active) {
|
||||||
delay(50);
|
pitch = notes[j];
|
||||||
|
// break out of for loop as further iterations are not neccesary.
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// If note isn't active then increment index counter.
|
||||||
|
++j;
|
||||||
|
}
|
||||||
|
// Switch allows for easy overwriting of buton's default functionality.
|
||||||
|
switch(j) {
|
||||||
|
case 7:
|
||||||
|
// Special case to play tune with button 7.
|
||||||
|
player.playTune();
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
// Special case to play tune on a per note basis with button 6.
|
||||||
|
player.playTuneNote();
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
// If no note is active then silence instrument.
|
||||||
|
noTone(13);
|
||||||
|
// Set tune button as inactive ready for next note.
|
||||||
|
player.buttonInactive();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// default action to output a tone for a button
|
||||||
|
// Get integer value from FSR in range 0-1023
|
||||||
|
int sensorVal = analogRead(0);
|
||||||
|
|
||||||
|
// Calculate the offset 5% of the bend.
|
||||||
|
int bend = round(pitch / 100.0 * 5.0);
|
||||||
|
|
||||||
|
// Map values from the FSR to the pitch -5% to the pitch +5%
|
||||||
|
pitch = map(sensorVal, 0, 1023, pitch-bend, pitch+bend);
|
||||||
|
|
||||||
|
// Generate tone based on pitch +/- bend.
|
||||||
|
tone(13,pitch);
|
||||||
|
player.buttonInactive();
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user