Gestire un comando in base al tempo di durata dell'ingresso

ciao ragazzi!! finalmente sono approdato a un mio progetto con l'Arduino!! :slight_smile:
Siccome sono un hardwarista puro, ho qualche difficoltà con la programmazione.. :blush:
Vorrei che il mio arduino al variare di stato di un ingresso da 0 a 1 (ipotizziamo il pin 13) emetta un comando (ipotizziamo sul pin 13)
Se l'input dura meno di 4 sec, il comando segue la durata del DI
se l'input dura tra i 4 e gli 8 sec, il comando deve durare 30 secondi
se l'input dura più di 8 secondi, il comando deve durare 60 secondi
e se durante l'uscita del comando ho una variazione dell'input (nel frattempo tornato a 0) il comando si deve fermare
come posso fare??
qualcuno mi può aiutare?

Grazie Mille!!!

usa la funzione millis per scandire i tempi

Vorrei che il mio arduino al variare di stato di un ingresso da 0 a 1 (ipotizziamo il pin 13) emetta un comando (ipotizziamo sul pin 13)

Se l'input dura meno di 4 sec, il comando segue la durata del DI

che vuol dire ?

e se durante l'uscita del comando ho una variazione dell'input (nel frattempo tornato a 0) il comando si deve fermare

Questo è impossibile se il piedino di input e di output è fisicamente lo stesso. Qui fai appunto l'ipotesi che il pin 13 venga usato in entrambe i modi, input e output allo stesso tempo.

Vorrei che il mio arduino al variare di stato di un ingresso da 0 a 1 (ipotizziamo il pin 13) emetta un comando (ipotizziamo sul pin 13)

pablos lo ha già notato e chiesto lumi.

@pablos
credo che DI significhi digital input, pertanto se l'input dura 4 secondi anche l'output deve durare 4 secondi, ma aspettiamo lui che risponda ufficialmente.

Ciao.

eccomi ragazzi!!! scusate ma la reperibilità al lavoro mi ha tenuto un pò lontano...
in effetti leggendo la mia richiesta non brilla la chiarezza, e soprattutto l'errore madornale di volere ingresso e uscita sullo stesso pin!!! :blush:
Esatto DI significa Digital Input e DO Digital Output (deformazione professionale)
mi spiego molto meglio, tralasciando la divisione temporale dei DI della volta precedente
quando ho una variazione di stato del pin 13 (Digital Input) di durata anche irrisoria data da un dito umano,(per intenderci un dito che preme un pulsante e poi rilascia) il mio fantastico arduino deve emettere un comando (HIGH) sul pin 12 per un tempo totale di 60 secondi
se durante questo comando ho un'altra variazione di stato sul pin 13, il comando deve rientrare (LOW)
quando ripremerò il pulsante sul pin 13, il comando dovrà ritornare HIGH per un tempo di 60sec meno il tempo che è stato HIGH nei 2 step precedenti
se anche durante questo comando ho un'ennesima variazione di stato sul pin 13, il comando sul pin 12 deve rientrare
quando ripremerò ancora il pulsante sul pin 13 il comando dovrà ritornare HIGH per un tempo di 60sec meno i due tempi precedenti in cui è stato HIGH
e cosi via finchè non raggiungerò i 60 secondi totali

nessuno di voi mi può aiutare?
Many thanks

Generalmente non si scrivono gli sketch "su ordinazione".
Correggiamo gli sketch degli utenti. Questo perché bisogna che l'utente si impegni un po' altrimenti con uno sketch scritto da altri non impara nulla.

Hai fatto un ragionamento logico che ha già la struttura per essere convertito in un algoritmo. Prova a buttar giù 2 righe di codice. Aiutati con l'esempio "Blink Without Delay" che ti mostra come si può controllare lo scorrere del tempo facendo nel contempo altre azioni

Il problema principale è il calcolo del tempo.

Devi prima itercettare la pressione del pulsante, e contare per quanto tempo il pulsante rimane premuto

Fatto questo posti il codice nel tag code, piggiando il pulsante "#" che trovi sopra le faccine.

Ma prima come dice leo, prendi confidenza con gli esempi presenti nell'ide.

Ciao.

grazie ragazzi stasera mi metto all'opera!!!
sperem in ben!

ciao a tutti!! ci sono riuscito finalmente, praticamente ho creato un relè temporizzato con 2 digital input che mi comandano 2 digital output per un massimo di tot secondi che posso impostare a piacere, creando dei finecorsa temporali...
il compilatore me lo compila giusto, ma quando lo carico sull'arduino non sempre funziona, mi ignora le variazioni di stato dei digital input (quando premo per bloccare il comando, questa uscita viene interrotta solo per il tempo di pigiatura dell'interruttore..)
come posso fare per filtrare i miei digitali di ingresso? dove devo inserire il filtro?
ecco il mio programma:

/*
  DigitalReadSerial
 Reads a digital input on pin 2, prints the result to the serial monitor 
 
 This example code is in the public domain.
 */
//variabili utili nello sketch
#define TOT_TAPP 1
#define APRI 1
#define CHIUDI 2
#define STOP 0

long interval = 500; //espresso in millisecondi. quindi giro 10 volte al secondo
long previousMillis = 0;

//definisco i pin degli ingressi un apri e un chiudi per ogni tapparella
const int pushButtonAp[]={3,3,3,3,3,3,3,3};
const int pushButtonCh[]={2,2,2,2,2,2,2,2};

//Defininisco i pin dei comandi un chiudi e un apri per ogni tapparella
const int CmdAp[]={12,12,12,12,12,12,12,12};
const int CmdCh[]={9,9,9,9,9,9,9,9};
//definisco le variabili per la gestione delle temporizzazioni
// Temp_Ap[i] rappresenta il tempo di escursione in apertura della tapparella i-esima
// Temp_Ch[i] rappresenta il tempo di escursione in chiusura della tapparella i-esima (da tutto aperto a tutto chiuso).
// Temp_ResAp[i] rappresenta il tempo che manca per l'apertura totale della tapparella i-esima
// Temp_ResCh[i] rappresenta il tempo che manca per la chiusura totale della tapparella i-esima
const int Temp_Ap[]={20,100,100,100,100,100,100,100};
const int Temp_Ch[]={20,100,100,100,100,100,100,100};


//azione da intraprendere per ogni tapparella
int Azione;
//stato precedente del tasto apri di ogni tapparella
int btnStPrAp[TOT_TAPP];
//stato precedente del tasto chiudi di ogni tapparella
int btnStPrCh[TOT_TAPP];
int Temp_ResAp[]={20,100,100,100,100,100,100,100};
int Temp_ResCh[]={0,0,0,0,0,0,0,0};
//vettori conteneti il numero di volte che è stato pigiato apri e chiudi per ogni tapparella
int numAp[TOT_TAPP];
int a=0;
int numCh[TOT_TAPP];


int i =0;
int j =0;
// La riutine setup() viene eseguita solo al reset del PIC
void setup() {
// initialize serial communication at 9600 bits per second:

  Serial.begin(9600);

  for (i=0; i < 8; ++i){
      // Inizializzo i pin per gli ingressi
      pinMode(pushButtonAp[i], INPUT);
      pinMode(pushButtonCh[i], INPUT);
      //inizializzo i pin delle uscute(2 per ogni tapparella)
      pinMode(CmdAp[i], OUTPUT);
      pinMode(CmdCh[i], OUTPUT);
      //inizializzo il tempo residuo di apertura pari al tempo di apertura
      //perchè considero di partire con le tapparelle chiuse
      //quindi il tempo residuo di chiusura lo inizializzo a 0.
//      Temp_ResAp[i]=Temp_Ap[i];
//      Temp_ResCh[i]=0;
      //inizializzo azioni e numero di aperture/chiusure
      Azione=STOP;
      numAp[i]=0;
      numCh[i]=0;
   }
   Serial.print("Sono fuori dal for del setup e i=");
   Serial.println(i);
}

// the loop routine runs over and over again forever:
void loop()
{
  unsigned long currentMillis = millis();
  if(abs(currentMillis-previousMillis)>=interval) 
  {
    previousMillis=currentMillis;
    //for (i=0; i < TOT_TAPP; i++)
    //{
//      i=0;
      j=0;
        Azione=GestVettInput();
        GestVettOutput(CmdAp[j],CmdCh[j],Azione);
    //}

      //Azione01++;
      //if(Azione01>2)
      //Azione01=0;
  }
}


