#include <Adafruit_NeoPixel.h>
// Pin configuration
const int LED_PIN = 23;
const int TEMPO_BUTTON_PIN = 13; // Pin for the button
const int RESET_BUTTON_PIN = 12; // Pin for the reset button
const int CHANGE_SET_BUTTON_PIN = 11; // Pin for changing the interval set
const int NUM_LEDS = 18;
const int BRIGHTNESS = 255;
const int DEFAULT_BPM = 60;
const int BUTTON_DEBOUNCE_DELAY = 50;
// NeoPixel object
Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_LEDS, LED_PIN, NEO_GRB + NEO_KHZ800);
// Structs to represent intervals and LED states
struct Interval {
float startTime;
float endTime;
int ledIndex;
};
struct LedState {
bool isOn;
};
// Array of intervals arrays
Interval intervalsAndNotesSets[][24] = {
{
{2.29, 4.27, 2},
{2.29, 4.25, 7},
{2.29, 4.24, 1},
{4.57, 5.94, 4},
{4.57, 5.96, 7},
{4.57, 5.94, 11},
{6.29, 6.79, 4},
{6.29, 6.80, 7},
{6.29, 6.80, 11},
{6.86, 8.96, 0},
{6.86, 8.99, 4},
{6.86, 9.00, 7},
{9.14, 11.12, 2},
{9.14, 11.13, 6},
{9.14, 11.15, 9},
{11.43, 13.31, 2},
{11.43, 13.24, 7},
{11.43, 13.27, 11},
{13.71, 15.17, 4},
{13.71, 15.17, 7},
{13.71, 15.15, 11},
{15.43, 15.88, 4},
{15.43, 15.90, 7},
{15.43, 15.90, 11}
},
{
{2.29, 4.27, 0},
{2.29, 4.25, 1},
{2.29, 4.24, 2},
{4.57, 5.94, 0},
{4.57, 5.96, 1},
{4.57, 5.94, 2},
{6.29, 6.79, 0},
{6.29, 6.80, 1},
{6.29, 6.80, 2},
{6.86, 8.96, 6},
{6.86, 8.99, 7},
{6.86, 9.00, 8},
{9.14, 11.12, 2},
{9.14, 11.13, 6},
{9.14, 11.15, 9},
{11.43, 13.31, 2},
{11.43, 13.24, 7},
{11.43, 13.27, 11},
{13.71, 15.17, 4},
{13.71, 15.17, 7},
{13.71, 15.15, 11},
{15.43, 15.88, 4},
{15.43, 15.90, 7},
{15.43, 15.90, 11}
},
};
// Array to store LED states
LedState ledStates[NUM_LEDS];
// Function prototypes
void initializeLEDs();
void updateLED(int index, bool turnOn);
void updateLEDState(int index, bool turnOn);
void showLEDs();
void checkButton();
int bpm = DEFAULT_BPM;
int currentMillis = 0;
int currentIntervalSet = 0;
#define BOXSIZE 80
#define PENRADIUS 3
int oldcolor, currentcolor;
void setup() {
Serial.begin(9600);
initializeLEDs();
// Set up the button pin
pinMode(TEMPO_BUTTON_PIN, INPUT);
pinMode(RESET_BUTTON_PIN, INPUT);
pinMode(CHANGE_SET_BUTTON_PIN, INPUT);
for (int i = 0; i < sizeof(intervalsAndNotesSets[currentIntervalSet]) / sizeof(Interval); i++) {
intervalsAndNotesSets[currentIntervalSet][i].endTime -= 0.05;
}
}
void loop() {
// Check for button press to change tempo
checkButton();
checkResetButton();
checkChangeSetButton();
float currentTime = (millis() - currentMillis) / (60000.0 / bpm);
for (int i = 0; i < NUM_LEDS; i++) {
bool ledOn = false;
for (Interval &interval : intervalsAndNotesSets[currentIntervalSet]) {
if (currentTime >= interval.startTime && currentTime <= interval.endTime && i == interval.ledIndex) {
ledOn = true;
break;
}
}
updateLEDState(i, ledOn);
}
showLEDs();
delay(10);
}
void initializeLEDs() {
strip.begin();
strip.show();
strip.setBrightness(BRIGHTNESS);
for (int i = 0; i < NUM_LEDS; i++) {
ledStates[i] = {false};
}
}
void updateLEDState(int index, bool turnOn) {
if (turnOn != ledStates[index].isOn) {
updateLED(index, turnOn);
}
}
void updateLED(int index, bool turnOn) {
if (turnOn) {
// Turn on the required LED
strip.setPixelColor(index, strip.Color(255, 0, 0)); // Red color, adjust as needed
ledStates[index] = {true};
} else {
// Turn off the specified LED
strip.setPixelColor(index, strip.Color(0, 0, 0)); // Off
ledStates[index] = {false};
}
}
void showLEDs() {
strip.show();
}
void resetMainLoop() {
// Reset LED states
for (int i = 0; i < NUM_LEDS; i++) {
updateLEDState(i, false);
}
// Reset BPM
//bpm = DEFAULT_BPM;
// set currentMillis to actual millis value
currentMillis = millis();
}
void checkButton() {
static unsigned long lastButtonPressTime = 0;
static bool buttonState = HIGH;
static bool lastButtonState = HIGH;
static bool buttonInitialized = false;
unsigned long currentMillis = millis();
if (!buttonInitialized) {
// Initialize the button state
buttonState = digitalRead(TEMPO_BUTTON_PIN);
lastButtonState = buttonState;
buttonInitialized = true;
}
if (currentMillis - lastButtonPressTime > BUTTON_DEBOUNCE_DELAY) {
buttonState = digitalRead(TEMPO_BUTTON_PIN);
if (buttonState != lastButtonState) {
if (buttonState == LOW) {
// Button is pressed, change tempo
bpm += 10; // Increase tempo by 10 BPM
if (bpm > 200) {
bpm = DEFAULT_BPM; // Reset to default if BPM exceeds 200
}
Serial.print("BPM: ");
Serial.println(bpm);
}
lastButtonPressTime = currentMillis;
}
lastButtonState = buttonState;
}
}
void checkResetButton() {
static unsigned long lastResetButtonPressTime = 0;
static bool resetButtonState = HIGH;
static bool lastResetButtonState = HIGH;
static bool resetButtonInitialized = false;
unsigned long currentMillis = millis();
if (!resetButtonInitialized) {
// Initialize the reset button state
resetButtonState = digitalRead(RESET_BUTTON_PIN);
lastResetButtonState = resetButtonState;
resetButtonInitialized = true;
}
if (currentMillis - lastResetButtonPressTime > BUTTON_DEBOUNCE_DELAY) {
resetButtonState = digitalRead(RESET_BUTTON_PIN);
if (resetButtonState != lastResetButtonState) {
if (resetButtonState == LOW) {
// Reset button is pressed, perform reset actions
resetMainLoop();
Serial.println("Reset button pressed");
}
lastResetButtonPressTime = currentMillis;
}
lastResetButtonState = resetButtonState;
}
}
void checkChangeSetButton() {
static unsigned long lastChangeSetButtonPressTime = 0;
static bool changeSetButtonState = HIGH;
static bool lastChangeSetButtonState = HIGH;
static bool changeSetButtonInitialized = false;
unsigned long currentMillis = millis();
if (!changeSetButtonInitialized) {
// Initialize the change set button state
changeSetButtonState = digitalRead(CHANGE_SET_BUTTON_PIN);
lastChangeSetButtonState = changeSetButtonState;
changeSetButtonInitialized = true;
}
if (currentMillis - lastChangeSetButtonPressTime > BUTTON_DEBOUNCE_DELAY) {
changeSetButtonState = digitalRead(CHANGE_SET_BUTTON_PIN);
if (changeSetButtonState != lastChangeSetButtonState) {
if (changeSetButtonState == LOW) {
// Change set button is pressed, change the interval set
currentIntervalSet = (currentIntervalSet + 1) % (sizeof(intervalsAndNotesSets) / sizeof(intervalsAndNotesSets[0]));
Serial.print("Changed to Interval Set: ");
Serial.println(currentIntervalSet);
}
lastChangeSetButtonPressTime = currentMillis;
}
lastChangeSetButtonState = changeSetButtonState;
}
}