Temporizzazione variabile ledState

Salve a tutti, avrei la necessità di avere una certa logica da questo listato ma non so come fare, attualmente se premo il pulsante la variazione di stato tra i due led è immediata invece a me serve che alla pressione del pulsante il led che era acceso lo spegne immediatamente e dopo 500mS mi accende il led che era spento, come posso fare? ecco il listato

  #define ledPin230 15 
  #define ledPin110 16 
  #define puls110e230 18 

  int ledState3 = HIGH;
  int ledState4 = LOW;
  int buttonState3;
  int lastButtonState3 = HIGH;
  long lastDebounceTime3 = 0;
  long debounceDelay3 = 50;

void setup() {

  pinMode (ledPin230, OUTPUT);
  pinMode (ledPin110, OUTPUT);
  pinMode (puls110e230, INPUT);
  digitalWrite (ledPin230, HIGH);
  digitalWrite (ledPin110, LOW);

}

void loop() {

    int reading3 = digitalRead(puls110e230);
      if (reading3 != lastButtonState3) {
        lastDebounceTime3 = millis();
      }
        if ((millis() - lastDebounceTime3) > debounceDelay3) {
          if (reading3 != buttonState3) {
            buttonState3 = reading3;
              if (buttonState3 == HIGH) {
                  ledState3 = !ledState3;
                  ledState4 = !ledState4;                  
                }
              }
            }                               
            digitalWrite (ledPin230, ledState3);
            digitalWrite (ledPin110, ledState4); 
            lastButtonState3 = reading3;

}

Così può andare? Una variabile 'attesa' per abilitare la riaccensione dopo tot millisecondi.

908345789.png

sinceramente non capisco benissimo quello che il diagramma propone, potresti spiegarmelo? grazie mille della disponibilità

ho provato così ma non va

#define ledPin230 15 
  #define ledPin110 16 
  #define puls110e230 18 

  int ledState3 = HIGH;
  int ledState4 = LOW;
  int buttonState3;
  int lastButtonState3 = HIGH;
  long lastDebounceTime3 = 0;
  long debounceDelay3 = 50;
  unsigned long t0 = 0;
  int dt = 0;
  int prox = LOW;
  int attesa = 0;

void setup() {

  pinMode (ledPin230, OUTPUT);
  pinMode (ledPin110, OUTPUT);
  pinMode (puls110e230, INPUT);
  digitalWrite (ledPin230, HIGH);
  digitalWrite (ledPin110, LOW);
  t0 = millis();

}

void loop() {

    int reading3 = digitalRead(puls110e230);
      if (reading3 != lastButtonState3) {
        lastDebounceTime3 = millis();
      }
        if ((millis() - lastDebounceTime3) > debounceDelay3) {
          if (reading3 != buttonState3) {
            buttonState3 = reading3;
              if (buttonState3 == HIGH) {
                prox = !prox;
                ledState3 = !ledState3;
                ledState4 = !ledState4;
                dt = millis() - t0;
                attesa = 1;
              } else 
              if (attesa == 1 and dt >= 500) {
              attesa = 0;
              t0 = millis();
              prox;
                ledState3 = !ledState3;
                ledState4 = !ledState4;                
              }
            }
          }                               
            digitalWrite (ledPin230, ledState3);
            digitalWrite (ledPin110, ledState4); 
            lastButtonState3 = reading3;

}

Allora ho fatto un'altra prova e funziona a metà cioè, all'inizio ledState3 è HIGH e ledState4 è LOW, alla pressione del pulsante ledState3 diventa subito LOW mentre ledState4 diventa HIGH dopo 500mS e fin qui è la logica che mi serve solo che, se schiaccio il pulsante per ritornare nella posizione iniziale tutti e due i ledState si mettono HIGH per poi passare solo HIGH il ledState3 e diventando LOW ledState4 e questo non va bene, in pratica ho spostato:

digitalWrite (ledPin230, ledState3);
digitalWrite (ledPin110, ledState4);

aggiungendoci un delay ecco la parte loop modificata

void loop() {

    int reading3 = digitalRead(puls110e230);
      if (reading3 != lastButtonState3) {
        lastDebounceTime3 = millis();
      }
        if ((millis() - lastDebounceTime3) > debounceDelay3) {
          if (reading3 != buttonState3) {
            buttonState3 = reading3;
              if (buttonState3 == HIGH) {
                ledState3 = !ledState3;
                ledState4 = !ledState4;      
                  digitalWrite (ledPin230, ledState3);
                    delay (500);
                  digitalWrite (ledPin110, ledState4);          
                }
              }
            }                               
            
              lastButtonState3 = reading3;

}

ora come posso ovviare a questo malfunzionamento?

ho provato anche così ma niente, in questo caso funziona sempre nel primo passaggio con la variante che alla seconda pigiata del pulsante la variazione di stato è immediata senza che i due led risultino entrambi accesi, però in quest'ultima versione come logica penso che ci sono, o no? Se è no mi potete spiegare perchè non funziona?

