Comandare uscite con un Keypad

Di fatti avevo notato che si bloccava tutto per il tempo impostato in delay..
Nell'esempio che mi hai mandato il link cè lo sketch per eseguire un blink, ima io esattamente nel mio sketch dove devo mettere esattamente il tutto per poter spegnere l'uscita attivata tramite pulsante del Keypad?

Conviene usare una variabile di stato 0 o 1 , la metti a 1 quando premi il pulsante (nello switch)
Poi dopo lo switch, se stato==1 allora conti con la millis e dopo 2 secondi (contati con millis) allora spegni rele e riponi stato=0.

Grazie per la risposta, ma come dovrei fare esattamente tutto questo? Perché non sono molto pratico.. La variabile di stato è la funzione int?

dichiari una variabile di tipo int (non è una funzione) che puoi chiamare statoRele1 e la inizializzi a 0

nel programma quando premi il tasto che ti interessa, quindi nello switch...case ramo giusto statoRele1=1; e memorizzi millis()

fuori e dopo lo switch() metti un if che verifica se statoRele1==1, se si allora verifichi se passati 2 secondi.
Questo il codice aggiuntivo rispetto al tuo, la parte iniziale fino a #define ledpin 13 va bene.
L'ho scritto senza provarlo !!

...   la parte iniziale non la riporto, va bene
#define ledpin 13  
int StatoRele1=0;
unsigned long previousMillis = 0;

void setup()
{ pinMode(ledpin,OUTPUT);
  digitalWrite(ledpin, HIGH);
  statoRele1=0;
  Serial.begin(9600);
  delay(1000);
}

void loop()
{ char key = kpd.getKey();
  if(key) Serial.println(key);
  switch (key)
  { case '1':
        statoRele1=1;                 // attivare rele e conteggio
        previousMillis = millis();  // istante in cui ha premuto
        break;
  }
  if(statoRele1==1)
  { if( millis()- previousMillis > 2000 )    // passati 2 secondi ? da quando hai premuto
    { statoRele1=0;    // disattivare rele e conteggio
    }
    digitalWrite(ledpin,statoRele1);
  }

Grazie mille per il codice. Provandolo mi funzionava al contrario, cioè il relè restava sempre acceso e quando premevo restava spento per 2 secondi, e si riaccendeva. Allora ho invertito tutti i valori di statoRelè e adesso funziona correttamente tutto.
Adesso se io volessi comandare anche il secondo relè, sempre con questo procedimento, come devo fare?

crei un altro statoRele2, ed anche un'altra previousMillis2
(e cambia la previousMillis in previousMillis1)
Poi raddoppi il pezzo alla fine dove fai if su statoRele1 ma lavori con statoRele2 e previouseMillis2
Ovviamente nello switch dovrai aggiungere un case per il rele2 gestendo sempre statoRele2 e previouseMillis2

E per quanto riguarda il #define ledpin 13, dovrei fare #define ledpin 12 anche, però come devo scriverlo questo pezzetto? Perché se lo metto sotto mi lavora solo con il 12 dopo

marcosilve95:
E per quanto riguarda il #define ledpin 13, dovrei fare #define ledpin 12 anche, però come devo scriverlo questo pezzetto? Perché se lo metto sotto mi lavora solo con il 12 dopo

fai due define, anche qui ledpin1 e ledpin2 cosi hai "associato" le varie variabili/define 1 e 2 tra loro

#define LEDPIN1 13  
#define LEDPIN2 12
byte StatoRele1,StatoRele2;
unsigned long prevMillis1,prevMillis2;

void setup()
{ pinMode(LEDPIN1,OUTPUT);
  pinMode(LEDPIN2,OUTPUT);
  statoRele1=LOW;       // LOW è uguale a 0, HIGH uguale a 1
  statoRele2=LOW;
  digitalWrite(LEDPIN1, statoRele1);
  digitalWrite(LEDPIN2, statoRele2);
  Serial.begin(9600);
  delay(1000);
}

void loop()
{ char key = kpd.getKey();
  if(key) Serial.println(key);
  switch (key)
  { case '1':
        statoRele1=HIGH;         // attivare rele e conteggio   
        prevMillis1 = millis();     // istante in cui ha premuto
        break;
    case '2':
        statoRele2=HIGH;         // attivare rele e conteggio   
        prevMillis2 = millis();     // istante in cui ha premuto
        break;
  }
  if(statoRele1==HIGH) 
  { if( millis()- prevMillis1 > 2000 )    // passati 2 secondi ? da quando hai premuto
    { statoRele1=LOW;    // disattivare rele e conteggio
    }
    digitalWrite(LEDPIN1,statoRele1);
  }
  if(statoRele2==HIGH)
  { if( millis()- prevMillis2 > 2000 )    // passati 2 secondi ? da quando hai premuto
    { statoRele2=LOW;    // disattivare rele e conteggio
    }
    digitalWrite(LEDPIN2,statoRele2);
  }
}

Grazie mille, funziona!

Vorrei vedere, ci mancava solo che venisse pure a digitartelo.
E daglielo almeno un Karma a @nid69ita

Adesso vorrei chiederti un'altra cosa: se volessi attivare statoRèle con due pulsanti, cioè magari premendo 1 si attiva il relè per 2 secondi, e magari premendo il tasto 2 si attiva sempre lo stesso relè per 4 secondi... Dovrei usare un altro previousMillis2, però non riesco a far in modo che si attivi il relè...

se gli stati sono sempre 2 sono sufficienti 2 coppie di variabili (statoRele + previusMillis).
aggiungi altre coppie (tipo statoRele3 e previusMillis3) solo se aggiungi un terzo stato.

per adesso, per variare solo il tempo di accensione, è sufficiente che modifichi il "2000" nell'if (2000 corrisponde a 2 secondi).

marcosilve95:
Adesso vorrei chiederti un'altra cosa: se volessi attivare statoRèle con due pulsanti, cioè magari premendo 1 si attiva il relè per 2 secondi, e magari premendo il tasto 2 si attiva sempre lo stesso relè per 4 secondi... Dovrei usare un altro previousMillis2, però non riesco a far in modo che si attivi il relè...

In questo caso la strada più semplice è avere una variabile che indica QUANTO tempo deve passare, invece di mettere fisso 2000, a seconda del tasto premuto, imponi il tempo 2000 o 4000 ad una variabile che userai come "intervallo" necessario.

Ecco il codice completo :

#include <Keypad.h>

const byte ROWS = 4; // quattro righe
const byte COLS = 4; // quattro colonne
// Definizione del Keymap
char keys[ROWS][COLS] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'#','0','*','D'}
};
// Connessione Keypad ROW0, ROW1, ROW2 e ROW3 ai pin Arduino
byte rowPins[ROWS] = { 2,3,4,5};
// Connessione Kaypad COL0, COL1 e COL2 ai pin Arduino
byte colPins[COLS] = { 6,7,8,9 }; 

