Opto Sensore a forcella ->. conteggi multipli

Ciao a tutti,

Per contare il numero di cicli di un movimento meccanico utilizzo una piastrina montata sull’albero lento di un riduttore.

Un sensore a forcella, di cui allego la foto, da un’uscita di 3v quando il fascio luminoso viene interrotto dal passaggio della piastrina ed io tramite un’istruzione attachinterrupt aumento di 1 una variabile …e fin qui tutto bene e funzionante a parte dei conteggi multipli che pare arrivino casualmente e aumentano con l’aumentare della velocità di passaggio.

Pensavo che il problema che si sarebbe posto potesse essere il contrario e cioè la perdita di conteggi, invece ne conto troppi e non riesco a risolverlo.

Ho anche messo, per evitare effetti di debounce, una condizione nella funzione di interrupt che se non sono trascorsi almeno un tot di millisec (350) non deve aumentare la variabile ma questo, oltre a limitare la velocità di acquisizione, non ha risolto (se non in parte) il problema.

Sapete darmi qualche consiglio, grazie

Sergio

image.jpg

posta lo sketch lo schema dei collegamenti e il datasheet del sensore

Ciao, nella funzione dell'interrupt non puoi usare ne delay ne millis ( http://arduino.cc/en/Reference/Interrupts ), se il problema è un rimbalzo allora credo proprio che dovrai provvedere ad effettuarlo via hardware

Ecco la funzione a cui l'interrupt invia:

