Flipper temporizzare uscite con millis

Salve a tutti ho un vecchio flipper che o lo butto o lo faccio funzionare almeno un minimo per giocare. tutti i fine corsa del piano lavorano a matrice, fin qui tutto ok, ho recuperato tutte le colonne e righe e ho realizzato un 1° sketch con la libreria <KEYPAD.H> abilitando il monitor seriale nonostante la ruggine tutti i finecorsa funzionano e scrivono il loro caratetre ascii. il problema è questo alcune uscite devono avere delle temporizzazioni usando millis invece di delay. non riesco a sostituire delay con millis ho provato da settimane in tutte le maniere ma nulla con comando diretto da ingresso tutto ok da matrice non riesco a farlo andare. di seguito il codice semplificato con il delay da sostituire con millis. se qualcuno mi può dare una dritta..grazie

//Definisce i pin per comandare i rele'
const int rele_1 =  13;      // bumper up sx




// Definizione tastiera
#include <Keypad.h>

const int ROW_NUM = 2; // otto righe
const int COLUMN_NUM = 1; // quattro colonne
// Definizione mappa della tastiera
char keys[ROW_NUM][COLUMN_NUM] = {
  {'1'},
  {'7'},
  
};
byte pin_rows[ROW_NUM] = { 3, 4}; // Riga 0,1,2,3,4,5,6,7,8
byte pin_column[COLUMN_NUM] = { 5 }; // Colonna 0,1,2,3,4
// Creazione della tastiera
Keypad kpd = Keypad( makeKeymap(keys), pin_rows, pin_column, ROW_NUM, COLUMN_NUM );

void setup() {
  Serial.begin(9600);
  // imposta i pin digitali come uscite:
  pinMode(rele_1, OUTPUT);
digitalWrite(rele_1,LOW);
 
  
}
void loop() {
  char key = kpd.getKey();
  if (key) {
    Serial.println(key);
     switch (key)
     {
  case 49: //valore ascii del numero 1
        digitalWrite(rele_1, HIGH);
        delay (100);
        digitalWrite(rele_1, LOW);
    
  }          
  }
        
        
  
    } 

cosa esattamente dovrebbe essere sostituito da millis, quali regole

grazie per la risposta, ho semplificato il codice a soli 2 ingressi (gestiti sempre a matrice) di cui il 1° attiva il led uscita 13 per 100 millisecondi. l'uscita è attivata dal codice ascii 49. ho trovato un codice che attivata un uscita da un normale ingresso usando millis la spegne dopo il tempo impostato. il problema che sostituendo il delay con la parte di codice che usa millis non funziona. sembra che non riconosce come comando il case 49 ( ascii) . ilcodice che volevo sostituire a delay è questo

const int button1Pin = 2;

const int led1Pin = 13;

 
unsigned long led1OnTime = 0;

bool led1On;
 
void setup() {
 
  pinMode(led1Pin, OUTPUT);
  
  pinMode(button1Pin, INPUT);
  
 
  led1On = false;
  
}
 
void loop(){
 
  if (digitalRead(button1Pin) == HIGH) {     
    digitalWrite(led1Pin, HIGH);
    led1On = true;
    led1OnTime = millis();
  }
 
 
  if(led1On) 
    if(millis() - led1OnTime >= 200) {
      digitalWrite(led1Pin, LOW);
      led1On = false;
    }   

}

ho 2 soluzioni o invece della libreria keypad uso la lettura della matrice abilitando i la scansione delle colonne e così mi trovo gli ingressi da abilitare come il 2° codice oppure metto dei bei condensatori al mosfet che pilota le uscite da ritardare e ho risolto. il 1° codice mi sembra più lineare

@donaldduck7272:

:warning:
Ti segnalo che, nella sezione in lingua Inglese, si può scrivere SOLO in Inglese ... quindi, per favore, la prossima volta presta più attenzione in quale sezione metti i tuoi post; questa volta esso è stato spostato, da un moderatore della sezione di lingua Inglese, nella sezione di lingua Italiana ... la prossima volta potrebbe venire direttamente eliminato. Grazie.

Guglielmo

chiedo scusa non avevo notato sono alle prime conoscenze delle regole del forum

Direi una cosa di questo tipo, dove memorizzi l'eventuale tempo di disattivazione di un particolare relè mettendo però anche questo in un array parallelo, unitamente ad uno che "tiene a mente" il momento in cui va disattivato (nota: non solo il codice è ovviamente la versione "semplificata", ma ho scritto il codice di getto, non è detto che sia esente da errori, sta a te provarlo e debuggarlo anche per non darti "pappa pronta".. :wink: ):