// Creazione del Keypad
Keypad kpd = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

#define LEDPIN1 13  
#define LEDPIN2 12
byte statoRele0,statoRele1,statoRele2,statoRele3,statoRele4,statoRele5,statoRele6,statoRele7,statoRele8,statoRele9;
unsigned long prevMillis0,prevMillis1,prevMillis2,prevMillis3,prevMillis4,prevMillis5,prevMillis6,prevMillis7,prevMillis8,prevMillis9;

void setup()
{ pinMode(LEDPIN1,OUTPUT);
  pinMode(LEDPIN2,OUTPUT);
  statoRele0=1;       
  statoRele1=1;
  statoRele2=1;
  statoRele3=1;
  statoRele4=1;
  statoRele5=1;
  statoRele6=1;
  statoRele7=1;
  statoRele8=1;
  statoRele9=1;
  digitalWrite(LEDPIN2, statoRele0);
  digitalWrite(LEDPIN1, statoRele1);
  digitalWrite(LEDPIN1, statoRele3);
  digitalWrite(LEDPIN1, statoRele4);
  digitalWrite(LEDPIN1, statoRele5);
  digitalWrite(LEDPIN1, statoRele6);
  digitalWrite(LEDPIN1, statoRele7);
  digitalWrite(LEDPIN1, statoRele8);
  digitalWrite(LEDPIN1, statoRele9);
  Serial.begin(9600);
  delay(1000);
}

void loop()
{ char key = kpd.getKey();
  if(key) Serial.println(key);
  switch (key)
  { case '1':
        statoRele1=0;         // attivare relè ALZATA e conteggio   
        prevMillis1 = millis();     // istante in cui ha premuto
        break;

    case '2':
        statoRele2=0;         // attivare relè ALZATA e conteggio   
        prevMillis2= millis();     // istante in cui ha premuto
        break;

    case '3':
        statoRele3=0;         // attivare relè ALZATA e conteggio   
        prevMillis3= millis();     // istante in cui ha premuto
        break;

    case '4':
        statoRele4=0;         // attivare relè ALZATA e conteggio   
        prevMillis4= millis();     // istante in cui ha premuto
        break;

    case '5':
        statoRele5=0;         // attivare relè ALZATA e conteggio   
        prevMillis5= millis();     // istante in cui ha premuto
        break;

    case '6':
        statoRele6=0;         // attivare relè ALZATA e conteggio   
        prevMillis6= millis();     // istante in cui ha premuto
        break;

    case '7':
        statoRele7=0;         // attivare relè ALZATA e conteggio   
        prevMillis7= millis();     // istante in cui ha premuto
        break;

    case '8':
        statoRele8=0;         // attivare relè ALZATA e conteggio   
        prevMillis8= millis();     // istante in cui ha premuto
        break;

    case '9':
        statoRele9=0;         // attivare relè ALZATA e conteggio   
        prevMillis9= millis();     // istante in cui ha premuto
        break;

    case '0':
        statoRele0=0;         // attivare relè DISCESA e conteggio   
        prevMillis0= millis();     // istante in cui ha premuto
        break;
  }

  
  if(statoRele1==0) 
  { if( millis()- prevMillis1 > 1000 )    // passati 1 secondO da quando si preme
    { statoRele1=1;    // disattivare relè e conteggio
    }
    digitalWrite(LEDPIN1,statoRele1);
  }

    if(statoRele2==0) 
  { if( millis()- prevMillis2 > 2000 )    // passati 2 secondi da quando si preme
    { statoRele2=1;    // disattivare relè e conteggio
    }
    digitalWrite(LEDPIN1,statoRele2);
  }

    if(statoRele3==0) 
  { if( millis()- prevMillis3 > 3000 )    // passati 3 secondi da quando si preme
    { statoRele3=1;    // disattivare relè e conteggio
    }
    digitalWrite(LEDPIN1,statoRele3);
  }

    if(statoRele4==0) 
  { if( millis()- prevMillis4 > 4000 )    // passati 4 secondi da quando si preme
    { statoRele4=1;    // disattivare relè e conteggio
    }
    digitalWrite(LEDPIN1,statoRele4);
  }

  if(statoRele5==0) 
  { if( millis()- prevMillis5 > 5000 )    // passati 5 secondi da quando si preme
    { statoRele5=1;    // disattivare relè e conteggio
    }
    digitalWrite(LEDPIN1,statoRele5);
  }

  if(statoRele6==0) 
  { if( millis()- prevMillis6 > 6000 )    // passati 6 secondi da quando si preme
    { statoRele6=1;    // disattivare relè e conteggio
    }
    digitalWrite(LEDPIN1,statoRele6);
  }

  if(statoRele7==0) 
  { if( millis()- prevMillis7 > 7000 )    // passati 7 secondi da quando si preme
    { statoRele7=1;    // disattivare relè e conteggio
    }
    digitalWrite(LEDPIN1,statoRele7);
  }

  if(statoRele8==0) 
  { if( millis()- prevMillis8 > 8000 )    // passati 8 secondi da quando si preme
    { statoRele8=1;    // disattivare relè e conteggio
    }
    digitalWrite(LEDPIN1,statoRele8);
  }

  if(statoRele9==0) 
  { if( millis()- prevMillis9 > 9000 )    // passati 9 secondi da quando si preme
    { statoRele9=1;    // disattivare relè e conteggio
    }
    digitalWrite(LEDPIN1,statoRele9);
  }
  
  if(statoRele0==0)
  { if( millis()- prevMillis0 > 10000 )    // passati 10 secondi da quando si preme
    { statoRele0=1;    // disattivare relè e conteggio
    }
    digitalWrite(LEDPIN2,statoRele0);
  }

}

Adesso vorrei chiedervi un'altra cosa: con un relè praticamente alzo ad un determinato livello (impostato dal tempo), con l'altro (statoRele0) abbasso. Si riuscirebbe a fare in modo che il sistema si ricordi a quanto è stato alzato (in secondi) e poi quando si attivi la discesa sappia automaticamente di scendere lo stesso tempo che è salito?

Ovviamente. millis() è una funzione che funziona similmente ad un orologio e ti aiuta a tracciare lo scorrere del tempo, vedi nella mia firma per maggiori dettagli.

Basta salvare il valore di millis() quando inizi ad alzare, e poi quando finisci di alzare fai la differenza col valore attuale di millis(): otterrai la durata dell'"alzata" in millisecondi. A quel punto ti basta abbassare per la stessa durata.

Il problema è che io ho 9 prevMillis, come dovrei fare io esattamente?

Cioé hai 9 relé?

non ho ben capito cosa vuoi fare, ma nel tuo codice c'è qualcosa di strano...

hai 2 led e 9 stati... sicuro che servano?

  digitalWrite(LEDPIN2, statoRele0);
  digitalWrite(LEDPIN1, statoRele1);
  digitalWrite(LEDPIN1, statoRele3);
  digitalWrite(LEDPIN1, statoRele4);
  digitalWrite(LEDPIN1, statoRele5);
  digitalWrite(LEDPIN1, statoRele6);
  digitalWrite(LEDPIN1, statoRele7);
  digitalWrite(LEDPIN1, statoRele8);
  digitalWrite(LEDPIN1, statoRele9);

a cosa dovrebbero servire i digitalWrite da 1 a 9 sempre sullo stesso pin?

Mi servono perché ad ogni pressione di un tasto del keypad devo avere un determinato tempo.... Io devo, quando premo il tasto 0 della discesa , il relè deve restare acceso lo stesso tempo di uno dei 9 tasti premuti prima per l'altra

Mi servono perché ad ogni pressione di un tasto del keypad devo avere un determinato tempo

Capisco il tuo ragionamento, però che senso ha mettere 9 volte in HIGH lo stesso piedino, basta una volta

Brunello:
Capisco il tuo ragionamento, però che senso ha mettere 9 volte in HIGH lo stesso piedino, basta una volta

se leggi le risposte precedenti c'è scritto tutto il procedimento che mi hanno consigliato di fare