aiuto bug con millis

ciao a tutti, sto provando ad abbozzare un codice su tinkercad ma riscontro dei problemi.
il mio scopo è:
premo un pulsante e mi attiva un led per TOT tempo e poi lo spegne (mentre questo led è acceso NON DEVE eseguire altri comandi)
premo un secondo pulsante e mi attiva un secondo led per TOT tempo e poi lo spegne (anche qui non deve fare nel mentre).

i 2 led non devono mai essere accesi insieme.
ora sto facendo dei test con un led, poi quando avrò sistemato la logica farò fare altro.

praticamente ero partito con i classici delay e funzionava, ora ho convertito a millis ed ho il problema che dopo che si è spento un led, premo l'altro e mi fa un rapido lampeggio (rimanendo poi spento), se lo ripremo funziona bene.
questo problema si manifesta solo quando cambio pulsante.
da cosa può dipendere?
grazie

int papertura = 2; //pulsante
int pchiusura = 3; //pulsante
int apertura  = 4; //led
int chiusura = 5; //led
int statoapertura;
int statochiusura;
int tempomov = 5000;
unsigned long timeoutap;
unsigned long inizioap;
unsigned long timeoutchius;
unsigned long iniziochius;

void setup()
{
  pinMode(papertura, INPUT_PULLUP);
  pinMode (pchiusura, INPUT_PULLUP);
  pinMode (apertura, OUTPUT);
  pinMode (chiusura, OUTPUT);
  digitalWrite (apertura, LOW);
  digitalWrite (chiusura, LOW);
  statoapertura = 0;
  statochiusura = 0;
}

void loop()
{
  if ((digitalRead(papertura) == LOW) and (statoapertura == 0) and (statochiusura == 0))
  {
    statoapertura = 1;
  }
  if ((digitalRead(pchiusura) == LOW) and (statochiusura == 0) and (statoapertura == 0))
  {
    statochiusura = 1;
  }

  if (statoapertura == 1)
  {
    inizioap = millis();
    digitalWrite (apertura, HIGH);
    if (((unsigned long)(inizioap)) > (timeoutap + tempomov))
    {
      digitalWrite (apertura, LOW);
      delay (1000);
      statoapertura = 0;
      timeoutap = millis();

    }
  }
  if (statochiusura == 1)
  {
    iniziochius = millis();
    digitalWrite (chiusura, HIGH);
    if (((unsigned long)(iniziochius)) > (timeoutchius + tempomov)) //tempo massimo riscaldamento
    {
      digitalWrite (chiusura, LOW);
      delay (1000);
      statochiusura = 0;
      timeoutchius = millis();
    }
  }
  delay (100);
}]

acuplush:
...(mentre questo led è acceso NON DEVE eseguire altri comandi)...

Ecco ... questo e' uno dei pochi casi in cui "delay" e' piu utile di millis ... proprio perche' mentre "aspetta", non fa assolutamente nient'altro ... :wink:

Il passo successivo è che in quel tempo dovrà inviare un segnale in radiofrequenza in continuo, quindi penso che il delay non vada bene.
Tipo io che tengo premuto un pulsante del telecomando per tutto il tempo

acuplush:
Il passo successivo è che in quel tempo dovrà inviare un segnale in radiofrequenza in continuo, quindi penso che il delay non vada bene.
Tipo io che tengo premuto un pulsante del telecomando per tutto il tempo

... perche' no ? ...

leggi il pulsante, se premuto accendi il led (e con lo stesso pin del led, piloti un transistor che attivera' il rele' con il contatto in parallelo al tuo pulsante), delay(iltempocheserve), spegni il led ... :wink:

Etemenanki:
... perche' no ? ...

leggi il pulsante, se premuto accendi il led (e con lo stesso pin del led, piloti un transistor che attivera' il rele' con il contatto in parallelo al tuo pulsante), delay(iltempocheserve), spegni il led ... :wink:

Perché la mia idea non è quella di agire su un telecomando fisico, bensì inviare il segnale tramite un trasmettitore apposito collegato ad Arduino

ho fatto qualche modifica al tuo programma e anche se compila non l'ho testato, spero funzioni :confused: e ti sia utile :slight_smile:

