[RICHIESTA] Cronometro con attivazione a sensore IR

Salve a tutti.
Premetto che ho fatto diverse ricerche ma non ho trovato quello che serve a me.

faccio una domanda secca, poi se eventualmente non risolvo posso provare ad argomentare la richiesta.

In poche parole sono alla ricerca di un progetto di un Cronometro che si abiliti tramite un sensore Infrarossi a forcella, dove il classico fascio di luce è interrotto al passaggio di un ostacolo.

Dovrebbe essere uno START/STOP con lo stesso sensore (l'oggetto passa ripetutamente nello stesso sensore ed eventualmente un reset su un pulsante, (va bene in questo caso).

A me interessano sopratutto i secondi e millesimi (ecco perche mi servirebbe precisino).

Di progetti simili, se ne trovano, il problema è che usano un pulsante che è poi accompagnato da una funzione di antibounce.

Visto che a me serve qualcosa di un pelino preciso, vorrei usare qualcosa che eviti ritardi e faccia partire il conteggio esattamente sul fronte di discesa del segnale e si stoppi sul prossimo cambio di fronte
L'uso di un interrupt sarebbe il top ma è solo un mio pensiero.

Grazie per una eventuale risposta
Andy

Per il pulsante puoi usare un debounce hardware, dal sistema più semplice R+C al chip MC14490 che gestisce il debounce (non costosissimo ma neppure da pochi euro mi pare, sui 3 o 4 euro)

Per il codice, non mi pare ci siano molte istruzioni da scrivere, quindi opterei per non usare i comandi di Arduino ma direttamente la gestione dei pin a basso livello. Vedi "Arduino manipolazione diretta pin".

Grazie.

In realtà il grosso del codice ce l'ho.
Il problema è che mi sono bloccato sulla gestione dell'interrupt che sicuramente, a causa di una mia mancanza, mi sta dando dei grattacapi.
Sicuramente non è nemmeno il modo giusto di affrontare il problema, ma per non riscrivere tutto, vorrei capire se è il caso di continuare questa strada.

Il codice sfrutta un meccanismo di "TOGGLE" di una variabile che è a sua volta gestita dall'interrupt.
Purtroppo, per sua natura, il sensore IR, durante il segnale alto, (che indica il passaggio di un oggetto), mi fa invertire decine di volte la variabile.

Come si gestisce un segnale in modo da darmi un secco ALTO/BASSO e non un ALTO indefinito finche l'oggetto non transita dal sensore??

Spero si capisca quello che voglio dire :slight_smile:

In pratica:

const byte startButton = 2;                       // canale interr per Sensore IR

volatile byte statoStart = LOW;                   // variabile volatile per interr.

void setup()
{
  pinMode(startButton, INPUT);                   // PIN 2 come ingresso

  attachInterrupt(digitalPinToInterrupt(startButton), fotocellula, RISING);      // ISR che valuta il fronte di salita

  delay(500);                           // stabilizzazione
}

bool Stato = LOW;                       // inizialmente a livello basso

void loop()
{
  if (statoStart)                     // Quando il PIN 2 sente una transizione BASSO a ALTO cambia la variabile
  {
    Stato = !Stato;                   // Al passaggio di un oggetto, "Stato" si inverte
    startMillis = millis();           // variabile utile al conteggio del cronometro
  }

  if (Stato)                         // se Stato è 1, visualizza l'incremento dei numeri
{                                    // se Stato è 0, l'ultimo conteggio rimane impresso sul LCD
//...codice cronometro
}

void fotocellula()                  // funzione ISR che monitora il PIN 2
{
  statoStart = digitalRead(startButton);
}

Non ho scritto tutto il codice perchè credo sia irrilevante.

Quello che vorrei cercare di fare è fare in modo che lo stato del PIN 2 venga visto come variazione di livello BASSO / ALTO.

Se vuoi posto tutto il codice ma mi rincuorerebbe sapere che si puo' risolvere in questa maniera.

Bye

landyandy2:
Come si gestisce un segnale in modo da darmi un secco ALTO/BASSO e non un ALTO indefinito finche l'oggetto non transita dal sensore??

Devi realizzare un algoritmo che cattura il "fronte di salita".
Esempio:

bool oldStato = false;
....

void fotocellula()                  // funzione ISR che monitora il PIN 2
{
  oldStato = false;
  statoStart = true;                // Non è necessario il digitalRead() che è molto "lento", 
                                    // hai chiamato la funzione ISR sul RISING del segnale
                                    // quindi il digitalRead(startButton) è sicuramente HIGH
}

if (statoStart && !oldStato)        // Quando il PIN 2 sente una transizione ALTO a BASSO cambia la variabile
{
 oldStato = true;
 statoStart = false; 
 Stato = !Stato;                   // Al passaggio di un oggetto, "startState" si inverte
 startMillis = millis();           // variabile utile al conteggio del cronometro
}

SANTI SUBITO!!!!! :grin: :grin:

Mi metto all'opera e faccio risapere.

GRAZIE

Ho messo un punto Karma ad entrambi.

@cotestatnt
Il codice che mi hai dato è semplicemente perfetto.

Una volta implementato ho notato effettivamente anche un miglioramento nella risposta d'innesco del Cronometro.
Non sarei riuscito a fare meglio.

Una curiosità, se hai voglia di spiegarmelo.

Ho notato che se uso come metodo per interrompere il fascio del sensore, un terminale di una resistenza, l'avvio è perfetto.
Se invece uso un pezzetto di cartone, che ha una superficie piu larga, noto delle stranezze tipo avvio ritardato, azzeramento del conteggio e altre cosette.

Centra per caso questo?

!oldStato

Ovvero se il livello ALTO permane per troppo tempo, oldStato comincia a oscillare?

Ciao e grazie di nuovo.
Andy

Forse dipende solo da come hai cablato il fototransistor della forcella ... se chiude verso massa o verso VCC ... perche' dipende dal tipo di transizione che legge il programma ...

Ad esempio, se lo hai collegato che chiude verso massa e leggi la transizione da alto a basso, nel momento in cui INTERROMPI il fascio va da basso ad alto, e torna da alto a basso quando il fascio si ripristina ... per cui o leggi l'opposto o cabli il sensore in modo inverso ... si fa prima a leggere l'opposto, in questo caso :wink:

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.