Go Down

Topic: Input che aziona 5 relay in sequenza e si interrompe al rilascio improvviso (Read 2746 times) previous topic - next topic

Etemenanki

... quello che vorrei accadesse quando rilascio il pulsante: la sequanza di accensione si interrompe ed uscita dal ciclo, restando in attesa che venga ripremuto il pulsante "input12". Per poi ripartire dal primo relay alla nuova pressione del pulsante.
Quindi, presumo, quando il pulsante lo rilasci i rele' si devono spegnere tutti ... inoltre, da come scrivi, i rele' si devono accendere in sequenza ma rimanere accesi tutti finche' il pulsante e' premuto, non accendo 1, aspetto un secondo, spengo1 ed accendo 2, eccetera ... giusto ?

[/quote]
... una volta acceso il 5°, non deve accadere più nulla.[/quote]

Nel senso che non si devono spegnere piu neppure se poi rilasci il pulsante, o solo nel senso che c'e' una sola sequenza di accensione, pero' se il pulsante viene rilasciato tutto deve ripartire da capo ?
"Sopravvivere" e' attualmente l'unico lusso che la maggior parte dei Cittadini italiani,
sia pure a costo di enormi sacrifici, riesce ancora a permettersi.

AlPinkish

Il funzionamento è il seguente:

permo il pulsante, accendo relay1 per 1 secondo, (e non lo spengo), proseguendo senza mai staccare il dito dal pulsante, accendo il relay2 per 1 secondo, e cosi via fino al 5. durante il processo se il pulsante resta premuto, nessuno dei relay si deve spegnere.

Implementare la funzione millis è comodo per spegnere i relay immediatamente, perchè con il delay arduino resta occupato, invece con millis, se manca il segnale input12 i relay si spengono senza attendere il secondo intero, giusto, ma come?
Homo Faber Fortunae Suae

docdoc

Il funzionamento è il seguente:
permo il pulsante, accendo relay1 per 1 secondo, (e non lo spengo), proseguendo senza mai staccare il dito dal pulsante, accendo il relay2 per 1 secondo, e cosi via fino al 5. durante il processo se il pulsante resta premuto, nessuno dei relay si deve spegnere.
Allora, una cosa per volta. Per ora prova questo codice come te l'ho modificato "al volo" (quindi non è detto sia 100% funzionante, a dovrebbe esserlo), ma dove troverai penso/spero delle cosette interessanti come consiglio di stile di programmazione.

Una volta che questo ti funziona, puoi eventualmente pensare ad usare millis() al posto dei delay().

Code: [Select]
// numero di relè
#define NUMRELE 5
// Pin di ogni relè
int pin[5] = { 3,4,5,6,7 };
// Relè attualmente attivo (-1 indica "nessun relè")
int releON = -1;
// Flag fine ciclo relè
bool fineCiclo = false;
// Pin del pulsante
#define PULSANTE 12

void setup() {
  Serial.begin(115200); //attivo comunicazione seriale
  // Inizializzazione pin dei relè e li spengo
  for (int i=0; i<NUMRELE; i++) {
    pinMode(pin[i], OUTPUT);
digitalWrite(pin[i], LOW);
  }
  // Inizializzazione pin pulsante
  pinMode(PULSANTE, INPUT);

  }

void loop() {
  // Vedo se il tasto è stato premuto
  if ( digitalRead(PULSANTE) == HIGH ) {
    if ( !fineCiclo ) {
      // Passo al successivo rele?
      // (all'inizio poiché parto da -1, il primo sarà 0)
      releON++;
      if ( releON < NUMRELE ) { // Se non ho ancora finito
        digitalWrite(pin[releON], HIGH); //accendo
        Serial.print("Relè ");
        Serial.print(releON);
        Serial.println(" acceso");
        delay(1000); // aspetto 1 secondo
      }
      else
      { // Ho finito!
        fineCiclo = true; // Segnalo che ho finito
      }
    }
  }
  else
  { // Tasto non premuto o rilasciato, resetto le variabili
    spengo();
    resetto();
  }

  funzione_esterna();

} // fine loop

void spengo() {
  for (int i=0; i<NUMRELE; i++) {
    digitalWrite(pin[i], LOW);
  }
  releON = -1;
}

void resetto() {
  fineCiclo = false;
  releON = -1;
}

