#include <Toggle.h>
#include "melodies.h"
struct Melody {
int * melody;
size_t noteCnt;
int tempo;
};
Melody songList[] = {
{mario, sizeof(mario) / sizeof(*mario) / 2, 120},
{starWars, sizeof(starWars) / sizeof(*starWars) / 2, 80},
{indianaJones, sizeof(indianaJones) / sizeof(*indianaJones) / 2, 100},
{titanic, sizeof(titanic) / sizeof(*titanic) / 2, 90}
};
const byte buzzerPin = 11;
const byte songSelectPins[] = {2, 3, 4, 5};
const byte ledPins[] = {6, 7, 8, 9};
Toggle songSelectBtns[4];
size_t currentSong = 0;
int currentNote = 0;
unsigned long previousNoteTime = 0;
unsigned long noteDuration = 0;
bool notePlaying = false;
void playNextNote() {
Melody &activeMelody = songList[currentSong];
int wholenote = (60000L * 4) / activeMelody.tempo;
int divider = 0;
if (currentNote < activeMelody.noteCnt * 2) {
divider = activeMelody.melody[currentNote + 1];
if (divider > 0) {
noteDuration = wholenote / divider;
} else if (divider < 0) {
noteDuration = wholenote / abs(divider);
noteDuration *= 1.5;
}
tone(buzzerPin, activeMelody.melody[currentNote], noteDuration * 0.9);
previousNoteTime = millis();
notePlaying = true;
currentNote += 2;
} else {
currentNote = 0;
notePlaying = false;
}
}
void resetMelodyState() {
noTone(buzzerPin);
currentNote = 0;
notePlaying = false;
for (int i = 0; i < 4; ++i) {
digitalWrite(ledPins[i], LOW);
}
digitalWrite(ledPins[currentSong], HIGH);
Serial.print("Música tocando: ");
switch (currentSong) {
case 0:
Serial.println("Mario Bros");
break;
case 1:
Serial.println("Star Wars");
break;
case 2:
Serial.println("Indiana Jones");
break;
case 3:
Serial.println("Titanic");
break;
default:
Serial.println("Desconhecido");
break;
}
}
void setup() {
Serial.begin(115200);
pinMode(buzzerPin, OUTPUT);
for (int i = 0; i < 4; ++i) {
pinMode(songSelectPins[i], INPUT_PULLUP);
songSelectBtns[i].begin(songSelectPins[i]);
pinMode(ledPins[i], OUTPUT);
digitalWrite(ledPins[i], LOW);
}
resetMelodyState();
}
void loop() {
for (int i = 0; i < 4; ++i) {
songSelectBtns[i].poll();
if (songSelectBtns[i].onPress()) {
currentSong = i;
resetMelodyState();
}
}
if (!notePlaying) {
playNextNote();
} else {
if (millis() - previousNoteTime >= noteDuration) {
noTone(buzzerPin);
notePlaying = false;
}
}
}