Files
project-vesper/bellEngine.hpp
bonamin 84534025f4 Added Separate Timings for each Relay
The setting is saved on a file in:
/settings/relayTimings.json

Then during bootup, it's read and restored. 
Settings can be set via MQTT command on Topic: 
vesoer/*dev-id*/control/settings/relayTimers
using a json format. 
{ "b1":50, b2...}
where b1 is Bell 1, b2 Bell 2, etc..
2025-01-21 11:42:23 +02:00

94 lines
2.6 KiB
C++

// MELODY PLAYBACK WILL BE HANDLED HERE
#include <vector>
extern melody_attributes melody;
// 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 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(melody.isPlaying && !melody.isPaused){
// iterate through the beats and call the bell mechanism on each beat
for (uint16_t note : melody_steps) {
if (melody.hardStop) return;
itsHammerTime(note);
int tempo = melody.speed;
vTaskDelay(pdMS_TO_TICKS(tempo));
}
Serial.println("SINGLE LOOP OVER.");
//if (!melody.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]});
}
}
}