#include <LiquidCrystal.h>
#include <math.h>
// lcd(RS, E, D4, D5, D6, D7) pin configuration for the LCD screen
const int rs = 2, en = 3, d4 = 4, d5 = 5, d6 = 6, d7 = 7;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7); // Initialise the LCD
const int sensorPin = A0; // Analog pin connected to the potentiometer.
const int led1 = 12; // Pin for the first LED.
const int led2 = 11; // Pin for the second LED.
const int led3 = 10; // Pin for the third LED.
const int led4 = 9; // Pin for the fourth LED.
// The 4 LEDs will indicate the tempo (in any time signature).
int sensorValue; // Variable to store potentiometer reading.
int bpm; // Variable to store the calculated BPM (beats per minute).
double interval; // Time interval (in ms) between each LED flash.
int counter = 0; // Counter to track which LED should be turned on.
int timeSignature = 4; // Default time signature (e.g., 4/4), can be changed.
void setup() {
pinMode(led1, OUTPUT); // Set the first LED as output.
pinMode(led2, OUTPUT); // Set the second LED as output.
pinMode(led3, OUTPUT); // Set the third LED as output.
pinMode(led4, OUTPUT); // Set the fourth LED as output.
lcd.begin(16, 2); // Initialise the LCD to have 16 columns and 2 rows.
lcd.print("BPM:"); // Print "BPM:" on the LCD to label the BPM display.
Serial.begin(9600); // Start the serial communication at 9600 baud rate.
}
void loop() {
lcd.setCursor(5, 0); // Move the cursor to the 6th character of the first row on the LCD.
sensorValue = analogRead(sensorPin); // Read the current value of the potentiometer.
bpm = map(sensorValue, 0, 1023, 60, 170); // Map the potentiometer value to a BPM range of 60 to 170.
interval = 60000 / bpm; // Calculate the interval between beats in milliseconds.
lcd.print(String(bpm)); // Display the BPM on the LCD screen.
counter += 1; // Increment the counter to track the current beat.
// Use the counter value to determine which LED should be turned on/off
switch(counter) {
case 1:
digitalWrite(led1, HIGH); // Turn on the first LED for the first beat.
delay(interval); // Wait for the calculated interval.
digitalWrite(led1, LOW); // Turn off the first LED after the delay.
break;
case 2:
if (timeSignature >= 2) { // Only flash the second LED if the time signature has at least 2 beats.
digitalWrite(led2, HIGH); // Turn on the second LED for the second beat.
delay(interval); // Wait for the calculated interval.
digitalWrite(led2, LOW); // Turn off the second LED after the delay.
}
break;
case 3:
if (timeSignature >= 3) { // Only flash the third LED if the time signature has at least 3 beats.
digitalWrite(led3, HIGH); // Turn on the third LED for the third beat.
delay(interval); // Wait for the calculated interval.
digitalWrite(led3, LOW); // Turn off the third LED after the delay.
}
break;
case 4:
if (timeSignature == 4) { // Only flash the fourth LED if the time signature is 4/4 or greater.
digitalWrite(led4, HIGH); // Turn on the fourth LED for the fourth beat.
delay(interval); // Wait for the calculated interval.
digitalWrite(led4, LOW); // Turn off the fourth LED after the delay.
}
break;
}
// Reset the counter based on the time signature
if (counter >= timeSignature) {
counter = 0; // Reset counter when reaching the end of the measure.
}
}