// MELODY PLAYBACK WILL BE HANDLED HERE #include 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 activeRelays; void loop_playback(std::vector &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 &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]}); } } }