#include <LiquidCrystal_I2C.h>
// Notes
#define NOTE_C4 262
#define NOTE_D4 294
#define NOTE_E4 330
#define NOTE_F4 349
#define NOTE_G4 392
#define NOTE_A4 440
#define NOTE_B4 494
#define SPEAKER_PIN 8
// LCD
#define I2C_ADDR 0x27
#define LCD_COLUMNS 20
#define LCD_LINES 4
// Set up LCD
LiquidCrystal_I2C lcd(I2C_ADDR, LCD_COLUMNS, LCD_LINES);
// LED Pins: 10-Yellow, 11-Green, 12-Red, 13-Blue
const uint8_t ledPins[] = {10, 11, 12, 13};
// Variables
// tune_01 is a table containing notes to play
int tune_01[] = {NOTE_C4, NOTE_D4, NOTE_E4, NOTE_F4, NOTE_G4, NOTE_A4, NOTE_B4};
int note_time = 300;
int gap_time = 100;
int no_notes = 7; //the number of notes in the tunes array
int potpin = 0; // port A0
int val; // variable for reading potentiometer
long randNumber; // random number variable
int iTune = 0; // Note played
int iLED = 0; // LED Pin
// Set up Section to initialize all components
void setup() {
// Set up LCD
lcd.init();
lcd.backlight();
// Set up LED to OUTPUT mode
for (byte i = 0; i < 4; i++) {
pinMode(ledPins[i], OUTPUT);
}
// Set up Speaker to OUTPUT mode
pinMode(SPEAKER_PIN, OUTPUT);
}
// *** Main Loop ***
void loop() {
// Print all static information (song name, titles)
lcd.setCursor(0, 0); // Print Song Name at Row 0, Col 0
lcd.print("Some Random Song!");
lcd.setCursor(0, 1); // Print Speed title at Row 1, Col 0
lcd.print("Speed: ");
lcd.setCursor(0, 2); // Print Note title at Row 2, Col 0
lcd.print("Note : ");
// Loop from 0 to 7
for (int i = 0; i < no_notes; i++) {
val = analogRead(potpin); // reads the value of the potentiometer (value between 0 and 1023)
val = map(val, 0, 1023, 100, 500); // scale it to use it with the servo (value between 0 and 180)
lcd.setCursor(7, 1); // Print speed at Row 1, Col 7
lcd.print(val);
iLED = random(0, 4); // pick a random number from 0 to 4 for LED
digitalWrite(ledPins[iLED], HIGH); // Switch On LED
randNumber = random(0, 7); // Set a random number from 0 to 7 for tune
iTune = tune_01[randNumber]; // Pick Note from tune_01 table
tone(SPEAKER_PIN, iTune, val); // play tone based on potentiometer position
// Case statement to display the label of the note played
switch (iTune) { // Display Note Label based on value
case NOTE_C4:
// lcd.setCursor(7,2); // Replaced all print codes with
// lcd.print("NOTE_C4 "); // custom function for efficiency
// lcd.setCursor(15,2);
// lcd.print(iTune);
LCD_Print("NOTE_C4"); // Call LCD_Print function to display
break;
case NOTE_D4:
// lcd.setCursor(7,2);
// lcd.print("NOTE_D4 ");
// lcd.setCursor(15,2);
// lcd.print(iTune);
LCD_Print("NOTE_D4"); // Call LCD_Print function to display
break;
case NOTE_E4:
// lcd.setCursor(7,2);
// lcd.print("NOTE_E4 ");
// lcd.setCursor(15,2);
// lcd.print(iTune);
LCD_Print("NOTE_E4"); // Call LCD_Print function to display
break;
case NOTE_F4:
// lcd.setCursor(7,2);
// lcd.print("NOTE_F4 ");
// lcd.setCursor(15,2);
// lcd.print(iTune);
LCD_Print("NOTE_F4"); // Call LCD_Print function to display
break;
case NOTE_G4:
// lcd.setCursor(7,2);
// lcd.print("NOTE_G4 ");
// lcd.setCursor(15,2);
// lcd.print(iTune);
LCD_Print("NOTE_G4"); // Call LCD_Print function to display
break;
case NOTE_A4:
// lcd.setCursor(7,2);
// lcd.print("NOTE_A4 ");
// lcd.setCursor(15,2);
// lcd.print(iTune);
LCD_Print("NOTE_A4"); // Call LCD_Print function to display
break;
case NOTE_B4:
// lcd.setCursor(7,2);
// lcd.print("NOTE_B4 ");
// lcd.setCursor(15,2);
// lcd.print(iTune);
LCD_Print("NOTE_B4"); // Call LCD_Print function to display
break;
default:
lcd.setCursor(7,2); // Print Blank by default
lcd.print(" ");
break;
}
delay(gap_time+val); // delay
digitalWrite(ledPins[iLED], LOW); // Switch Off LED
}
}
// Custom function to print the Note Label (more code efficient)
// iString is passed to the function for display
void LCD_Print(String iString)
{
lcd.setCursor(7,2); // Print Note played at Row 2, Col 7
lcd.print(iString);
lcd.setCursor(15,2);
lcd.print(iTune);
}