/*
Wokwi | general
reyydean — 9/20/25 7:27 PM
Project Link: https://wokwi.com/projects/442645968652418049?gh=1
Arduino songs:
https://github.com/robsoncouto/arduino-songs/tree/master
*/
#include <LiquidCrystal_I2C.h>
#include "pitches.h"
const int BUZZ_PIN = 8;
const int COLS = 16;
const int ROWS = 2;
const int TEMPO = 140; // melody tempo
const unsigned long SCROLL_SPD = 250; // scroll speed
int melody[] = {
// Happy Birthday
// Score available at https://musescore.com/user/8221/scores/26906
NOTE_C4, NOTE_C4, NOTE_D4, NOTE_C4, NOTE_F4, NOTE_E4,
NOTE_C4, NOTE_C4, NOTE_D4, NOTE_C4, NOTE_G4, NOTE_F4,
NOTE_C4, NOTE_C4, NOTE_C5, NOTE_A4, NOTE_F4, NOTE_E4, NOTE_D4,
NOTE_AS4, NOTE_AS4, NOTE_A4, NOTE_F4, NOTE_G4, NOTE_F4
};
// 2 = half note, 4 = quarter note, 8 = eighth note, etc.
int noteDurations[] = {
4, 8, 4, 4, 4, 2,
4, 8, 4, 4, 4, 2,
4, 8, 4, 4, 4, 4, 2,
4, 8, 4, 4, 4, 2
};
int notes = sizeof(melody) / sizeof(melody[0]) ;
int wholenote = (60000 * 4) / TEMPO;
int currentNoteIndex = 0;
int scrollPos = 0;
unsigned long previousNoteMillis = 0;
unsigned long noteDuration;
unsigned long lastScroll = 0;
LiquidCrystal_I2C lcd (0x27, COLS, ROWS);
void initLCD() {
lcd.clear();
lcd.setCursor(16, 0);
lcd.print("Happy birthday");
lcd.setCursor(20, 1);
lcd.print("Lia !!!");
}
void playTune() {
if (millis() - previousNoteMillis >= noteDuration) {
previousNoteMillis = millis();
if (currentNoteIndex < notes) { // melody is not done
noteDuration = 1000 / noteDurations[currentNoteIndex];
if (melody[currentNoteIndex] != REST) { // if not a REST
tone(BUZZ_PIN, melody[currentNoteIndex], noteDuration * 0.9);
} else {
noTone(BUZZ_PIN);
}
noteDuration = noteDuration * 1.1; // adds small pause between notes
currentNoteIndex++; // next note
} else { // melody is done
noTone(BUZZ_PIN);
currentNoteIndex = 0;
}
}
}
void scrollMsg() {
if (millis() - lastScroll >= SCROLL_SPD) {
lastScroll = millis();
lcd.scrollDisplayLeft();
scrollPos++;
if (scrollPos >= 31) {
scrollPos = 0;
initLCD();
}
}
}
void setup() {
lcd.init();
lcd.backlight();
pinMode(BUZZ_PIN, OUTPUT);
initLCD();
}
void loop() {
scrollMsg();
playTune();
}