#include "SPI.h"
#include "Adafruit_GFX.h"
#include "Adafruit_ILI9341.h"
#define TFT_CLK 13
#define TFT_MISO 12
#define TFT_MOSI 11
#define TFT_DC 10
#define TFT_CS 8
#define TFT_RST 9
//建立LCD class
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_MOSI, TFT_CLK, TFT_RST, TFT_MISO);
#define BUZZER_PIN 4
#define BUTTON1_PIN 2
#define BUTTON2_PIN 3
#define N_B0 31
#define N_C1 33
#define N_CS1 35
#define N_D1 37
#define N_DS1 39
#define N_E1 41
#define N_F1 44
#define N_FS1 46
#define N_G1 49
#define N_GS1 52
#define N_A1 55
#define N_AS1 58
#define N_B1 62
#define N_C2 65
#define N_CS2 69
#define N_D2 73
#define N_DS2 78
#define N_E2 82
#define N_F2 87
#define N_FS2 93
#define N_G2 98
#define N_GS2 104
#define N_A2 110
#define N_AS2 117
#define N_B2 123
#define N_C3 131
#define N_CS3 139
#define N_D3 147
#define N_DS3 156
#define N_E3 165
#define N_F3 175
#define N_FS3 185
#define N_G3 196
#define N_GS3 208
#define N_A3 220
#define N_AS3 233
#define N_B3 247
#define N_C4 262
#define N_CS4 277
#define N_D4 294
#define N_DS4 311
#define N_E4 330
#define N_F4 349
#define N_FS4 370
#define N_G4 392
#define N_GS4 415
#define N_A4 440
#define N_AS4 466
#define N_B4 494
#define N_C5 523
#define N_CS5 554
#define N_D5 587
#define N_DS5 622
#define N_E5 659
#define N_F5 698
#define N_FS5 740
#define N_G5 784
#define N_GS5 831
#define N_A5 880
#define N_AS5 932
#define N_B5 988
#define N_C6 1047
#define N_CS6 1109
#define N_D6 1175
#define N_DS6 1245
#define N_E6 1319
#define N_F6 1397
#define N_FS6 1480
#define N_G6 1568
#define N_GS6 1661
#define N_A6 1760
#define N_AS6 1865
#define N_B6 1976
#define N_C7 2093
#define N_CS7 2217
#define N_D7 2349
#define N_DS7 2489
#define N_E7 2637
#define N_F7 2794
#define N_FS7 2960
#define N_G7 3136
#define N_GS7 3322
#define N_A7 3520
#define N_AS7 3729
#define N_B7 3951
#define N_C8 4186
#define N_CS8 4435
#define N_D8 4699
#define N_DS8 4978
#define REST 0
#define PER_BEAT 134
unsigned int notes[] =
{
REST, REST, REST, REST,
N_DS4, N_CS4, N_DS4, N_GS4, N_FS4, N_DS4, N_CS4, N_B3,
N_CS4, N_DS4, N_CS4, N_B3, N_CS4, N_DS4, N_CS4, N_B3,
N_DS4, N_CS4, N_DS4, N_GS4, N_FS4, N_B3, N_B3, N_B3,
N_CS4, N_DS4, N_CS4, N_B3, N_AS3, N_B3, REST,
N_B4, N_B4, N_CS5, N_B4, N_B4, N_CS5,
N_DS5, N_CS5, N_B4, N_CS5, N_B4,
N_DS4, N_CS4, N_DS4, N_GS4, N_FS4, N_B3, N_B3,
N_CS4, N_DS4, N_CS4, N_B3, N_AS3, N_B3, N_CS5, N_B4,
N_CS4, N_DS4, N_FS4, N_B4, N_AS4, N_FS4, N_CS4, N_DS4, N_B3,
N_FS4, N_B3, N_DS4, N_FS4, N_CS4, N_DS4, N_CS4, N_B3, N_FS3,
N_CS4, N_DS4, N_FS4, N_B4, N_AS4, N_FS4, N_CS4, N_DS4, N_B3,
N_B3, N_CS4, N_DS4, N_FS4, N_B4, N_CS5, N_B4, N_FS4, N_DS5, N_E5, N_DS5, N_B4,
N_DS4, N_DS4, N_GS4, N_FS4, N_B3, N_B3, N_B3,
N_CS4, N_DS4, N_CS4, N_B3, N_CS4, N_DS4, REST,
N_DS4, N_DS4, N_GS4, N_FS4, N_B3, N_B3, N_B3,
N_CS4, N_DS4, N_CS4, N_B3, N_AS3, N_B3, REST,
N_B4, N_B4, N_CS5, N_B4, N_B4, N_CS5,
N_DS5, N_CS5, N_B4, N_CS5, N_B4,
N_DS4, N_CS4, N_DS4, N_GS4, N_FS4, N_B3,
N_CS5, N_DS5, N_CS5, N_B4, N_AS4, N_B4, N_DS5, N_CS5,
N_B4, N_DS5, N_CS5, N_B4, N_DS5, N_CS5,
N_B4, N_FS4, N_AS4, N_B4, N_DS5, N_CS5,
N_B4, N_DS4, N_CS5, N_B4, N_FS5, N_GS5,
N_FS5, N_B4, N_B4, N_CS5, N_DS5, N_DS5, N_CS5,
N_B4, N_DS5, N_CS5, N_B4, N_DS5, N_CS5,
N_B4, N_B4, N_FS4, N_AS4, N_B4, N_DS5, N_CS5,
N_B4, N_DS5, N_CS5, N_B4, N_FS5, N_GS5,
N_FS5, N_B4, N_B4, N_CS5, N_B4, REST,
REST, REST, REST, REST,
};
unsigned int beats[] =
{
4, 4, 4, 4,
3, 1, 2, 2, 4, 1, 1, 2,
2, 1, 1, 2, 2, 4, 2, 2,
3, 1, 2, 2, 2, 2, 2, 2,
2, 1, 1, 2, 2, 4, 4,
4, 4, 2, 2, 2, 2,
2, 2, 2, 2, 8,
3, 1, 2, 2, 4, 2, 2,
2, 1, 1, 2, 2, 4, 2, 2,
1, 1, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 1, 1, 1, 1, 4,
1, 1, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1,
4, 3, 1, 2, 2, 2, 2,
2, 1, 1, 2, 2, 4, 4,
4, 3, 1, 2, 2, 2, 2,
2, 1, 1, 2, 2, 4, 4,
4, 4, 2, 2, 2, 2,
2, 2, 2, 2, 8,
3, 1, 2, 2, 4, 4,
2, 1, 1, 2, 2, 4, 2, 2,
4, 2, 2, 4, 2, 2,
4, 2, 2, 4, 2, 2,
4, 2, 2, 4, 2, 2,
2, 2, 2, 2, 4, 2, 2,
4, 2, 2, 4, 2, 2,
2, 2, 2, 2, 4, 2, 2,
4, 2, 2, 4, 2, 2,
2, 2, 2, 2, 4, 4,
4, 4, 4, 4,
};
volatile bool reRender = false;
volatile unsigned int btnState = 0;
volatile unsigned int point = 0;
const unsigned int notesCount = sizeof(notes)/sizeof(int);
unsigned int drums[] =
{
0, 0, 0, 0,
1, 2, 1, 2, 1, 1, 2, 1,
1, 1, 2, 1, 2, 1, 2, 2,
1, 2, 1, 2, 1, 2, 2, 2,
1, 2, 1, 1, 1, 2, 0,
1, 1, 1, 2, 2, 1,
1, 2, 1, 2, 2,
1, 2, 1, 2, 1, 2, 2,
2, 1, 1, 2, 1, 2, 1, 2,
1, 2, 1, 1, 2, 1, 2, 1, 2,
1, 2, 1, 2, 1, 2, 1, 2, 1,
1, 2, 1, 1, 2, 1, 2, 1, 2,
1, 2, 2, 2, 1, 2, 1, 2, 1, 2, 1, 2,
1, 1, 2, 1, 2, 2, 2,
1, 1, 2, 1, 2, 1, 0,
1, 1, 2, 1, 2, 2, 2,
1, 1, 2, 1, 2, 1, 0,
1, 1, 1, 2, 2, 1,
1, 2, 1, 2, 2,
1, 2, 1, 2, 2, 1,
2, 1, 2, 1, 2, 2, 1, 1,
2, 1, 1, 2, 1, 1,
2, 1, 2, 1, 1, 1,
2, 1, 1, 2, 1, 2,
1, 2, 2, 1, 2, 1, 1,
2, 1, 1, 2, 1, 2,
1, 2, 2, 1, 2, 1, 1,
2, 1, 1, 2, 1, 2,
1, 2, 2, 1, 2, 0,
0, 0, 0, 0,
};
unsigned int idx = 0;
void btn1Clicked() {
if(btnState == 0) {
btnState = 1;
if(btnState == drums[idx])
++point;
}
}
void btn2Clicked() {
if(btnState == 0) {
btnState = 2;
if(btnState == drums[idx])
++point;
}
}
ISR(TIMER1_COMPA_vect) {
TCNT1 = 0;
if(idx < notesCount) {
OCR1A = (unsigned int)(2093.75 * beats[idx]);
tone(BUZZER_PIN, notes[idx], PER_BEAT * beats[idx] - 14);
++idx;
reRender = true;
}
else {
idx = 0;
point = 0;
tft.setCursor(0, 0);
tft.println(" ");
}
}
void setup() {
// put your setup code here, to run once:
pinMode(BUTTON1_PIN, INPUT_PULLUP);
pinMode(BUZZER_PIN, OUTPUT);
attachInterrupt(digitalPinToInterrupt(BUTTON1_PIN), btn1Clicked, FALLING);
attachInterrupt(digitalPinToInterrupt(BUTTON2_PIN), btn2Clicked, FALLING);
cli();
TCCR1A = 0;
TCCR1B = 0;
TCCR1B |= B00000101;
TIMSK1 |= B00000010;
tft.begin();
tft.fillScreen(ILI9341_BLACK);
tft.setTextSize(2);
tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK);
tft.setRotation(3);
sei();
}
void loop() {
// put your main code here, to run repeatedly:
if(reRender) {
reRender = false;
btnState = 0;
tft.setCursor(0, 0);
tft.print("Point: ");
tft.println(point);
tft.drawCircle(20, 120, 15, ILI9341_WHITE);
for(int i=idx-1;i<idx+7 || i<notesCount;++i) {
if(drums[i] == 0U)
tft.fillCircle(20+(i-idx+1)*40, 120, 10, ILI9341_BLACK);
else if(drums[i] == 1U)
tft.fillCircle(20+(i-idx+1)*40, 120, 10, ILI9341_RED);
else if(drums[i] == 2U)
tft.fillCircle(20+(i-idx+1)*40, 120, 10, ILI9341_BLUE);
}
}
}