/*
Logica slave sequenziale in catena:
- Aspetta rising edge stabile dal master (o dal precedente slave)
- Se master va LOW in qualsiasi momento → ABORT immediato, output LOW (blocca catena a valle)
- Esegue PHASE1 → PHASE2 solo se master resta HIGH
- Output resta LOW durante IDLE / PHASE1 / PHASE2
- Solo al termine corretto delle fasi → DONE + output HIGH permanente
(attiva il successivo slave nella catena)
- In DONE diventa ripetitore passivo HIGH (finché master resta HIGH)
*/
constexpr uint8_t PIN_MASTER_SIGNAL = 2;
constexpr uint8_t PIN_END_SIGNAL = A0;
constexpr uint8_t PIN_ACTIVE_LED = 13;
constexpr uint32_t DEBOUNCE_MS = 300;
enum class SlaveState : uint8_t {
IDLE, // in attesa di rising edge sul master input
PHASE1, // fase 1 in corso
PHASE2, // fase 2 in corso
DONE, // completato con successo → output HIGH permanente (finché master HIGH)
ABORT // interrotto da master LOW → output LOW
};
struct Slave {
SlaveState state = SlaveState::IDLE;
uint32_t phaseStart = 0;
} slave;
bool phase1(uint32_t now) {
// ── Codice reale della fase 1 qui ──
// Esempio:
uint32_t elapsed = now - slave.phaseStart;
if (elapsed >= 5000) return true;
digitalWrite(PIN_ACTIVE_LED, (elapsed / 500) % 2);
return false;
}
bool phase2(uint32_t now) {
// ── Codice reale della fase 2 qui ──
// Esempio:
uint32_t elapsed = now - slave.phaseStart;
if (elapsed >= 7000) return true;
digitalWrite(PIN_ACTIVE_LED, (elapsed / 200) % 2);
return false;
}
void setup() {
pinMode(PIN_MASTER_SIGNAL, INPUT);
pinMode(PIN_END_SIGNAL, OUTPUT);
pinMode(PIN_ACTIVE_LED, OUTPUT);
digitalWrite(PIN_END_SIGNAL, LOW);
digitalWrite(PIN_ACTIVE_LED, LOW);
}
void loop() {
uint32_t now = millis();
bool master = digitalRead(PIN_MASTER_SIGNAL);
// Master LOW → abort immediato
if (!master) {
if (slave.state != SlaveState::ABORT &&
slave.state != SlaveState::IDLE) {
slave.state = SlaveState::ABORT;
digitalWrite(PIN_ACTIVE_LED, LOW);
}
digitalWrite(PIN_END_SIGNAL, LOW);
return;
}
// Macchina a stati
switch (slave.state) {
case SlaveState::IDLE: {
static bool prev = LOW;
static uint32_t riseTime = 0;
if (master && !prev) {
riseTime = now;
}
prev = master;
if (master && (now - riseTime >= DEBOUNCE_MS)) {
slave.state = SlaveState::PHASE1;
slave.phaseStart = now;
digitalWrite(PIN_ACTIVE_LED, HIGH);
// NOTA BENE: END_SIGNAL resta LOW → prossimo slave non parte ancora
}
break;
}
case SlaveState::PHASE1:
if (phase1(now)) {
slave.state = SlaveState::PHASE2;
slave.phaseStart = now;
}
// END_SIGNAL resta LOW
break;
case SlaveState::PHASE2:
if (phase2(now)) {
digitalWrite(PIN_ACTIVE_LED, LOW);
slave.state = SlaveState::DONE;
digitalWrite(PIN_END_SIGNAL, HIGH); // attiva il successivo in catena
}
// END_SIGNAL resta LOW fino a completamento
break;
case SlaveState::DONE:
// Ripetitore passivo del master
static uint32_t lastStableHigh = 0;
if (master) {
lastStableHigh = now;
digitalWrite(PIN_END_SIGNAL, HIGH);
} else {
if (now - lastStableHigh >= DEBOUNCE_MS) {
digitalWrite(PIN_END_SIGNAL, LOW);
}
}
break;
case SlaveState::ABORT:
digitalWrite(PIN_END_SIGNAL, LOW);
digitalWrite(PIN_ACTIVE_LED, LOW);
break;
}
}MASTER_SIGNAL
END_SIGNAL