const int ROW_NUM = 2; // otto righe
const int COL_NUM = 1; // quattro colonne
// Mappa che associa ogni "tasto" ad un pin dei relè,
char tasto[ROW_NUM*COL_NUM] = { '1', '7' };
byte rele[ROW_NUM*COL_NUM] = { 12, 13 };
// Mappa che rappresenta il millis() di disattivazione relè
// (0=nessuno)
unsigned long tmrRele[ROW_NUM*COL_NUM];
// Intervallo di disattivazione
const unsigned long DELAY_RELE = 100;

void setup() {
  Serial.begin(9600);
  // imposta i pin digitali come uscite, ed i relativi timer:
  for (int r=0; r<ROW_NUM*COL_NUM; ++r) {
    pinMode(rele[r], OUTPUT);
    digitalWrite(rele[r],LOW);
    tmrRele[r] = 0; 
  }
}
...
void loop() {
  // Gestisco le disattivazioni
  for (int r=0; r<ROW_NUM*COL_NUM; ++r) {
    if (tmrRele[r] > 0UL && millis()-tmrRele[r] >= 0UL) {
      // Disattivo il relè tmrRele[r]
      // TODO
      // "spengo" il timer
      tmrRele[r] = 0;
    }
  }
  // Leggo il "tasto"
  char key = kpd.getKey();
  if (key) {
    Serial.println(key);
    // Cerco il tasto nell'array dei tasti
    for (int r=0; r<ROW_NUM*COL_NUM; ++r) {
      if (tasto[r] == key) {
        // trovato, attivo il relè rele[r]
        // TODO
        // Ed attivo il timer tmrRele[r] con il valore di millis() al quale
        // aggiungere il delay (DELAY_RELE)
        // TODO
        break;
      }
    } 
  }
}

PS: ovviamente se hai domande o problemi, chiedi!

Fai un giro su "la pappa è fatta", troverai idee per risolvere il tuo problema

grazie tenterò spero non mi ci vorranno giorni... per interpretare

adesso do un occhiata grazie

