Go Down

Topic: [HELP] Filtro software anti-polvere per fotocellula (Read 741 times) previous topic - next topic

BaBBuino

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:

Code: [Select]
  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?

uwefed

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

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)

BaBBuino

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

Code: [Select]
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);
             }
       }     
    }

uwefed


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

leo72

Code: [Select]

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.

Go Up