void loop() {

    int reading3 = digitalRead(puls110e230);
      if (reading3 != lastButtonState3) {
        lastDebounceTime3 = millis();
      }
        if ((millis() - lastDebounceTime3) > debounceDelay3) {
          if (reading3 != buttonState3) {
            buttonState3 = reading3;
              if (buttonState3 == HIGH) {
                ledState3 = !ledState3;
                ledState4 = !ledState4; 
    if (ledState3 == HIGH) {
      delay (500);
      digitalWrite (ledPin230, HIGH);
    } 
    if (ledState3 == LOW) {
      digitalWrite (ledPin230, LOW);
    }

    if (ledState4 == HIGH) {
      delay (500);
      digitalWrite (ledPin110, HIGH);
    } 
    if (ledState4 == LOW) {
      digitalWrite (ledPin110, LOW);
    }              
                }
              }
            }                               
              lastButtonState3 = reading3;
    
}

Per cortesia prima di postare il codice usa CTRL-t che formatta il codice in modo (standard) da essere più leggibile. Grazie.

Ciao.

ecco il codice di partenza formattato

#define ledPin230 15
#define ledPin110 16
#define puls110e230 18

int ledState3 = HIGH;
int ledState4 = LOW;
int buttonState3;
int lastButtonState3 = HIGH;
long lastDebounceTime3 = 0;
long debounceDelay3 = 50;

void setup() {

  pinMode (ledPin230, OUTPUT);
  pinMode (ledPin110, OUTPUT);
  pinMode (puls110e230, INPUT);
  digitalWrite (ledPin230, HIGH);
  digitalWrite (ledPin110, LOW);

}

void loop() {

  int reading3 = digitalRead(puls110e230);
  if (reading3 != lastButtonState3) {
    lastDebounceTime3 = millis();
  }
  if ((millis() - lastDebounceTime3) > debounceDelay3) {
    if (reading3 != buttonState3) {
      buttonState3 = reading3;
      if (buttonState3 == HIGH) {
        ledState3 = !ledState3;
        ledState4 = !ledState4;
      }
    }
  }
  digitalWrite (ledPin230, ledState3);
  digitalWrite (ledPin110, ledState4);
  lastButtonState3 = reading3;

}

Questa è parte del tuo codice riformattata per essere più leggibile:

if (buttonState3 == HIGH) 
{
    ledState3 = !ledState3;
    ledState4 = !ledState4;
    if (ledState3 == HIGH) { delay (500);  digitalWrite (ledPin230, HIGH); }
    if (ledState3 == LOW)  {               digitalWrite (ledPin230, LOW);  }
    if (ledState4 == HIGH) { delay (500);  digitalWrite (ledPin110, HIGH); }
    if (ledState4 == LOW)  {               digitalWrite (ledPin110, LOW);  }
}

Il problema è che nel caso di ledState3 == HIGH accendi ledPin230 dopo 500ms, ma nel frattempo non hai ancora spento ledPin110. Basta spegnere prima: spengo tutto → attendo → accendo.

perfetto adesso così funziona

if (buttonState3 == HIGH) {
        ledState3 = !ledState3;
        ledState4 = !ledState4;
        if (ledState3 == HIGH) {
          digitalWrite (ledPin230, LOW);
          digitalWrite (ledPin110, LOW);
          delay (500);
          digitalWrite (ledPin230, HIGH);
        }
        if (ledState3 == LOW) {
          digitalWrite (ledPin230, LOW);
        }
        if (ledState4 == HIGH) {
          digitalWrite (ledPin230, LOW);
          digitalWrite (ledPin110, LOW);
          delay (500);
          digitalWrite (ledPin110, HIGH);
        }
        if (ledState4 == LOW) {
          digitalWrite (ledPin110, LOW);
        }

grazie mille per i vostri preziosi aiuti

Perché complicarsi così la vita? È molto più semplice seguire pari pari la procedura espressa in italiano, le istruzioni devono seguire l'idea, non il contrario:

if (buttonState3 == HIGH)   // se fronte di pressione
{
    // inverto
    ledState3 = !ledState3;
    ledState4 = !ledState4;

    // spengo tutto
    digitalWrite(ledPin230, LOW);
    digitalWrite(ledPin110, LOW);

    // attendo
    delay(500);

    // accendo
    digitalWrite(ledPin230, ledState3);
    digitalWrite(ledPin110, ledState4);
}

hai ragione grazie mille del consiglio

scusami Claudio_FF, ho una variabile che se risulta essere 1 mi deve forzare a HIGH per esempio ledPin230 sempre dopo 500mS e se la variabile torna a 0 mi fa ritornare al led acceso prima sempre dopo 500mS, come si può fare?

RoccoStragapede: come si può fare?

La frase "mi fa ritornare al led acceso prima" non la capisco.

Un po'di post addietro si parlava di macchine a stati, che sono il modo più comodo per apportare modifiche e realizzare processi temporizzati che tengono conto di molti eventi contemporaneamente. Ogni altra via è un bagno di sangue (tranne nel caso in cui il programma deve fare una e una sola cosa alla volta).

In ogni caso tra quello che si vuole fare e le istruzioni ci va la logica intermedia, le istruzioni servono in un secondo momento per codificare in un linguaggio specifico la logica intermedia.

Quello che vuoi fare prova a disegnarlo prima con diagrammi di flusso, e solo quando il diagramma "funziona" allora passa alla codifica in istruzioni.

Con quella frase intendevo che se ho acceso ledPin110 è la variabile va a 1 mi forza ad alto ledPin230 dopo 500mS, ma se la variabile torna a 0 mi riaccende ledPin110 sempre dopo 500mS

ho visto qualche video sulle macchine a stati, uno fra tutti quello di Paolo Aliverti, ma non riesco a capire come applicarlo al mio progetto........

allora ho fatto una macchina a stati e il risultato mi soddisfa a metà, cioè: come logica di funzionamento ora ci siamo e questo è il listato

  switch (stato1) {
    case 0:
      loop0();
      break;
    case 1:
      loop1();
      break;
  }
}