salve, ho fatto delle prove ma il problema è che forse lo sketch da modificare non è la mia soluzione. purtroppo ho tempo solo nel week end di fare qualcosa. ho preso spunto da questo sketch di prova`

const int button1Pin = 2;
const int button3Pin = 3;

const int led1Pin = 13;
const int led1Pin1 = 12;

 
unsigned long led1OnTime = 0;

bool led1On;
 
void setup() {
 
  pinMode(led1Pin, OUTPUT);
  pinMode(led1Pin1, OUTPUT);
  
  pinMode(button1Pin, INPUT);
  pinMode(button3Pin, INPUT);
  
 
  led1On = false;
  
}
 
void loop(){
 if(digitalRead(button3Pin) == HIGH)  {    
    digitalWrite(led1Pin1, HIGH);
    }
 
  if(digitalRead(button3Pin) == LOW)  {    
    digitalWrite(led1Pin1, LOW);
    } 
  
  
  
  if (digitalRead(led1Pin1) == HIGH) {     
    digitalWrite(led1Pin, HIGH);
    led1On = true;
    led1OnTime = millis();
  }
 
 
  if(led1On) 
    if(millis() - led1OnTime >= 20) {
      digitalWrite(led1Pin, LOW);
      led1On = false;
    }   

}

per realizzare questo, ma l'uscita si accende e non si spegne più. dove ho sbagliato?

digita o inco//Definisce i pin per comandare i rele'
const int rele_1 =  13;      // bumper up sx
unsigned long led1OnTime = 0;
bool led1On;

// Definizione tastiera
#include <Keypad.h>

const int ROW_NUM = 2; // otto righe
const int COLUMN_NUM = 1; // quattro colonne
// Definizione mappa della tastiera
char keys[ROW_NUM][COLUMN_NUM] = {
  {'1'},
  {'7'},
  
};
byte pin_rows[ROW_NUM] = { 3, 4}; // Riga 0,1,2,3,4,5,6,7,8
byte pin_column[COLUMN_NUM] = { 5 }; // Colonna 0,1,2,3,4
// Creazione della tastiera
Keypad kpd = Keypad( makeKeymap(keys), pin_rows, pin_column, ROW_NUM, COLUMN_NUM );

void setup() {
  Serial.begin(9600);
  // imposta i pin digitali come uscite:
  pinMode(rele_1, OUTPUT);
digitalWrite(rele_1,LOW);

 
  
}
void loop() {
  char key = kpd.getKey();
  if (key) {
    Serial.println(key);
     switch (key)
     {
  case 49: //valore ascii del numero 1

        digitalWrite(rele_1, HIGH);
      
   
   if (digitalRead(rele_1) == HIGH) {  

    
    led1OnTime = millis();
    }
 

  if(led1On) 
    if(millis() - led1OnTime >= 20) {
      digitalWrite(rele_1, LOW);
   
    }     
  }          
   }
    }   
        
  lla il codice qui

All'interno del case, il controllo di tempo trascorso non viene mai eseguito, perché il case viene eseguito solo alla pressione del pulsante.

grazie per le indicazioni, ho modificato il codice così ma niente

const int rele_1 =  13;      // bumper up sx
unsigned long led1OnTime = 0;
bool led1On;

// Definizione tastiera
#include <Keypad.h>

const int ROW_NUM = 2; // otto righe
const int COLUMN_NUM = 1; // quattro colonne
// Definizione mappa della tastiera
char keys[ROW_NUM][COLUMN_NUM] = {
  {'1'},
  {'7'},
  
};
byte pin_rows[ROW_NUM] = { 3, 4}; // Riga 0,1,2,3,4,5,6,7,8
byte pin_column[COLUMN_NUM] = { 5 }; // Colonna 0,1,2,3,4
// Creazione della tastiera
Keypad kpd = Keypad( makeKeymap(keys), pin_rows, pin_column, ROW_NUM, COLUMN_NUM );

void setup() {
  Serial.begin(9600);
  // imposta i pin digitali come uscite:
  pinMode(rele_1, OUTPUT);

led1On = false;
 
  
}
void loop() {
  char key = kpd.getKey();
  if (key) 
    Serial.println(key);
     switch (key)
     {
  case 49: //valore ascii del numero 1

        digitalWrite(rele_1, HIGH);}
      
   
   if (digitalRead(rele_1) == HIGH) {
    digitalWrite (rele_1, HIGH );
    led1On =true;
    led1OnTime =millis();
   }

    
 

  if(led1On) 
    if(millis() - led1OnTime >= 20) {
      digitalWrite(rele_1, LOW);
      led1On =false;
    }
} 

Formattalo meglio, il codice
E spiega bene cosa vuol dire "ma niente"

Tu vedi il problema, tu lo devi descrivere...

Adesso il controllo del tempo è correttamente fuori dal case. Ma hai messo fuori dal case anche la memorizzazione del tempo iniziale, che invece deve avvenire solo alla pressione del pulsante, mentre fuori dal case viene effettuata sempre, e il timeout non arriva mai.

Consiglio: simula mentalmente l'ordine di esecuzione delle istruzioni.

per niente intendo che il led si accende attivato dal tasto di prova della matrice che ho ridotto per semplificare ma rimane acceso. il problema che attivata una uscita da tastiera, questa si dovrebbe diseccitare dopo pochissimo tempo con il comando millis. senza delay che bloccherebbe troppo il programma

ora riprovo grazie

Naturalmente hai ragione

In tutto il tuo post

si ho risolto adesso funziona grazie infinite per il tuo tempo e le dritte. ho modificato così `

const int rele_1 =  13;      // bumper up sx
unsigned long led1OnTime = 0;
bool led1On;

// Definizione tastiera
#include <Keypad.h>

const int ROW_NUM = 2; // otto righe
const int COLUMN_NUM = 1; // quattro colonne
// Definizione mappa della tastiera
char keys[ROW_NUM][COLUMN_NUM] = {
  {'1'},
  {'7'},
  
};
byte pin_rows[ROW_NUM] = { 3, 4}; // Riga 0,1,2,3,4,5,6,7,8
byte pin_column[COLUMN_NUM] = { 5 }; // Colonna 0,1,2,3,4
// Creazione della tastiera
Keypad kpd = Keypad( makeKeymap(keys), pin_rows, pin_column, ROW_NUM, COLUMN_NUM );

void setup() {
  Serial.begin(9600);
  // imposta i pin digitali come uscite:
  pinMode(rele_1, OUTPUT);

led1On = false;
 
  
}
void loop() {
  char key = kpd.getKey();
  if (key) 
    Serial.println(key);
     switch (key)
     {
  case 49: //valore ascii del numero 1

        digitalWrite(rele_1, HIGH);
        led1OnTime =millis();}
      
        
        
      
   
   if (digitalRead(rele_1) == HIGH) {
    digitalWrite (rele_1, HIGH );
    led1On =true;
  
   }

    
 

  if(led1On) 
    if(millis() - led1OnTime >= 200)
  
    {
      digitalWrite(rele_1, LOW);
      led1On =false;
    } 
}

Ma veramente...
Se non formatti il codice queste cose ti sfuggono facilmente

Quindi: formatta quel codice