#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
int buzzerMelody = 14; // Pin for melody
int buzzerRhythm = 27; // Pin for rhythm
int ledDo = 2; // LED for Do
int ledRe = 4; // LED for Re
int ledMi = 16; // LED for Mi
int ledFa = 17; // LED for Fa
int ledSol = 5; // LED for Sol
int ledLa = 18; // LED for La
int ledSi = 19; // LED for Si
int buttonUp = 12;
int buttonDown = 13;
int buttonOk = 32;
int buttonTempoUp = 33;
int buttonTempoDown = 34;
int currentSong = 1;
int tempoFactor = 1; // Default tempo
// Example song melodies (you can add more songs)
int melodyNotes[] = {262, 294, 330, 349, 392, 440, 494}; // C D E F G A B (Do, Re, Mi, Fa, Sol, La, Si)
int melodyDurations[] = {500, 500, 500, 500, 500, 500, 500};
int rhythmNotes[] = {392, 349, 330, 294, 262}; // G F E D C (Sol, Fa, Mi, Re, Do)
int rhythmDurations[] = {500, 500, 500, 500, 500};
void setup() {
pinMode(buzzerMelody, OUTPUT);
pinMode(buzzerRhythm, OUTPUT);
pinMode(ledDo, OUTPUT);
pinMode(ledRe, OUTPUT);
pinMode(ledMi, OUTPUT);
pinMode(ledFa, OUTPUT);
pinMode(ledSol, OUTPUT);
pinMode(ledLa, OUTPUT);
pinMode(ledSi, OUTPUT);
pinMode(buttonUp, INPUT_PULLUP);
pinMode(buttonDown, INPUT_PULLUP);
pinMode(buttonOk, INPUT_PULLUP);
pinMode(buttonTempoUp, INPUT_PULLUP);
pinMode(buttonTempoDown, INPUT_PULLUP);
// Initialize OLED
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("SSD1306 allocation failed"));
for (;;);
}
display.clearDisplay();
display.display();
displayMenu();
// Create tasks for playing melody and rhythm
xTaskCreatePinnedToCore(playMelody, "Melody Task", 10000, NULL, 1, NULL, 0);
xTaskCreatePinnedToCore(playRhythm, "Rhythm Task", 10000, NULL, 1, NULL, 1);
}
void loop() {
checkButtons(); // Handle button inputs
}
void checkButtons() {
if (digitalRead(buttonUp) == LOW) {
currentSong++;
if (currentSong > 10) currentSong = 1;
displayMenu();
delay(200);
}
if (digitalRead(buttonDown) == LOW) {
currentSong--;
if (currentSong < 1) currentSong = 10;
displayMenu();
delay(200);
}
if (digitalRead(buttonTempoUp) == LOW) {
tempoFactor++;
displayMenu();
delay(200);
}
if (digitalRead(buttonTempoDown) == LOW) {
tempoFactor = max(1, tempoFactor - 1);
displayMenu();
delay(200);
}
}
void displayMenu() {
display.clearDisplay();
display.setTextSize(2);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
display.print(" Song: ");
display.println(currentSong);
display.setCursor(0, 35);
display.print("Tempo: ");
display.println(tempoFactor);
display.display();
}
void playMelody(void * parameter) {
while (true) {
for (int i = 0; i < sizeof(melodyNotes) / sizeof(int); i++) {
tone(buzzerMelody, melodyNotes[i]);
lightUpLED(melodyNotes[i]); // Light up corresponding LED for melody
vTaskDelay((melodyDurations[i] / tempoFactor) / portTICK_PERIOD_MS);
noTone(buzzerMelody);
turnOffAllLEDs(); // Turn off all LEDs
vTaskDelay(50 / portTICK_PERIOD_MS);
}
vTaskDelay(1000 / portTICK_PERIOD_MS); // Pause between loops
}
}
void playRhythm(void * parameter) {
while (true) {
for (int i = 0; i < sizeof(rhythmNotes) / sizeof(int); i++) {
tone(buzzerRhythm, rhythmNotes[i]);
lightUpLED(rhythmNotes[i]); // Light up corresponding LED for rhythm
vTaskDelay((rhythmDurations[i] / tempoFactor) / portTICK_PERIOD_MS);
noTone(buzzerRhythm);
turnOffAllLEDs(); // Turn off all LEDs
vTaskDelay(50 / portTICK_PERIOD_MS);
}
vTaskDelay(1000 / portTICK_PERIOD_MS); // Pause between loops
}
}
void lightUpLED(int frequency) {
// Check the frequency and light the corresponding LED
if (frequency == 262) { // Do (C)
digitalWrite(ledDo, HIGH);
} else if (frequency == 294) { // Re (D)
digitalWrite(ledRe, HIGH);
} else if (frequency == 330) { // Mi (E)
digitalWrite(ledMi, HIGH);
} else if (frequency == 349) { // Fa (F)
digitalWrite(ledFa, HIGH);
} else if (frequency == 392) { // Sol (G)
digitalWrite(ledSol, HIGH);
} else if (frequency == 440) { // La (A)
digitalWrite(ledLa, HIGH);
} else if (frequency == 494) { // Si (B)
digitalWrite(ledSi, HIGH);
}
}
void turnOffAllLEDs() {
// Turn off all LEDs
digitalWrite(ledDo, LOW);
digitalWrite(ledRe, LOW);
digitalWrite(ledMi, LOW);
digitalWrite(ledFa, LOW);
digitalWrite(ledSol, LOW);
digitalWrite(ledLa, LOW);
digitalWrite(ledSi, LOW);
}