void funzione_esterna(){
  if ( fineCiclo ) {
    Serial.println(" tutti i relay sono stati accesi e la nuova funzione è stata richiamata correttamente");
    //nuova funzione da preparare
  }
}

Alex "docdoc"
- "Qualsiasi cosa, prima di rompersi, funzionava"

Etemenanki

Potresti anche usare una cosa del genere, senza while e senza delay ... (pseudocodice parziale da completare, perche' se posto il programma completo, poi Guglielmo mi bacchetta :D)

Code: [Select]

definisci i pin dei rele' come 1, 2, 3, 4, 5, per comodita'
byte tempo = 0; // per sapere se il secondo e' passato
byte rele = 1; //per il ciclo for ed accendere le uscite
byte nociclo = 0; //per non ripetere inutilmente il ciclo
unsigned long prevmil = millis(); //per controllo tempo
...

setup()
...

void loop()
   {
   ...
   ... il tuo programma
   ...

   ... leggi pulsante
   if ((pulsante premuto) //se pulsante premuto controlla tempo
   {
      if ((tempo == 1) && (rele < 5)) //se tempo = 1 e rele non tutti accesi fai ciclo for
      {
         for (rele = 1; rele = 5; rele++) //ciclo variabile rele da 1 a 5
         {
            digitalWrite(rele, HIGH); //uso il valore di rele per accendere il corrispondente pin
            tempo = 0; //azzero tempo per ricontrollare quando passato un'altro secondo
            prevmil = millis(); //e resetto prevmil per lo stesso motivo
         }
      }
   }
   else //pulsante non premuto
   {
      for (rele = 1; rele = 5; rele++) digitalWrite(rele, LOW); //spengo tutti i rele
   }
   if (prevmil - millis() >= 1000) tempo = 1; //cambia valore tempo dopo un secondo
   ...
   ... resto del programma
   ...
}


Intendiamoci, e' buttato li al volo, non posso provarlo qui, non e' completo e non e' certo ottimizzato (ad esempio se il pulsante non e' premuto il ciclo che spegne i rele' continua a ripetersi, male non fa ma "spreca tempo", e si puo ottimizzare anche questo), consideralo solo come l'esempio di un possibile modo per fare la sequenza che vorresti (sempre che funzioni)
"Sopravvivere" e' attualmente l'unico lusso che la maggior parte dei Cittadini italiani,
sia pure a costo di enormi sacrifici, riesce ancora a permettersi.

AlPinkish

Allora, una cosa per volta. Per ora prova questo codice come te l'ho modificato "al volo" (quindi non è detto sia 100% funzionante, a dovrebbe esserlo), ma dove troverai penso/spero delle cosette interessanti come consiglio di stile di programmazione.

Una volta che questo ti funziona, puoi eventualmente pensare ad usare millis() al posto dei delay().

Code: [Select]
// numero di relè
#define NUMRELE 5
// Pin di ogni relè
int pin[5] = { 3,4,5,6,7 };
// Relè attualmente attivo (-1 indica "nessun relè")
int releON = -1;
// Flag fine ciclo relè
bool fineCiclo = false;
// Pin del pulsante
#define PULSANTE 12

void setup() {
  Serial.begin(115200); //attivo comunicazione seriale
  // Inizializzazione pin dei relè e li spengo
  for (int i=0; i<NUMRELE; i++) {
    pinMode(pin[i], OUTPUT);
digitalWrite(pin[i], LOW);
  }
  // Inizializzazione pin pulsante
  pinMode(PULSANTE, INPUT);

  }

void loop() {
  // Vedo se il tasto è stato premuto
  if ( digitalRead(PULSANTE) == HIGH ) {
    if ( !fineCiclo ) {
      // Passo al successivo rele?
      // (all'inizio poiché parto da -1, il primo sarà 0)
      releON++;
      if ( releON < NUMRELE ) { // Se non ho ancora finito
        digitalWrite(pin[releON], HIGH); //accendo
        Serial.print("Relè ");
        Serial.print(releON);
        Serial.println(" acceso");
        delay(1000); // aspetto 1 secondo
      }
      else
      { // Ho finito!
        fineCiclo = true; // Segnalo che ho finito
      }
    }
  }
  else
  { // Tasto non premuto o rilasciato, resetto le variabili
    spengo();
    resetto();
  }

  funzione_esterna();

} // fine loop

void spengo() {
  for (int i=0; i<NUMRELE; i++) {
    digitalWrite(pin[i], LOW);
  }
  releON = -1;
}

void resetto() {
  fineCiclo = false;
  releON = -1;
}

void funzione_esterna(){
  if ( fineCiclo ) {
    Serial.println(" tutti i relay sono stati accesi e la nuova funzione è stata richiamata correttamente");
    //nuova funzione da preparare
  }
}


Ottimo, ho capito molte migliorie, i cicli for semplificano davvero tanto.

Ho testato e funziona bene, la cosa che ho notato è che se lascio il pulsante e poi lo ripremo subito, il ciclo non si interrompe e prosegue, secondo me è proprio a causa del delay.

Ho dato un occhiata all'esempio di Etemenanki, ho capito il senso, ma per integrarlo in questo codice ho bisogno di capire bene come funziona.

una domanda mi sorge spontanea, avendo fatto tutto con il ciclo for, se  in futuro volessi aggiungere un effetto accendi-spegni per 3 volte, solo al relay 4, questo ciclo for non va più bene, giusto?
Homo Faber Fortunae Suae

docdoc

Ottimo, ho capito molte migliorie, i cicli for semplificano davvero tanto.
Bene! Ma non solo, usa i #define per cose come i pin (se fissi), ed array quando hai gruppi di oggetti dello stesso tipo, che quindi puoi gestire ed identificare con un solo indice numerico.

Quote
Ho testato e funziona bene, la cosa che ho notato è che se lascio il pulsante e poi lo ripremo subito, il ciclo non si interrompe e prosegue, secondo me è proprio a causa del delay.
Esattamente.

Quote
una domanda mi sorge spontanea, avendo fatto tutto con il ciclo for, se  in futuro volessi aggiungere un effetto accendi-spegni per 3 volte, solo al relay 4, questo ciclo for non va più bene, giusto?
Dovresti mettere una if() dentro al for, per fare qualcosa di diverso se l'indice vale 4, ad esempio:

Code: [Select]

      if ( releON < NUMRELE ) { // Se non ho ancora finito
        Serial.print("Relè ");
        Serial.print(releON);
        Serial.println(" acceso");
        if ( releON == 4 ) {
          for (int j=0; j<3; j++) {
            digitalWrite(pin[releON], HIGH); //accendo
            delay(1000); // aspetto 1 secondo
            digitalWrite(pin[releON], LOW); //spengo
          }
          digitalWrite(pin[releON], HIGH); //alla fine riaccendo
        }
        else
        {
          digitalWrite(pin[releON], HIGH); //accendo
          delay(1000); // aspetto 1 secondo
        }
      }


Ma, ripeto, io lo gestirei con dei timer (o comunque con millis) ed una macchina a stati finiti. Ma è prematuro, per ora direi prosegui a sperimentare con queste logiche.
Alex "docdoc"
- "Qualsiasi cosa, prima di rompersi, funzionava"

AlPinkish

Ma, ripeto, io lo gestirei con dei timer (o comunque con millis) ed una macchina a stati finiti. Ma è prematuro, per ora direi prosegui a sperimentare con queste logiche.
Grazie per tutti i consigli, adesso devo solo inserire i millis e poi per il momento va bene così.

Fatto questo il il thread è risolto. :D
Homo Faber Fortunae Suae

Etemenanki

... ho capito il senso, ma per integrarlo in questo codice ho bisogno di capire bene come funziona....
Sono solo un paio di cicli if nidificati, ed un for per fare la sequenza, sia di accensione (temporizata) che di spegnimento (rapida) ... unica cosa, ho messo un solo ciclo di millis esterno al ciclo perche' tanto i ritardi erano tutti uguali ... pero' ripeto, buttato giu al volo e tutto da controllare, cosa che non posso fare io qui  ...
"Sopravvivere" e' attualmente l'unico lusso che la maggior parte dei Cittadini italiani,
sia pure a costo di enormi sacrifici, riesce ancora a permettersi.

Etemenanki

... devo solo inserire i millis ...
Attenzione che non puoi semplicemente "inserire" i millis al posto dei delay ... delay e' una "funzione" che blocca tutto per il numero di millisecondi che gli passi, mentre millis si limita a restituirti un valore, sta poi a te usarlo in modo opportuno per fare quello che ti serve ... ;)
"Sopravvivere" e' attualmente l'unico lusso che la maggior parte dei Cittadini italiani,
sia pure a costo di enormi sacrifici, riesce ancora a permettersi.

docdoc

Grazie per tutti i consigli, adesso devo solo inserire i millis e poi per il momento va bene così.

Fatto questo il il thread è risolto. :D
Devi quindi mettere una variabile dove memorizzare il valore di millis() quando inizia l'evento di accensione di un relè (o direttamente millis()+1000 quindi di quando devi passare al successivo) e fare in modo che quel codice passi al successivo relè quando il pulsante è stato premuto *E* quando il tempo è passato.

Io l'ho già fatto in locale (Tinkercad..;-)) ti dò solo una "imbeccata" vedi se riesci a capire e completare lo sketch:

Code: [Select]
...
      // Passo al successivo rele?
      if ( millis() >= endTime || releON == -1) {
        // (all'inizio poiché parto da -1, il primo sarà 0)
        releON++;
        if ( releON < NUMRELE ) { // Se non ho ancora finito
          digitalWrite(pin[releON], HIGH); //accendo
          Serial.print("Relè ");
          Serial.print(releON);
          Serial.println(" acceso");
          //delay(1000); // aspetto 1 secondo
          endTime = millis() + 1000;
        }
  ...
Alex "docdoc"
- "Qualsiasi cosa, prima di rompersi, funzionava"

AlPinkish

Devi quindi mettere una variabile dove memorizzare il valore di millis() quando inizia l'evento di accensione di un relè (o direttamente millis()+1000 quindi di quando devi passare al successivo) e fare in modo che quel codice passi al successivo relè quando il pulsante è stato premuto *E* quando il tempo è passato.
Dunque ci sto provando e vedo che, sicuramente devo aggiungere long endTime;.


La condizione permette di proseguire o se i millis sono >= di endTime oppure se nessun relay è attivo, quindi,
la prima volta la condizione è soddisfatta da releON=-1, poi dopo che è stato acceso il realy1, endTime diventa  uguale a millis + 1000ms.

fin qua ci sono ed è chiaro. Ora dovrebbe rifare il ciclo considerando l'altra condizione millis() >= endTime, dove adesso i millis sono minori di 1000ms rispetto a endTime, pertanto proseguirà solo quando si verifica la condizione maggiore o uguale, e così si simula il ritardo. Ma logicamente non accade perchè manca qualcosa...

indizio?

Homo Faber Fortunae Suae

Claudio_FF

Il modo corretto di usare millis() NON è vedere se ha raggiunto tinizio+x (che funziona solo per 50 giorni poi il ritorno a zero del contatore causa problemi), ma vedere se da tinizio sono trascorsi almeno x calcolando millis()-tinizio (questo non causa mai problemi di overflow).

In pratica basta una funzione che calcoli la differenza ritornando true se è passato l'intervallo di tempo specificato:
Code: [Select]
bool timeOut(unsigned long initTime, unsigned long interval)
{
    return (millis() - initTime >= interval);
}

Ad esempio per far lampeggiare due LED in modo indipendente senza bloccare il mainloop con delay:

Code: [Select]
#define  LED1_PIN    ...
#define  LED2_PIN    ...
#define  LED1_DELAY  ...
#define  LED2_DELAY  ...
//--------------------------------------------------------------------
uint32_t led1Time = 0;
uint32_t led2Time = 0;
//--------------------------------------------------------------------
bool timeOut(uint32_t initTime, uint32_t interval) {
    return (millis() - initTime >= interval);
}
//--------------------------------------------------------------------
void setup() {
    pinMode(LED1_PIN, OUTPUT);
    pinMode(LED2_PIN, OUTPUT);
}
//--------------------------------------------------------------------
void loop()
{
    if (timeOut(led1Time, LED1_DELAY)) {
        led1Time += LED1_DELAY;
        digitalWrite(LED1_PIN, !digitalRead(LED1_PIN));
    }

    if (timeOut(led2Time, LED2_DELAY)) {
        led2Time += LED2_DELAY;
        digitalWrite(LED2_PIN, !digitalRead(LED2_PIN));
    }
}



Tra parentesi: sbaglio o il programma deve fare questo?


Le soluzioni possibili sono molte, tra cui quella di emulare direttamente il circuito a porte e timer tramite espressioni logiche. Il circuito qui sopra sono banalmente quattro timer in serie che si comportano come nel diagrammino temporale disegnato. Il codice qui sotto simula i quattro timer (l'uscita del precedente diventa l'ingresso del seguente) ed è totalmente parametrizzato, basta compilare le define in base ai collegamenti effettuati (nel resto del codice non si specificano mai esplicitamente stati legati all'hardware come LOW HIGH, quindi il suo funzionamento è indipendente dai collegamenti hardware). Si da per scontato che l'ingresso abbia un adeguato debounce hardware, altrimenti bisognerebbe aggiungere anche una funzione per il debounce sofware.

Code: [Select]
//--------------------------------------------------------------------
#define  RELEASE_STATE   ...  // Stato pulsante rilasciato
#define  RELEOFF_STATE   ...  // Stato rele' spento
#define  IN_PIN          ...
#define  RELE1_PIN       ...
#define  RELE2_PIN       ...
#define  RELE3_PIN       ...
#define  RELE4_PIN       ...
#define  RELE5_PIN       ...
#define  RELEON_STATE    !RELEOFF_STATE
#define  SEQUENCE_DELAY  1000
//--------------------------------------------------------------------
byte      T1out = 0;
uint32_t  T1time;

byte      T2out = 0;
uint32_t  T2time;

byte      T3out = 0;
uint32_t  T3time;

byte      T4out = 0;
uint32_t  T4time;
//--------------------------------------------------------------------
void timerUpdate(byte in, uint32_t *t, byte *out, uint32_t dly) {
    if (!in)  { *t = millis();  *out = 0; }
    else if (millis() - *t >= dly)  *out = 1;
}
//--------------------------------------------------------------------
void setup() {
    pinMode(IN_PIN, INPUT);
    pinMode(RELE1_PIN, OUTPUT);
    pinMode(RELE2_PIN, OUTPUT);
    pinMode(RELE3_PIN, OUTPUT);
    pinMode(RELE4_PIN, OUTPUT);
    pinMode(RELE5_PIN, OUTPUT);
}
//--------------------------------------------------------------------
void loop() {
    byte in = (digitalRead(IN_PIN) != RELEASE_STATE);

    timerUpdate(in,    &T1time, &T1out, SEQUENCE_DELAY);
    timerUpdate(T1out, &T2time, &T2out, SEQUENCE_DELAY);
    timerUpdate(T2out, &T3time, &T3out, SEQUENCE_DELAY);
    timerUpdate(T3out, &T4time, &T4out, SEQUENCE_DELAY);

    digitalWrite(RELE1_PIN, in    ? RELEON_STATE : RELEOFF_STATE);
    digitalWrite(RELE2_PIN, T1out ? RELEON_STATE : RELEOFF_STATE);
    digitalWrite(RELE3_PIN, T2out ? RELEON_STATE : RELEOFF_STATE);
    digitalWrite(RELE4_PIN, T3out ? RELEON_STATE : RELEOFF_STATE);
    digitalWrite(RELE5_PIN, T4out ? RELEON_STATE : RELEOFF_STATE);
}
********* IF e SWITCH non sono cicli ! *********
**** Una domanda ben posta è già mezza risposta ****
*** La corrente si misura in mA, la quantità di carica in mAh ***

AlPinkish

Il modo corretto di usare millis() NON è vedere se ha raggiunto tinizio+x (che funziona solo per 50 giorni poi il ritorno a zero del contatore causa problemi), ma vedere se da tinizio sono trascorsi almeno x calcolando millis()-tinizio (questo non causa mai problemi di overflow).

In pratica basta una funzione che calcoli la differenza ritornando true se è passato l'intervallo di tempo specificato:
Code: [Select]
bool timeOut(unsigned long initTime, unsigned long interval)
{
    return (millis() - initTime >= interval);
}

Ad esempio per far lampeggiare due LED in modo indipendente senza bloccare il mainloop con delay:

Code: [Select]
#define  LED1_PIN    ...
#define  LED2_PIN    ...
#define  LED1_DELAY  ...
#define  LED2_DELAY  ...

//--------------------------------------------------------------------

uint32_t led1Time = 0;
uint32_t led2Time = 0;

//--------------------------------------------------------------------

bool timeOut(uint32_t initTime, uint32_t interval)
{
    return (millis() - initTime >= interval);
}

//--------------------------------------------------------------------

void setup()
{
    pinMode(LED1_PIN, OUTPUT);
    pinMode(LED2_PIN, OUTPUT);
}

//--------------------------------------------------------------------

void loop()
{
    if (timeOut(led1Time, LED1_DELAY))
    {
        led1Time += LED1_DELAY;
        digitalWrite(LED1_PIN, !digitalRead(LED1_PIN));
    }

    if (timeOut(led2Time, LED2_DELAY))
    {
        led2Time += LED2_DELAY;
        digitalWrite(LED2_PIN, !digitalRead(LED2_PIN));
    }
}



Tra parentesi: sbaglio o il programma deve fare questo? (ok, magari c'è anche qualche porta in esubero)



Le soluzioni possibili sono molte, tra cui quella di emulare direttamente il circuito a porte e timer tramite espressioni logiche.

Diciamo che ho capito come funziona il millis(), però il problema è inserirlo qua:


Quote
Quote
Quote from: docdoc on Sep 15, 2017, 03:41 pm
Devi quindi mettere una variabile dove memorizzare il valore di millis() quando inizia l'evento di accensione di un relè (o direttamente millis()+1000 quindi di quando devi passare al successivo) e fare in modo che quel codice passi al successivo relè quando il pulsante è stato premuto *E* quando il tempo è passato.
Dunque ci sto provando e vedo che, sicuramente devo aggiungere long endTime;.


La condizione permette di proseguire o se i millis sono >= di endTime oppure se nessun relay è attivo, quindi,
la prima volta la condizione è soddisfatta da releON=-1, poi dopo che è stato acceso il realy1, endTime diventa  uguale a millis + 1000ms.

fin qua ci sono ed è chiaro. Ora dovrebbe rifare il ciclo considerando l'altra condizione millis() >= endTime, dove adesso i millis sono minori di 1000ms rispetto a endTime, pertanto proseguirà solo quando si verifica la condizione maggiore o uguale, e così si simula il ritardo. Ma logicamente non accade perchè manca qualcosa...

indizio?
Code: [Select]
...
      // Passo al successivo rele?
      if ( millis() >= endTime || releON == -1) {
        // (all'inizio poiché parto da -1, il primo sarà 0)
        releON++;
        if ( releON < NUMRELE ) { // Se non ho ancora finito
          digitalWrite(pin[releON], HIGH); //accendo
          Serial.print("Relè ");
          Serial.print(releON);
          Serial.println(" acceso");
          //delay(1000); // aspetto 1 secondo
          endTime = millis() + 1000;
        }
  ...


Lo sketch era quasi finito e mi basta capire come concluderlo
Homo Faber Fortunae Suae

Claudio_FF

Quote from: AlPinkish
Diciamo che ho capito come funziona il millis()
Code: [Select]
millis() >= endTime
Come detto nel post precedente, questa condizione va in errore dopo 50 giorni.
Se va bene sballa i tempi per un secondo, se va male blocca per altri 50 giorni (o per sempre, se ne sta parlando anche qui).

Quote
condizione maggiore o uguale, e così si simula il ritardo. Ma logicamente non accade perchè manca qualcosa...
indizio?
L'errore si trova al di fuori di quel pezzo di codice.
********* IF e SWITCH non sono cicli ! *********
**** Una domanda ben posta è già mezza risposta ****
*** La corrente si misura in mA, la quantità di carica in mAh ***

Puso

Provo a spiegarlo io il millis() siccome sono neofita e spiegazioni ne ho sentite tante e sono ancora lontano dall'averle stampate nella zucca....in pratica è come accendere il forno e metterci dentro una torta, ora se la torta ci mette 45minuti a cuocere, punto la campanella del forno da 0 a 45 minuti, cosi suona e levo la torta.

Ora però se nello stesso forno ci voglio mettere anche i biscotti che ci mettono solo 5 minuti a cuocere e li metto dentro mettiamo dopo mezzora della torta, mi serve un altra campanella che metterò a 5minuti,ma non da 0,bensi da quando o messo la torta nel forno,quindi da mezz'ora che è gia trascora punterò i 5minuti.

Attento a non cadere nelle sbaglio che ho fatto io ultimamente di azzerare il forno"MILLIS()" perche magari la torta esce buona,ma i biscotti o escono crudi oppure bruciati.

Quindi da come l'ho capita io per i tuoi rele è sufficente che accendi il forno e punti il timer a suonare NON una volta sola  ma OGNI tot tempo che decidi ed ogni volta che suona cambi semplicemente  pin.

Go Up