Salve, ho creato un codice con i delay e mi funziona. Ora mi è venuto in mente di aggiungere un'altra funzione ma i delay non vanno più bene perchè bloccano l'esecuzione del codice. Il pezzo di codice in questione è questo:
void controllo_automatico() {
stampa_testo(0,0,"Tensione Assente ");
delay(2000); // Aspetta 2 secondi
digitalWrite(pin_start,1); // Attiva il relè per aprire
stampa_testo(0,0,"Apre cancello ");
delay(500); // Aspetta mezzo secondo
digitalWrite(pin_start,0); // Spegne il relè per aprire
delay(30000); // Aspetta 30 secondi
digitalWrite(pin_stop,1); // Attiva il relè per lo stop
stampa_testo(0,0,"Cancello fermo ");
controllo = 1; // Questa variabile viene posta a 1 per indicare che la tensione è mancata
}
Come si può trasformare il tutto con millis()?
Con un delay riesco a farlo ma qui ce ne son troppi in sequenza.
void setup() {
// put your setup code here, to run once:
controllo_automatico(true);
}
void loop() {
// put your main code here, to run repeatedly:
controllo_automatico(false);
}
void controllo_automatico(bool start) {
static uint32_t lastTime = millis();
static uint8_t state = 0;
if (start == true) state = 1;
switch (state) {
case 0:
break;
case 1:
lastTime = millis();
stampa_testo(0, 0, "Tensione Assente ");
state = 2;
break;
case 2: // Aspetta 2 secondi
if (millis() - lastTime >= 2000) state = 3;
break;
case 3:
digitalWrite(pin_start, 1); // Attiva il relè per aprire
stampa_testo(0, 0, "Apre cancello ");
lastTime = millis();
state = 4;
break;
case 4: // Aspetta mezzo secondo
if (millis() - lastTime >= 500) state = 5;
break;
case 5:
digitalWrite(pin_start, 0); // Spegne il relè per aprire
lastTime = millis();
state = 6;
break;
case 6: // Aspetta 30 secondi
if (millis() - lastTime >= 30000) state = 7;
break;
case 7:
digitalWrite(pin_stop, 1); // Attiva il relè per lo stop
stampa_testo(0, 0, "Cancello fermo ");
controllo = 1; // Questa variabile viene posta a 1 per indicare che la tensione è mancata
state = 0; // go idle
start = false;
break;
}
}
Grazie per l'aiuto, avevo iniziato a scrivere qualcosa di simile ma utilizzando gli if e una variabile step per indicare la successione, sicuramente il tuo sistema è più leggibile. Ho notato un errore, all'inizio della funzione controllo_automatico, hai messo state=0. Se chuiamo la funzione con true, viene stampato il messaggio: Tensione assente, esce dal case, va nel loop e torna a chiamare la funzione controllo_automatico, mi mette la variabile state=0 e quindi mi stampa di nuovo: Tensione assente, esce dal case va nel loop e rifà sempre questo all'infinito. L'idea è buona, la devo modificare per farla funzionare.
@anon57585045: Buongiorno, come forse avrai letto, la sezione Italiana del forum ha un suo REGOLAMENTO (che ti chiediamo gentilmente di leggere) e richiede che, cortesemente, se non l'hai già fatta, tu faccia la tua presentazione NELL'APPOSITA DISCUSSIONE spiegando bene quali esperienze hai in elettronica e programmazione, affinché noi possiamo conoscere la tua esperienza ed esprimerci con termini adeguati.
Un altra cosa, qui nella sezione Italiana, NON scriviamo l'intero codice agli utenti (NON diamo la "pappa fatta"), ma cerchiamo di spiegargli cosa devono fare in modo che siano loro a farlo ... in merito il punto 16.13 del succitato regolamento spiega bene le motivazioni. Tiello presente per il futuro
Non ho chiesto di darmi il codice ma come si poteva trasformare in millis(), mi basta l'idea. Infatti ho scritto che avevo iniziato a scrivere un codice simile ma con gli if. Comunque ho risolto i problemi presente nel codice di aarg.
bool no_tensione=0;
bool controllo=0;
byte state=1;
uint32_t lastTime = millis();
void setup(){
}
void loop(){
no_tensione = digitalRead(4);
if (no_tensione == 0 && controllo == 0) controllo_automatico();
}
void controllo_automatico() {
switch (state) {
case 1:
lastTime = millis();
stampa_testo(0, 0, "Tensione Assente ");
state = 2;
break;
case 2: // Aspetta 2 secondi
if (millis() - lastTime >= 2000) state = 3;
break;
case 3:
digitalWrite(pin_start, 1); // Attiva il relè per aprire
stampa_testo(0, 0, "Apre cancello ");
lastTime = millis();
state = 4;
break;
case 4: // Aspetta mezzo secondo
if (millis() - lastTime >= 500) state = 5;
break;
case 5:
digitalWrite(pin_start, 0); // Spegne il relè per aprire
lastTime = millis();
state = 6;
break;
case 6: // Aspetta 30 secondi
if (millis() - lastTime >= 3000) state = 7;
break;
case 7:
digitalWrite(pin_stop, 1); // Attiva il relè per lo stop
stampa_testo(0, 0, "Cancello fermo ");
controllo = 1; // Questa variabile viene posta a 1 per indicare che la tensione è mancata
state = 1; // go idle
break;
}
}