[HELP] Filtro software anti-polvere per fotocellula

Ho un sistema di contapezzi su un macchinario che ogni tanto manifesta il problema della polvere, e conta più del necessario.

In pratica la polvere si aggrega in batufoli di dimensioni abbastanza consistenti, da passare sotto la fotocellula ed essere contati come pezzi validi.

Per ora ho inserito un controllo doppio in Polling, ma vorrei farlo su attivazione di Interrupt sul PIN 2

Funzione attuale:

  Fotocellula_1 = digitalRead(in_NPN);
  
  if (Fotocellula_1 == 0)
  {
    delay(300);
     if(Fotocellula_1  == 0)
      {
       ++contatore;
       if(contatore == 999) contatore = 0;
       Riempi();
       while(Fotocellula_1 == 1)
            {
              Fotocellula_1 = digitalRead(in_NPN);
             } 
       }     
    }

In pratica leggo l'ingresso, attendo 300 msec, rileggo, e se è ancora ON, incremento il contatore e attivo la funzione Riempi().

Il while mi serve come condizione bloccante per non continuare ad aumentare il contatore finchè la fotocellula è a 1 (mi conterebbe 30-40 pezzi al secondo!)

Il filtro consiste nel doppio check intervallato da 300 msec.

Utilizzando un interrupt come posso fare?

Perché usare un interrupt?
se un pezzo di una certa dimensione minima passa con una velocitá data interrompe la fotocellula per x secondi.
Al passaggio L-H della fotocellula memorizi i millis in una funzione
Al passaggio H-L calcoli il tempo passato. se é sotto un certo valore é solo sporco se sopra é un pezzo e va incrementato il contapezzi.
Ilpassaggio H-L lo determini con lo stato della fotocella e con lo stato precedente della fotocella.
Ciao Uwe

Più o meno come con il polling.

Il motivo per cui uso l'Interrupt è perchè se si blocca un pezzo sul nastro trasportatore, non si aggiorna l'orologio sul display (rimane dentro il while)

Ho modificato con il millis() e work fine, per ora me lo faccio andare bene.

if (Fotocellula_1 == 0)
  {
     if(millis() - milli_precedente > intervallo)
      {
       ++contatore;
       if(contatore == 999) contatore = 0;
       Riempi();
       while(Fotocellula_1 == 1)
            {
              Fotocellula_1 = digitalRead(in_NPN);
             } 
       }     
    }

BaBBuino:
Più o meno come con il polling.

Il motivo per cui uso l'Interrupt è perchè se si blocca un pezzo sul nastro trasportatore, non si aggiorna l'orologio sul display (rimane dentro il while)

allora non usare il while.
Controlla durante il High della fotocellula se i millis superano un valore e interrompi la misura.
Ciao Uwe

if (!Fotocellula_1) {
     if (millis() - milli_precedente > intervallo) {
         if(++contatore >= 999) {
              contatore = 0;
         }
         Riempi();
         start_timeout = millis();
         do {
              Fotocellula_1 = digitalRead(in_NPN);
         } while ((!Fotocellula_1) && (millis() - start_timeout < timeout));
    }     
}

Ho messo un timeout per l'uscita dal do..while. Dopo il while puoi controllare Fotocellula_1: se è a 0 vuol dire che sei uscito per timeout.