void FunzConteggio() { // Il seguente ciclo per contare più lentamente anche su piedini diversi da pin2 o pin 3 // sensoreStatePrev = sensoreState; // sensoreState = digitalRead(sensorePin); if ((millis() - tempoRitardoConteggio) > 350 && flag == 1) { conteggio ++; //aumento di uno il conteggio conteggioTotale ++; //aumento di uno il conteggio Totale } if (conteggio >= cicli) {flag = 3; } }

...ma non avevo tenuto conto che millis() non si poteva usare nella funzione di Interrupt ...ora modifico lo sketch attribuendo il tempo attuale è quello trascorso dall'ultimo conteggio fuori dalla funzione ...evete qualche idea su come farlo senza usare troppe flags??? ;)

da dove viene tempoRitardoConteggio?
perché non ci dai lo sketch intero??
Ciao Uwe

Eccolo

#include <EEPROMex.h>
#include <EEPROMVar.h>

#include <genieArduino.h>

#define sensorePin 2 //pin sensore cicli
#define sicurezzaPin 8 //pin ingresso sicurezza
#define motorePin 12 //Fase 1 motore

int keyboardValue;
volatile long conteggio = 0;
int sensoreStatePrev = HIGH;
long int cicli = 1000;
int flag = 0;
int sicurezzaState;
long tempoRitardoConteggio;

// variables will change:
int sensoreState = 0; // variable for reading the pushbutton status

void setup()
{
genieBegin (GENIE_SERIAL, 9600); //Serial1

genieAttachEventHandler(handleGenieEvent);

// initialize the LED pin as an output:
pinMode(motorePin, OUTPUT);
// initialize the pushbutton pin as an input:
pinMode(sensorePin, INPUT);
// definisco il pin dove collego la sicurezza come input:
pinMode(sicurezzaPin, INPUT);

digitalWrite(motorePin, LOW); // tengo il motore spento il motore

pinMode(4, OUTPUT); // Set D4 on Arduino to Output (4D Arduino Adaptor V2 - Display Reset)
digitalWrite(4, 1); // Reset the Display via D4
delay(100);
digitalWrite(4, 0); // unReset the Display via D4

delay (3500); //let the display start up

int cicli3Post = int (cicli % 1000L);
int cicli3Ant = int (cicli / 1000L);
genieWriteObject(GENIE_OBJ_LED_DIGITS, 0x00, cicli3Post);
genieWriteObject(GENIE_OBJ_LED_DIGITS, 0x01, cicli3Ant);
genieWriteObject(GENIE_OBJ_LED_DIGITS, 0x05, cicli3Post);
genieWriteObject(GENIE_OBJ_LED_DIGITS, 0x04, cicli3Ant);

//controllo lo stato del sensore di conteggio per letture veloci solo su piedini 2(0) e 3(1)
pinMode(2, INPUT_PULLUP); //Setto il Pin2 con PullUp per evitare conteggi multipli (rimbalzi)
attachInterrupt(0, FunzConteggio, FALLING); //Sensore di conteggio sul pin 2 attachInterrupt manda alla funzione FunzConteggio
}

void loop (void)
{
genieDoEvents();

if (flag == 1) {
if (conteggio >= cicli) {flag = 3; }
}

if (flag == 3) {
digitalWrite(motorePin, LOW); // spengo fase 1 motore
}

if (flag == 2) {
digitalWrite(motorePin, LOW); // spengo fase 1 motore
}

// Scrivo su Leddigits il numero di cili effettuati
int conteggio1 = int (conteggio % 1000L);
int conteggio2 = int (conteggio / 1000L);
genieWriteObject(GENIE_OBJ_LED_DIGITS, 0x03, conteggio1);
genieWriteObject(GENIE_OBJ_LED_DIGITS, 0x02, conteggio2);

} // fine loop *****

void handleGenieEvent (void)
{
genieFrame Event;
genieDequeueEvent(&Event); // Remove this event from the queue

if(Event.reportObject.cmd == GENIE_REPORT_EVENT)
{
if (Event.reportObject.object == GENIE_OBJ_4DBUTTON)
{
//evento da pulsante 4DBUTTON0 - START
if (Event.reportObject.index == 0x00) {
digitalWrite(motorePin, HIGH); // accendo il motore
flag = 1;
}
//evento da pulsante 4DBUTTON1 - PAUSE
if (Event.reportObject.index == 0x01) {
flag = 2;
}
//evento da pulsante 4DBUTTON1 - STOP
if (Event.reportObject.index== 0x02) {
flag = 3;
conteggio = 0;
}
}
}
}

// solo se usato con attachInterrupt
void FunzConteggio () {
if ((millis() - tempoRitardoConteggio) > 350) {
conteggio++;
tempoRitardoConteggio = millis();
}
}

I TAG CODE non li puoi usare??

Un sensore a forcella, di cui allego la foto, da un'uscita di 3v quando il fascio luminoso viene interrotto dal passaggio della piastrina

Perché da solo 3V? 3 V é la soglia di riconoscimento di un segnale HIGH di un Arduino alimentato a 5V.

Ma Ti funziona il sensore se non usi la libreria genieArduino e mandi i conteggi semplicemente via seriale al terminale del IDE o ancor piú semplice accendi il LED L (pin 13) in funion se la variabile conteggio é pari o dispari ( usando digitalWrite (13,conteggio%1) ?

Quale Arduino e quale display hai?

Ciao Uwe

Grazie innanzitutto per l'aiuto.

Conta correttamente ed il conteggio sul display è uguale a quello che ho in serialWrite (se inserisco il comando)

Non so perché questo sensore dia in uscita solo 3v ma questo è quanto ho trovato come sensore a forcella sul mercato; pensi che il fatto che lavori al limite del riconoscimento possa creare il problema del molteplice conteggio? Non è possibile definire tale limite

...ma il sistema di contaggio con ritardo di 350ms perché non funziona?

Sergiuli: Non so perché questo sensore dia in uscita solo 3v ma questo è quanto ho trovato come sensore a forcella sul mercato; pensi che il fatto che lavori al limite del riconoscimento possa creare il problema del molteplice conteggio? Non è possibile definire tale limite

Allora hanno usato un amplificatore operazionale sulls scheda che non é adatto per questo uso perché non puó dare sull' uscita una tensione vicina a quella di alimentazione (che sono la maggior parte dei Amplificatori) Avrebbero dovuto usare un "Rail to Rail"

Dei sensori a forcella ci sono a tonellate; stasera Ti do un indicazione.

Ciao Uwe

Grazie mille, rimango in attesa

http://it.rs-online.com/web/c/display-e-optoelettronica/accoppiatori-ottici-fotorilevatori-e-fotointerruttori/sensori-ottici-a-forcella/ c'é l' imbarazzo della scelta.

Hanno un LED e un fototransistor nello stesso contenitore. Devi pilotarli come un LED e leggerlo come un fototransistore uguale come un optoisolatore.

Ciao Uwe

Grazie Uwefed, userò sicuramente questi.

Per quanto riguarda la parte conteggio dello sketch, è corretta?