#include <stdio.h>
#include <SPI.h>
#include "pitches.h"
#include <Adafruit_SSD1306.h>
const uint8_t Butts[] = {13, 12, 11, 10, 9, 8, 7, 6}; //use ports 13-6 as inputs. Test only
#define SPEAKER_PIN 5 //speaker pin. Test only
const int notes[] = { //C1 = 1, C2 = 13, C3 = 25, C4 = 37
NOTE_B0,
NOTE_C1, NOTE_CS1, NOTE_D1, NOTE_DS1, NOTE_E1, NOTE_F1, NOTE_FS1, NOTE_G1, NOTE_GS1, NOTE_A1, NOTE_AS1, NOTE_B1,
NOTE_C2, NOTE_CS2, NOTE_D2, NOTE_DS2, NOTE_E2, NOTE_F2, NOTE_FS2, NOTE_G2, NOTE_GS2, NOTE_A2, NOTE_AS2, NOTE_B2,
NOTE_C3, NOTE_CS3, NOTE_D3, NOTE_DS3, NOTE_E3, NOTE_F3, NOTE_FS3, NOTE_G3, NOTE_GS3, NOTE_A3, NOTE_AS3, NOTE_B3,
NOTE_C4, NOTE_CS4, NOTE_D4, NOTE_DS4, NOTE_E4, NOTE_F4, NOTE_FS4, NOTE_G4, NOTE_GS4, NOTE_A4, NOTE_AS4, NOTE_B4,
NOTE_C5, NOTE_CS5, NOTE_D5, NOTE_DS5, NOTE_E5, NOTE_F5, NOTE_FS5, NOTE_G5, NOTE_GS5, NOTE_A5, NOTE_AS5, NOTE_B5,
NOTE_C6, NOTE_CS6, NOTE_D6, NOTE_DS6, NOTE_E6, NOTE_F6, NOTE_FS6, NOTE_G6, NOTE_GS6, NOTE_A6, NOTE_AS6, NOTE_B6,
NOTE_C7, NOTE_CS7, NOTE_D7, NOTE_DS7, NOTE_E7, NOTE_F7, NOTE_FS7, NOTE_G7, NOTE_GS7, NOTE_A7, NOTE_AS7, NOTE_B7,
NOTE_C8, NOTE_CS8, NOTE_D8, NOTE_DS8
};
#define LED 8 //# of LEDs
#define RGB 3 //# of color pins per LED
// how to read arrayLED: [LED#][RedValue, GreenValue, BlueValue, NoteValue]
int arrayLED[LED][RGB + 1] = { //use ports 53 - 30
{53, 52, 51, 0},
{50, 49, 48, 0},
{47, 46, 45, 0},
{44, 43, 42, 0},
{41, 40, 39, 0},
{38, 37, 36, 0},
{35, 34, 33, 0},
{32, 31, 30, 0}
};
char arrayStringNotes[LED][3] = {
{'c','#','1'},
{'c','#','1'},
{'c','#','1'},
{'c','#','1'},
{'c','#','1'},
{'c','#','1'},
{'c','#','1'},
{'c','#','1'},
};
Adafruit_SSD1306 display = Adafruit_SSD1306(128, 64, &Wire);
#define menuSize 4
char menu[menuSize][10] = { "DEMO", "LESSON", "FREESTYLE", "SETTINGS" };
int cursor = 1;
const uint8_t dirButts[] = {4, 3, 2}; //4 = select, 3 = up, = 2 = down
int gamemode = 0;
void setup() {
for (uint8_t i = 0; i < LED; i++) {
for (uint8_t j = 0; j < RGB; j++) {
pinMode(arrayLED[i][j], OUTPUT);
}
pinMode(Butts[i], INPUT_PULLUP);
}
pinMode(SPEAKER_PIN, OUTPUT);
for (uint8_t i = 0; i < 3; i++) {
pinMode(dirButts[i], INPUT_PULLUP);
}
Serial.begin(115200);
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
display.setTextColor(SSD1306_WHITE);
showMenu();
setScale(37, true); //C4Maj Scale by default
}
void loop() {
int pitch = 0;
for (uint8_t i = 0; i < LED; i++) { //LED color picker
if (digitalRead(Butts[i]) == LOW) {
for (uint8_t j = 0; j < RGB; j++) {
digitalWrite(arrayLED[i][j], LOW);
}
pitch = arrayLED[i][3];
}
else {
setColor();
}
}
for (uint8_t i = 0; i < 3; i++) { //direction button
if (digitalRead(dirButts[i]) == LOW){
if (gamemode == 0){
if (i == 0) { //select
executeChoice(cursor-1);
}
else {
setCursorN(0,cursor);
display.setTextColor(SSD1306_BLACK);
display.print('>');
display.display();
display.setTextColor(SSD1306_WHITE);
if (i == 1) { //down
cursor++;
if (cursor>(menuSize)) cursor=1;
}
else { //up
cursor--;
if (cursor<1) cursor=(menuSize);
}
setCursorN(0,cursor);
display.print('>');
display.display();
}
delay(200);
}
else if (gamemode) {
if (i == 0) { //select
showMenu();
gamemode = 0;
delay(200);
}
}
}
}
if (pitch) {
tone(SPEAKER_PIN, pitch);
}
else {
noTone(SPEAKER_PIN);
}
}
void showMenu() {
setCursorN(0,0);
display.clearDisplay();
// show menu items:
display.println("LasIR Harp");
for (uint8_t i = 0; i<menuSize; i++) {
display.print(" ");
display.println(menu[i]);
}
setCursorN(0,1);
display.print('>');
display.display();
}
void setCursorN(int x, int y) {
display.setCursor(x*6,y*8);
//cursor = y*8;
}
void executeChoice(int choice) {
display.clearDisplay();
display.display();
setCursorN(0,0);
display.print(menu[cursor-1]);
display.display();
switch(choice){
case 0: //Demo
gamemode = 1;
/*for (uint8_t i = 0; i < LED; i++) {
playString(i, 500);
}
setCursorN(0,1);
display.print("> End");
display.display();*/
replay();
break;
case 1: //Lesson
break;
case 2: //Freeplay
gamemode = 3;
setCursorN(0,1);
display.print("> End");
display.display();
break;
case 3: //Settings
break;
default :
display.println("error");
}
}
void playString(int i, int time) {
//setColor(0);
for (uint8_t j = 0; j < RGB; j++) {
digitalWrite(arrayLED[i][j], LOW);
}
tone(SPEAKER_PIN, arrayLED[i][3]);
setCursorN(2,2);
display.print(arrayStringNotes[i][0]);
display.print(arrayStringNotes[i][1]);
display.print(arrayStringNotes[i][2]);
display.display();
delay(time);
setColor();
noTone(SPEAKER_PIN);
setCursorN(2,2);
display.setTextColor(SSD1306_BLACK);
display.print(arrayStringNotes[i][0]);
display.print(arrayStringNotes[i][1]);
display.print(arrayStringNotes[i][2]);
display.setTextColor(SSD1306_WHITE);
display.display();
//setColor(ledNotes[i]);
}
void setColor(){
for (uint8_t i = 0; i < LED; i++) {
if ((arrayLED[i][3] == NOTE_C4) || (arrayLED[i][3] == NOTE_C5)) {
digitalWrite(arrayLED[i][0], HIGH); //red
digitalWrite(arrayLED[i][1], LOW);
digitalWrite(arrayLED[i][2], LOW);
}
else if (arrayLED[i][3] == NOTE_F4) {
digitalWrite(arrayLED[i][0], LOW);
digitalWrite(arrayLED[i][1], LOW);
digitalWrite(arrayLED[i][2], HIGH); //blue
}
else {
for (uint8_t j = 0; j < RGB; j++) {
digitalWrite(arrayLED[i][j], HIGH);
}
}
}
}
void setScale(int note, bool major){
if (major){
arrayLED[0][3] = notes[note];
arrayLED[1][3] = notes[note+2];
arrayLED[2][3] = notes[note+4];
arrayLED[3][3] = notes[note+5];
arrayLED[4][3] = notes[note+7];
arrayLED[5][3] = notes[note+9];
arrayLED[6][3] = notes[note+11];
arrayLED[7][3] = notes[note+12];
}
else {
arrayLED[0][3] = notes[note];
arrayLED[1][3] = notes[note+2];
arrayLED[2][3] = notes[note+3];
arrayLED[3][3] = notes[note+5];
arrayLED[4][3] = notes[note+7];
arrayLED[5][3] = notes[note+8];
arrayLED[6][3] = notes[note+10];
arrayLED[7][3] = notes[note+12];
}
for (uint8_t i = 0; i < LED; i++) {
switch (arrayLED[i][3]){
case NOTE_C4:
arrayStringNotes[i][0] = 'C';
arrayStringNotes[i][1] = ' ';
arrayStringNotes[i][2] = '4';
break;
case NOTE_D4:
arrayStringNotes[i][0] = 'D';
arrayStringNotes[i][1] = ' ';
arrayStringNotes[i][2] = '4';
break;
case NOTE_E4:
arrayStringNotes[i][0] = 'E';
arrayStringNotes[i][1] = ' ';
arrayStringNotes[i][2] = '4';
break;
case NOTE_F4:
arrayStringNotes[i][0] = 'F';
arrayStringNotes[i][1] = ' ';
arrayStringNotes[i][2] = '4';
break;
case NOTE_G4:
arrayStringNotes[i][0] = 'G';
arrayStringNotes[i][1] = ' ';
arrayStringNotes[i][2] = '4';
break;
case NOTE_A4:
arrayStringNotes[i][0] = 'A';
arrayStringNotes[i][1] = ' ';
arrayStringNotes[i][2] = '4';
break;
case NOTE_B4:
arrayStringNotes[i][0] = 'B';
arrayStringNotes[i][1] = ' ';
arrayStringNotes[i][2] = '4';
break;
case NOTE_C5:
arrayStringNotes[i][0] = 'C';
arrayStringNotes[i][1] = ' ';
arrayStringNotes[i][2] = '5';
break;
default:
break;
}
}
}
void replay(){
playString(7, 300); //shaw
playString(5, 300); //tys
playString(4, 100); //like
playString(3, 100); //a
playString(4, 100); //mel
playString(5, 100); //o
playString(4, 300); //dy
playString(3, 300);//in
playString(7, 300);//my
playString(5, 300);//head
playString(4, 100);//that
playString(3, 100);//I
playString(4, 100);//cant
noTone(SPEAKER_PIN);
delay(200);
playString(4, 300);//keep
playString(5, 300);//out
playString(4, 100);//got
playString(5, 100);//me
playString(4, 100);//sing
playString(3, 100);//ing
playString(1, 600);//like
playString(3, 100);//na
playString(1, 100);//na
playString(3, 300);//na
noTone(SPEAKER_PIN);
delay(20);
playString(3, 300);//na
noTone(SPEAKER_PIN);
delay(20);
playString(3, 100);//ev
playString(4, 100);//er
playString(5, 100);//y
noTone(SPEAKER_PIN);
delay(20);
playString(5, 400);//day
playString(3, 100);//like
playString(1, 100);//my
playString(3, 300);//i
noTone(SPEAKER_PIN);
delay(20);
playString(3, 300);//pods
noTone(SPEAKER_PIN);
delay(20);
playString(3, 100);//stuck
playString(4, 100);//on
playString(5, 100);//re
noTone(SPEAKER_PIN);
delay(40);
playString(5, 300);//play
noTone(SPEAKER_PIN);
delay(40);
playString(5, 100);//re
noTone(SPEAKER_PIN);
delay(40);
playString(5, 300);//play
noTone(SPEAKER_PIN);
delay(15);
playString(5, 100);//ay
noTone(SPEAKER_PIN);
delay(15);
playString(5, 100);//ay
noTone(SPEAKER_PIN);
delay(15);
playString(5, 100);//ay
}