doppio ritardo una uscita

Salve a tutti, vi chiedo aiuto perchè non riesco a capire come fare per avere due tempi che comandano una sola uscita.
Ovvero:
da un rele esterno, attivo un pin in ingresso
quindi attivo un pin in uscita e faccio passare un tempo e poi disattivo il pin in uscita
quando il rele esterno disattiva il pin in ingresso
attivo ancora il pin precedente, faccio passare un altro tempo, e poi disattivo il pin

forse sarà semplice ma mi incarto, e non capisco come poter procedere

vi ringrazio in anticipo

Ma cosa succede se lo stato del pin di ingresso cambia la condizione logica mentre il pin di uscita non ha completato il ritardo previsto?

in teoria ci dovrebbe essere una ripetizione di uno dei due cicli

oppure si potrebbe mettere un interblocco,in modo che fino a che non finisce un ciclo non si possa abilitare l'altro

grazie

kemosabesay:
in teoria [...] oppure si potrebbe

No in teoria... >:( mica ce lo dobbiamo inventare noi.... questa DEVE essere una precisa specifica funzionale ben esplicita da decidere in partenza, e in base alla decisione si imposta la logica che la realizza.

Cioè prima decidi esattamente cosa deve essere fatto, come deve comportarsi il sistema in ogni situazione, poi questa descrizione "verbale" la formalizzi in modo logico (pseudocodice, diagramma di flusso, diagramma di stato, diagramma temporale ecc a seconda di come è più comodo), e alla fine basta solo tradurre quella logica in istruzioni (che salvo errori sintattici/semantici funzioneranno al primo colpo).

Il passaggio che vedo mancare quasi sempre è la fase prima della scrittura delle istruzioni, e il 99% dei problemi si analizzano e risolvono li :wink:

In particolare hai già descritto bene i passaggi di come deve funzionare secondo la sequenza temporale corretta di eventi, manca appunto sapere cosa deve succedere se il relé stacca prima del primo scadere del tempo, e magari anche cosa deve succedere se riattacca prima dello scadere del secondo (sempre che siano eventualità possibili naturalmente).

Completa i seguenti diagrammi temporali :slight_smile:

rele2tempi.png

rele2tempi.png

L'uscita si deve attivare per un certo tempo sia sul fronte di salita che su quello di discesa dell'ingresso?
Durante il tempo in cui l'uscita è attiva deve essere ignorata qualunque cosa accada all'ingresso?

vi dicevo che non è importante cosa succede se il rele di ingresso scambia in tra un ciclo o l'altro, perchè l'uscita di arduino comanda solo dei led di segnalazione e un cicalino.
comunque per correttezza logica potrei dire che si possa creare un interblocco sull'ingresso, in modo che fino a che non finisce un ciclo non ne possa cominciare un'altro.

grazie

sto facendo una prova sul pin 2 di ingresso e il pin 13 ( led) di uscita con questo

int ledPin = 13; // choose the pin for the LED
int inPin = 2;   // choose the input pin (for a pushbutton)
int val = 0;     // variable for reading the pin status

void setup() {
  pinMode(ledPin, OUTPUT);  // declare LED as output
  pinMode(inPin, INPUT);    // declare pushbutton as input
}

void loop(){
  val = digitalRead(inPin);  // read input value
  if (val == LOW) {         // check if the input is HIGH (button released)
    digitalWrite(ledPin, LOW);  // turn LED OFF
  } else {
    digitalWrite(ledPin, HIGH);  // turn LED ON
  }
}

e sto vedendo che appena metto a positivo il pin 2 il 13 si accende, ma quando tolgo tensione al 2 il 13 ci mette quasi un secondo a spegnersi.

secondo voi come mai non si spegne subito?

grazie

Perché non hai messo all'ingresso una resistenza verso massa

kemosabesay:
vi dicevo che non è importante cosa succede se il rele di ingresso scambia in tra un ciclo o l'altro, perchè l'uscita di arduino comanda solo dei led di segnalazione e un cicalino.

Il problema non è questo, è che bisogna scrivere qualcosa1 che faccia qualcosa2, e se qualcosa2 non è ben chiaro e definito in tutti i suoi termini, allora si finisce per scrivere qualcosa1 che non fa quello che si vorrebbe, ad esempio restano indicatori o cicalini accesi, o non si accendono più ecc ecc ecc.

comunque per correttezza logica potrei dire che si possa creare un interblocco sull'ingresso, in modo che fino a che non finisce un ciclo non ne possa cominciare un'altro.

Definire "ciclo". Cosa succede se il relé da un solo impulso più breve di T1? Viene eseguito di seguito anche T2? Oppure viene eseguito solo T1? E se durante T2 il relé riparte, c'è da eseguire un altro ciclo mentre il precedente non è ancora finito? Come vedi non basta dire "facciamo solo un ciclo", BISOGNA dire (perché poi lo si deve dire alla macchina) esattamente quello che va fatto. In mancanza di questa chiarezza logica personalmente non sono in grado neppure di ipotizzare una procedura valida.

grazie Datman. non ci avevo pensato.....

definizione Ciclo:
arriva tensione sul pin di input e si eccita l'uscita dopo un tempo T1 l'uscita si diseccita
nel caso in cui la tensione sul pin in ingresso invece che rimanere costante, venga tolta prima dello scadere di T1,
viene eseguito T2.

se durante T2 viene a mancare tensione all'ingresso viene eseguito T1

grazie Claudio..anche per le lezioni di logica!

Potresti semplicemente rilevare il passaggio a livello alto, attivare l'uscita e poi, con un delay, disattivarla.
Quando va a livello basso, fai la stessa cosa con un altro tempo.

In questo modo, ovviamente, mentre l'uscita è attiva ignora l'ingresso, anche il ritorno allo stato di riposo.
In alternativa, devi usare millis().

comincio a scrivere qualcosa con il delay poi se funge vediamo perfezionarlo con il delay

grazie ti faccio sapere appena pronto

sono arrivato a questo che sembra funzioni.....

grazie

int led=9;
int inpin=2;
// the setup function runs once when you press reset or power the board
bool state=false;
bool cons=true;
void setup() {
  // initialize digital pin LED_BUILTIN as an output.
  pinMode(led, OUTPUT);
}

// the loop function runs over and over again forever
void loop() {
 if (digitalRead(inpin) == HIGH  && !state && cons) { 
  digitalWrite(led, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(3000);                       // wait for a second
  digitalWrite(led, LOW);    // turn the LED off by making the voltage LOW
  state=true;
  cons=false;
  }
else if (digitalRead(inpin) == LOW  && state && !cons){
  digitalWrite(led, HIGH);
  
  delay(5000);                       // wait for a second
  digitalWrite(led, LOW);    // turn the LED off by making the voltage LOW
  state=false;
  cons=true;
}
}

A che cosa serve cons, visto che è sempre l'opposto dello stato?...

const byte LED=9;
const byte INPIN=2;
bool state=false;

void setup()
{
  pinMode(LED, OUTPUT);
}

void loop() 
{
if (digitalRead(INPIN) && !state) 
  { 
  state=true;
  digitalWrite(led, HIGH); // LED on
  delay(3000); 
  digitalWrite(led, LOW);  // LED off
  }
else if (!digitalRead(INPIN) && state)
  {
  state=false;
  digitalWrite(LED, HIGH);
  delay(5000);
  digitalWrite(LED, LOW);    // LED off
  }
}
  • Solitamente le costanti sono scritte MAIUSCOLE.
  • const dichiara che sono costanti: verranno trattate adeguatamente, più o meno come se fossero #define.
  • if(x) è uguale a if(x!=0).
  • una variabile bool occupa comunque 1 byte, poiché non vengono fatte operazioni per allocarne 8 insieme.

ok grazie
adesso provo a inserire i millis

grazie

brutte notizie, purtroppo non riesco a capire come inserire il millis...
ho scritto questo ma non funge, nel senso che il tempo parte dopo che rilascio il pulsante
cosa non capisco????

grazie

const byte LED=9;
const byte INPIN=2;
bool STATE=false;
unsigned long previousMillis = 0; 
unsigned long previousMillis1 = 0;  
const long interval = 2000;
const long interval1 = 2000;
bool led1On = true;
int STATE_LED=LOW;
void setup()
{
  pinMode(LED, OUTPUT);
  pinMode(INPIN,INPUT);
}

void loop()
{
  unsigned long currentMillis = millis();
if (digitalRead(INPIN) )
  {
    STATE_LED=HIGH;
    previousMillis = currentMillis;
  }
if ( currentMillis - previousMillis >= interval ) 
   {
   STATE_LED=LOW;
   }
   digitalWrite(LED,STATE_LED);
}

Finché tieni il pulsante premuto, ad ogni giro di loop (cioè migliaia di volte al secondo) la condizione if(digitalRead(INPIN)) è sempre vera, quindi viene sempre eseguita, quindi il valore di previousMillis continua ad essere caricato con il nuovo valore di currentMillis. Solo quando rilasci il pulsante allora la condizione non è più vera, e il valore di previousMillis rimane fisso diventando il momento da cui inizia a misurare il tempo.

const byte LED=9;
const byte INPIN=2;
bool STATE=false;
unsigned long previousMillis = 0;
unsigned long previousMillis1 = 0; 
const long interval = 2000;
const long interval1 = 2000;
bool led1On = true;   // ok bool e boolean sono la stessa cosa
boolean STATE_LED=LOW;  
void setup()
{
  pinMode(LED, OUTPUT);
  pinMode(INPIN,INPUT);
}

void loop()
{
  // uint32_t e unsigned long sono la stessa cosa ma il primo richiede meno caratteri
  unsigned long currentMillis = millis();
if ( digitalRead(INPIN) && (STATE_LED == LOW))
  {
    STATE_LED=HIGH;
    previousMillis = currentMillis;
  }
if ( currentMillis - previousMillis >= interval )
   {
   STATE_LED=LOW;
   }
   digitalWrite(LED,STATE_LED);
}

Puoi provare con && cosa accade, comunque non è la soluzione perfetta. Parti con il piede giusto, usa il tipo boolean per le variabili che assumono valori true, false, HIGH, LOW , 1, 0 ecc. Se sono costanti specificalo anteponendo const. Prima di postare e di tanto in tanto premi nell'IDE Ctrl+T.

Ciao.