//Bisogna assumere:
// che pigiando entrambi i comandi contemporaneamente tolgo i comandi di apri e di chiudi
int GestVettInput()
{
    int currbtnStAp = digitalRead(pushButtonAp[j]);
    int currbtnStCh = digitalRead(pushButtonCh[j]);
    Serial.print("Tempo residuo apertura = ");
    Serial.print(Temp_ResAp[j]);
   Serial.print(" Tempo residuo chiusura = ");
    Serial.println(Temp_ResCh[j]);
    if(currbtnStAp==HIGH && currbtnStCh==HIGH)
    {
      numAp[j]=0;
      numCh[j]=0;
//      Serial.print("entrambi i bottoni pigiati elemento=");
//      Serial.println(j);
//      Serial.print("numAp=");
//      Serial.println(numAp[j]);
//      Serial.print("numCh=");
//      Serial.println(numCh[j]);
      return(STOP);
    }
    //conto il numero di aperture e chiusure
    if(currbtnStCh==HIGH && btnStPrCh[j]==LOW)
    {
      numCh[j]=numCh[j]+1;
      numAp[j]=0;
      btnStPrAp[j]=LOW;
//      Serial.print("Chiudi e totale=");
//      Serial.println(numCh[j]);
      if( numCh[j]>=2)
      {
          numCh[j]=0;
          return(STOP);
      }
    }
    if(currbtnStAp==HIGH && btnStPrAp[j]==LOW)
    {
      numAp[j]=numAp[j]+1;
      numCh[j]=0;
      btnStPrCh[j]=LOW;
//      Serial.print("Apri e totale=");
//      Serial.println(numAp[j]);
      if( numAp[j]>=2)
      {
          numAp[j]=0;
          return(STOP);
      }
    }
    
    //copio lo stato attuale su quello precedente
    btnStPrAp[j]=currbtnStAp;
    btnStPrCh[j]=currbtnStCh;

    //Se passo di qui posso avere o un apri o un chiudi    
    if (numAp[j]==1)
    {
      //gestisco il timer del chiudi
      if(Temp_ResCh[j]<Temp_Ch[j])
      {
        Temp_ResCh[j]++;
        if(Temp_ResCh[j]>Temp_Ch[j])
        {
          Temp_ResCh[j]=Temp_Ch[j];
        }
      }
      //gestisco il timer dell'apri e il comando di apri
      if(Temp_ResAp[j]>0)
      {
        Temp_ResAp[j]--;
        return(APRI);
      }
      else
      {
        numCh[j]=0;
        btnStPrCh[j]=LOW;
        numAp[j]=0;
        btnStPrAp[j]=LOW;
        return(STOP);
      }
    }

    if (numCh[j]==1)
    {
      //gestisco il timer dell'apri
      if(Temp_ResAp[j]<Temp_Ap[j])
      {
        Temp_ResAp[j]++;
      }
      //gestisco il timer del chiudi e il comando di chiudi
      if(Temp_ResCh[j]>0)
      {
        Temp_ResCh[j]--;
        return(CHIUDI);
      }
      else
      {
        numCh[j]=0;
        btnStPrCh[j]=LOW;
        numAp[j]=0;
        btnStPrAp[j]=LOW;
        return(STOP);
      }
    }
}

void GestVettOutput(int CmdAp, int CmdCh, int Azione)
{
  if(Azione==0)
  {
    digitalWrite(CmdAp, LOW);
    delay(15);
    digitalWrite(CmdCh, LOW);
//    Serial.println("Comando di STOP");
    return;
  }
  if(Azione==1)
  {
    digitalWrite(CmdCh, LOW);
    delay(15);
    digitalWrite(CmdAp, HIGH);
//    Serial.println("Comando di APRI");
    return;
  }
  if(Azione==2)
  {
    digitalWrite(CmdAp, LOW);
    delay(15);
    digitalWrite(CmdCh, HIGH);
//    Serial.println("Comando di chiudi");
    return;
  }
  //se passo qui spengo tutto
  digitalWrite(CmdAp, LOW);
  digitalWrite(CmdCh, LOW);
}

cosa ne pensate?
grazie mille!!

EDIT by MOD: per favore includi il codice negli appositi tag