int papertura = 2; //pulsante
int pchiusura = 3; //pulsante
int apertura  = 4; //led
int chiusura = 5; //led
int statoapertura;
//int statochiusura;
int tempomov = 5000;
unsigned long timeoutap;
//unsigned long inizioap;
//unsigned long timeoutchius;
//unsigned long iniziochius;

void setup()
{
  pinMode(papertura, INPUT_PULLUP);
  pinMode (pchiusura, INPUT_PULLUP);
  pinMode (apertura, OUTPUT);
  pinMode (chiusura, OUTPUT);
  digitalWrite (apertura, LOW);
  digitalWrite (chiusura, LOW);
  statoapertura = 0;
  //  statochiusura = 0;
}

void loop()
{
  if ((digitalRead(papertura) == LOW) and (statoapertura == 0))
  {
    timeoutap = millis() + tempomov;
    statoapertura = 1;
    digitalWrite (apertura, HIGH);
  }
  if ((digitalRead(pchiusura) == LOW) and (statoapertura == 0))
  {
    timeoutap = millis() + tempomov;
    statoapertura = 1;
    digitalWrite (chiusura, HIGH);
  }

  if (statoapertura == 1 and millis() > timeoutap)
  {
    statoapertura = 0;
    digitalWrite (apertura, LOW);
    digitalWrite (chiusura, LOW);
  }

  delay (100);
}

-zef-:
ho fatto qualche modifica al tuo programma e anche se compila non l'ho testato, spero funzioni :confused: e ti sia utile :slight_smile:

int papertura = 2; //pulsante

int pchiusura = 3; //pulsante
int apertura  = 4; //led
int chiusura = 5; //led
int statoapertura;
//int statochiusura;
int tempomov = 5000;
unsigned long timeoutap;
//unsigned long inizioap;
//unsigned long timeoutchius;
//unsigned long iniziochius;

void setup()
{
  pinMode(papertura, INPUT_PULLUP);
  pinMode (pchiusura, INPUT_PULLUP);
  pinMode (apertura, OUTPUT);
  pinMode (chiusura, OUTPUT);
  digitalWrite (apertura, LOW);
  digitalWrite (chiusura, LOW);
  statoapertura = 0;
  //  statochiusura = 0;
}

void loop()
{
  if ((digitalRead(papertura) == LOW) and (statoapertura == 0))
  {
    timeoutap = millis() + tempomov;
    statoapertura = 1;
    digitalWrite (apertura, HIGH);
  }
  if ((digitalRead(pchiusura) == LOW) and (statoapertura == 0))
  {
    timeoutap = millis() + tempomov;
    statoapertura = 1;
    digitalWrite (chiusura, HIGH);
  }

if (statoapertura == 1 and millis() > timeoutap)
  {
    statoapertura = 0;
    digitalWrite (apertura, LOW);
    digitalWrite (chiusura, LOW);
  }

delay (100);
}

grazie per il suggerimento, mi piace anche come l'hai fatto.
così con i led funziona bene senza bug, ora vedrò di implementare il segnale in radiofrequenza

Funziona, salvo nei cinque secondi nell'intorno dell'overflow di millis() in cui i tempi risulteranno sballati (questo accadrà ogni 1193 ore circa).

Claudio_FF:
Funziona, salvo nei cinque secondi nell'intorno dell'overflow di millis() in cui i tempi risulteranno sballati (questo accadrà ogni 1193 ore circa).

e con la sfortuna che mi perseguita riuscirò a beccare quell'intervallo!!! :grinning: :grinning:

quell'intervallo lo becchi ogni 49,7 giorni se lasci acceso arduino 24h su 24h e se premi uno dei due pulsanti.... ce ne vuole di sfortuna (o fortuna) a beccarlo :slight_smile:

-zef-:
.... ce ne vuole di sfortuna (o fortuna) a beccarlo :slight_smile:

... tu sai come si dice, vero ? ...

"la fortuna e' cieca ... ma la sfortuna ha 20 decimi" ... :smiley:

@Etemenanki

vero anche quello! ;D :sweat_smile: