#include "pitches.h"
#define REST 0
#define SPEAKER_PIN 8
// 按钮引脚
const uint8_t buttonPins[] = { 12, 11, 10, 9, 7, 6, 5, 4 };
const int numButtons = sizeof(buttonPins) / sizeof(buttonPins[0]);
// 第一首歌
const int melody1[] = {
REST,NOTE_F4,NOTE_FS4,NOTE_GS4,NOTE_AS4,NOTE_AS3,NOTE_CS4,NOTE_CS5,NOTE_AS4,NOTE_CS3,NOTE_F3,NOTE_GS3,
NOTE_F4,NOTE_FS4,NOTE_GS4,NOTE_AS4,NOTE_AS3,NOTE_CS4,NOTE_CS5,NOTE_AS4,NOTE_GS4,NOTE_AS4,NOTE_FS4,NOTE_GS4,
NOTE_F4,NOTE_FS4,NOTE_CS4,NOTE_F4,NOTE_FS4,NOTE_GS4,NOTE_AS4,NOTE_AS3,NOTE_CS4,NOTE_CS5,NOTE_AS4,
NOTE_CS3,NOTE_F3,NOTE_GS3,NOTE_F4,NOTE_FS4,NOTE_GS4,NOTE_AS4,NOTE_AS3,NOTE_CS4,NOTE_CS5,NOTE_AS4,
NOTE_GS4,NOTE_AS4,NOTE_FS4,NOTE_GS4,NOTE_F4,NOTE_FS4,NOTE_CS4
};
const int melody1Beats[] = {
2500,183,183,183,183,183,183,183,183,366,366,732,
183,183,183,183,183,183,183,183,183,183,183,183,
183,183,366,183,183,183,183,183,183,183,183,
366,366,732,183,183,183,183,183,183,183,183,
183,183,183,183,183,183,366
};
// 第二首歌
const int melody2[] = {
NOTE_D3,NOTE_D2,NOTE_D3,NOTE_D6,NOTE_D3,NOTE_D2,NOTE_D3,NOTE_D7,
NOTE_D3,NOTE_D2,NOTE_D3,NOTE_DH1,NOTE_D7,NOTE_D5,
NOTE_D3,NOTE_D2,NOTE_D3,NOTE_D6,NOTE_D3,NOTE_D2,NOTE_D3,NOTE_D7,
NOTE_D5,NOTE_D2,NOTE_DL7,
NOTE_D3,NOTE_D2,NOTE_D3,NOTE_D6,NOTE_D3,NOTE_D2,NOTE_D3,NOTE_D7,
NOTE_D3,NOTE_D2,NOTE_D3,NOTE_DH1,NOTE_D7,NOTE_D5,
NOTE_D2,NOTE_D3,NOTE_DL6,NOTE_D2,NOTE_D3,NOTE_DL6,NOTE_DL5,
NOTE_DL6,NOTE_D1,NOTE_DL7,
NOTE_DL6,NOTE_D1,NOTE_D1,NOTE_D2,NOTE_D2,NOTE_D3,NOTE_D3,NOTE_D5,NOTE_D6,
NOTE_D5,NOTE_D3,NOTE_D2,
NOTE_DL6,NOTE_D1,NOTE_D1,NOTE_D2,NOTE_D2,NOTE_D3,NOTE_D3,NOTE_DL6,NOTE_DL5,
NOTE_DL6,NOTE_D1,NOTE_D1,NOTE_D2,NOTE_D2,NOTE_D3,NOTE_D3,NOTE_D5,NOTE_D6,
NOTE_D5,NOTE_D3,NOTE_D2,
NOTE_D2,NOTE_D3,NOTE_DL6,NOTE_D2,NOTE_D3,NOTE_DL6,NOTE_DL5,NOTE_DL6,
NOTE_DL6,NOTE_D1,NOTE_D2,NOTE_D1,NOTE_DL6,
NOTE_DL6,NOTE_D1,NOTE_D2,NOTE_D1,NOTE_D3,
NOTE_D3,NOTE_D5,NOTE_D6,NOTE_D6,NOTE_D5,NOTE_D3,NOTE_D2,NOTE_D1,NOTE_D2,NOTE_D3,
NOTE_DL6,NOTE_D1,NOTE_D2,NOTE_D1,NOTE_DL6,
NOTE_DL6,NOTE_D1,NOTE_D2,NOTE_D1,NOTE_D3,
NOTE_D2,NOTE_D3,NOTE_DL6,NOTE_D2,NOTE_D3,NOTE_DL6,NOTE_DL5,NOTE_DL6,
NOTE_D3,NOTE_D5,NOTE_DH1,NOTE_D7,NOTE_D3,
NOTE_D3,NOTE_D2,NOTE_D1,NOTE_D1,NOTE_D2,NOTE_D3,
NOTE_D3,NOTE_D2,NOTE_D1,NOTE_D6,NOTE_DH1,NOTE_D7,NOTE_D6,NOTE_D5,NOTE_D2,NOTE_D3,
NOTE_D3,NOTE_D5,NOTE_DH1,NOTE_D7,NOTE_D3,
NOTE_D3,NOTE_D2,NOTE_D1,NOTE_D1,NOTE_D2,NOTE_D3,
NOTE_D2,NOTE_D3,NOTE_DL6,NOTE_D2,NOTE_D3,NOTE_DL6,NOTE_DL5,NOTE_DL6
};
const int melody2Beats[] = {
250,250,250,250,500,500,
250,250,250,250,250,250,250,250,
500,500,1000,
250,250,250,250,250,250,250,250,
250,250,250,250,500,500,
250,250,500,250,250,250,250,500,500,1000,
250,250,250,250,250,250,250,125,125,
750,250,1000,
250,250,250,250,250,250,500,500,1500,
250,250,250,250,250,250,250,125,125,
750,250,1000,
250,250,500,250,250,250,250,1500,
250,250,750,250,500,250,250,
750,250,500,250,250,500,250,250,250,250,500,500,1000,
250,250,875,125,500,250,250,500,500,1000,
250,250,500,250,250,250,250,1500,
250,250,750,250,500,250,250,
500,250,250,500,250,250,500,250,250,250,250,250,250,1500,
250,250,750,250,500,250,250,
500,250,250,1000,250,250,500,250,250,250,250,2000};
const int melody3[] = { NOTE_G5,NOTE_E5,NOTE_F5,NOTE_G5,NOTE_E5,NOTE_F5,
NOTE_G5,NOTE_G4,NOTE_A4,NOTE_B4,NOTE_C5,NOTE_D5,NOTE_E5,NOTE_F5,
NOTE_E5,NOTE_C5,NOTE_D5,NOTE_E5,NOTE_E4,NOTE_F4,
NOTE_G4,NOTE_A4,NOTE_G4,NOTE_F4,NOTE_G4,NOTE_E4,NOTE_F4,NOTE_G4,
NOTE_F4,NOTE_A4,NOTE_G4,NOTE_F4,NOTE_E4,NOTE_D4,
NOTE_E4,NOTE_D4,NOTE_C4,NOTE_D4,NOTE_E4,NOTE_F4,NOTE_G4,NOTE_A4,
NOTE_F4,NOTE_A4,NOTE_G4,NOTE_A4,NOTE_B4,NOTE_C5,
NOTE_G4,NOTE_A4,NOTE_B4,NOTE_C5,NOTE_D5,NOTE_E5,NOTE_F5,NOTE_G5
};
const int melody3Beats[] = {500,250,250,500,250,250,
500,250,250,250,250,250,250,250,
500,250,250,500,250,250,
500,250,250,250,250,250,250,250,
500,250,250,500,250,250,
500,250,250,250,250,250,250,250,
500,250,250,500,250,250,
500,250,250,250,250,250,250,250
};
// 歌曲数组
const int* melodies[] = { melody1, melody2 ,melody3};
const int* beatArrays[] = { melody1Beats, melody2Beats ,melody3Beats};
const int melodyLengths[] = {
sizeof(melody1) / sizeof(melody1[0]),
sizeof(melody2) / sizeof(melody2[0]),
sizeof(melody3) / sizeof(melody3[0])
};
const int numMelodies = sizeof(melodies) / sizeof(melodies[0]);
// 全局变量
int currentMelody = 0;
bool isPlaying = false;
int currentNote = 0;
unsigned long lastNoteTime = 0;
int tempo = 120;
void setup() {
// 初始化按钮引脚
for (uint8_t i = 0; i < numButtons; i++) {
pinMode(buttonPins[i], INPUT_PULLUP);
}
pinMode(SPEAKER_PIN, OUTPUT);
}
void loop() {
// 读取按钮状态
for (uint8_t i = 0; i < numButtons; i++) {
if (digitalRead(buttonPins[i]) == LOW) {
handleButton(i);
delay(20); // 消抖
}
}
// 播放音乐
if (isPlaying) {
playMelody();
}
}
void handleButton(int buttonIndex) {
if (buttonIndex < numMelodies) {
// 选择歌曲
currentMelody = buttonIndex;
currentNote = 0;
isPlaying = true;
}
else if (buttonIndex == numMelodies) {
// 暂停/播放
isPlaying = !isPlaying;
if (!isPlaying) {
noTone(SPEAKER_PIN);
}
}
else if (buttonIndex == numMelodies + 1) {
// 加速
tempo = min(tempo + 10, 240);
}
else if (buttonIndex == numMelodies + 2) {
// 减速
tempo = max(tempo - 10, 1);
}
else if (buttonIndex == numMelodies + 3) {
// 下一首
currentMelody = (currentMelody + 1) % numMelodies;
currentNote = 0;
isPlaying = true;
}
else if (buttonIndex == numMelodies + 4) {
// 上一首
currentMelody = (currentMelody > 0) ? (currentMelody - 1) : (numMelodies - 1);
currentNote = 0;
isPlaying = true;
}
}
void playMelody() {
if (currentNote >= melodyLengths[currentMelody]) {
isPlaying = false;
noTone(SPEAKER_PIN);
return;
}
unsigned long currentMillis = millis();
unsigned long noteDuration = beatArrays[currentMelody][currentNote];
if (currentMillis - lastNoteTime >= noteDuration) {
int note = melodies[currentMelody][currentNote];
if (note != REST) {
tone(SPEAKER_PIN, note, noteDuration);
} else {
noTone(SPEAKER_PIN);
}
lastNoteTime = currentMillis;
currentNote++;
}
}