89 lines
2.6 KiB
C++
89 lines
2.6 KiB
C++
// MELODY PLAYBACK WILL BE HANDLED HERE
|
|
#include <vector>
|
|
|
|
extern Player player;
|
|
|
|
// Define a structure to track active solenoids
|
|
struct ActiveRelay {
|
|
uint8_t relayIndex; // Index of the relay
|
|
uint64_t activationTime; // Activation start time
|
|
uint16_t duration; // Duration for which it should remain active
|
|
};
|
|
|
|
// Array of durations for each relay (configure remotely)
|
|
uint16_t relayDurations[16] = {90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90};
|
|
// Vector to track active solenoids
|
|
std::vector<ActiveRelay> activeRelays;
|
|
|
|
|
|
|
|
void loop_playback(std::vector<uint16_t> &melody_steps);
|
|
void bellEngine(void *parameter);
|
|
void relayControlTask(void *param);
|
|
void itsHammerTime(uint16_t note);
|
|
void turnOffRelays(uint64_t now);
|
|
|
|
void bellEngine(void *parameter) {
|
|
// SETUP TASK
|
|
for (;;) {
|
|
// Playback until stopped (Completes AT LEAST 1 full loop)
|
|
loop_playback(melody_steps);
|
|
/*
|
|
UBaseType_t highWaterMark = uxTaskGetStackHighWaterMark(NULL);
|
|
Serial.print("Stack high water mark: ");
|
|
Serial.println(highWaterMark);
|
|
*/
|
|
}
|
|
}
|
|
|
|
// Task to deactivate relays dynamically
|
|
void relayControlTask(void *param) {
|
|
while (true) {
|
|
uint64_t now = millis();
|
|
// Iterate through active relays and deactivate those whose duration has elapsed
|
|
for (auto it = activeRelays.begin(); it != activeRelays.end();) {
|
|
if (now - it->activationTime >= it->duration) {
|
|
relays.digitalWrite(it->relayIndex, HIGH); // Deactivate the relay
|
|
it = activeRelays.erase(it); // Remove from the active list
|
|
} else {
|
|
++it; // Move to the next relay
|
|
}
|
|
}
|
|
|
|
vTaskDelay(pdMS_TO_TICKS(10)); // Check every 10ms
|
|
}
|
|
}
|
|
|
|
|
|
void loop_playback(std::vector<uint16_t> &melody_steps) {
|
|
|
|
while(player.isPlaying && !player.isPaused){
|
|
|
|
// iterate through the beats and call the bell mechanism on each beat
|
|
for (uint16_t note : melody_steps) {
|
|
if (player.hardStop) return;
|
|
itsHammerTime(note);
|
|
int tempo = player.speed;
|
|
vTaskDelay(pdMS_TO_TICKS(tempo));
|
|
}
|
|
|
|
LOG_DEBUG("Single Loop Over.");
|
|
//if (!player.isPlaying) break; // Stop playback only after completing the loop
|
|
}
|
|
}
|
|
|
|
|
|
// Function to activate relays for a specific note
|
|
void itsHammerTime(uint16_t note) {
|
|
uint64_t now = millis();
|
|
|
|
for (uint8_t i = 0; i < 16; i++) {
|
|
if (note & (1 << i)) { // Check if this relay needs to activate
|
|
relays.digitalWrite(i, LOW); // Activate the relay
|
|
|
|
// Add to the activeRelays list
|
|
activeRelays.push_back({i, now, relayDurations[i]});
|
|
}
|
|
}
|
|
}
|