void loop0() {

  if (cont2 == 0) {
    stato1 = 1;
    digitalWrite (ledPin110, LOW);
    delay (500);
    digitalWrite (ledPin230, HIGH);
  }
}

void loop1() {

  if (cont2 == 1 or cont2 == 2 or cont2 == 3) {
    stato1 = 0;
    digitalWrite (ledPin230, LOW);
    digitalWrite (ledPin110, LOW);
    delay(500);
    digitalWrite (ledPin230, ledState3);
    digitalWrite (ledPin110, ledState4);
  }
}

solo che mi sono accorto che mettendo i delay quando schiaccio un pulsante per far avanzare una variabile chiamata cont2 (facente parte di un array) nella posizione cont2 == 0 verso la posizione cont2 == 1 deve aspettare i 500mS della pausa tra lo spegnimento e l'accensione, quindi ho usato la funzione millis ma con pessimi risultati e questo è il listato

switch (stato1) {
    case 0:
      loop0();
      break;
    case 1:
      loop1();
      break;
  }
}

void loop0() {

  if (cont2 == 0) {
    stato1 = 1;
    digitalWrite (ledPin110, LOW);
    dt4 = millis() - t4;
    if (dt4 >= 500) {
      digitalWrite (ledPin230, HIGH);
      t4 = millis();
    }
  }
}

void loop1() {

  if (cont2 == 1 or cont2 == 2 or cont2 == 3) {
    stato1 = 0;
    digitalWrite (ledPin230, LOW);
    digitalWrite (ledPin110, LOW);
    dt5 = millis() - t5;
    if (dt5 >= 500) {
      digitalWrite (ledPin230, ledState3);
      digitalWrite (ledPin110, ledState4);
      t5 = millis();
    }
  }
}

in pratica il sistema usando millis non mi fa passare i 500mS tra lo spegnimento e l'accensione sostanzialmente il passaggio di stato è immediato, mi dareste una mano a trovare gli errori?

Dalla descrizione in italiano risulta che servono quattro stati, cioè ci sono quattro diverse situazioni di attesa in cui ti puoi trovare:

  • Attesa prima condizione
  • Rilevata prima condizione e attesa primo timeout
  • Attesa seconda condizione
  • Rilevata seconda condizione e attesa secondo timeout

Quindi ti mancano due stati, e l'inghippo sui tempi deriva dall'impostazione errata dei momenti iniziali da cui calcolare il tempo trascorso (le tue variabili 't4' e 't5'):

Stato0: 
  Se cont2==0:
      spengo led
      salvo tempo iniziale
      stato=1

Stato1:
  Se trascorsi 500ms:
      accendo led
      stato=2

Stato2: 
  Se cont2  1 o 2 o 3:
      spengo led
      salvo tempo iniziale
      stato=3

Stato3:
  Se trascorsi 500ms:
      accendo led
      stato=0

Ogni stato di questo esempio è una semplice frase: se sono in questo stato, e avviene questo, faccio quest'altro. Ogni processo può essere descritto da una serie di frasi in questa forma, che funzionano su carta, e si traducono praticamente uno a uno in istruzioni.

Claudio_FF: e l'inghippo sui tempi deriva dall'impostazione errata dei momenti iniziali da cui calcolare il tempo trascorso (le tue variabili 't4' e 't5'):

a cosa ti stai riferendo?

Calcoli i delta t con:

dt4 = millis() - t4;

dt5 = millis() - t5;

Ma t4 e t5 dovrebbero contenere il valore che ha millis nel momento da cui vuoi misurare il trascorrere del tempo.