Buongiorno gente, credo argomento già trattato ma cercando non sono riuscito a trovare qualcosa di simile.
Sto tentando di fare un contagiri per la mia pala eolica. Uso il pin 2 dell'UNO R4 WIFI con una resistenza di pulldown di 10K verso GND.
Sto testando semplicemente con un pulsante anzi con un pezzetto di filo dal pin digitale 2 a far contatto sul +5V
Come potete vedere nel codice della callback come "antirimbalzo" assumo 100ms tra un impulso e l'altro e oltre a ciò assumo solo se lo stato del pin è HIGH.
Il comportamento anomalo è:
mi incrementa il pulseCounter anche se stacco il filo (va su LOW) (apro il circuito)
a volte chiudendo il circuito mi da una sfilza di incrementi (nonostante dovrebbero intercorrere 100ms tra uno e altro incremento
Nel progetto finale al pin conta impulsi dovrebbe andarci una fase del generatore che va da 5 a 40V circa (raddrizzata e con un zener 5.1V).
Potete darmi qualche aiuto ? So che come "antirimbalzo" è meglio risolvere via hardware con un condensatore di una decina di nanoF se ben ricordo.
Grazie mille a tutti se mi aiutate
salutone
Mario
Ecco il codice usato per il test e che da il comportamento indesiderato:
unsigned long pulseCounter = 0;
void speedCallback() {
unsigned long tAct = millis();
unsigned long tDelta;
static unsigned long tPrec = 0;
bool inStatus;
inStatus = digitalRead(2);
if (inStatus != HIGH) // assume only transiction to HIGH (if use on CHANGE interrupt))
return;
tDelta = tAct - tPrec;
if (tDelta > 100) { // anti-bumb filter
tPrec = tAct;
pulseCounter++;
}
}
void setup() {
Serial.begin(9600);
Serial.println("Start.....");
pinMode(2, INPUT);
attachInterrupt(digitalPinToInterrupt(2), speedCallback, CHANGE); // non cambia nulla se metto RISING FALLING o altro
}
unsigned long precPulseCounter = -1;
void loop() {
// put your main code here, to run repeatedly:
if (pulseCounter != precPulseCounter) {
Serial.print("Counter:");
Serial.println(pulseCounter);
precPulseCounter = pulseCounter;
}
}
I rimbalzi sono molto rapidi, nell'intervallo di 2ms ci possono essere centinaia di rimbalzi. Prova ad usare micros() al posto di millis(). Ti posto i rimbalzi simulati e ripresi con un analizzatore logico:
Come vedi ci sono rimbalzi sia alla pressione che al rilascio. Occhio ripeto è solo una simulazione, ma la realtà non è molto distante da questa simulazione.
Comunque non ti serve l'antirimbalzo se al posto del contatto meccanico usi un sensore reed e un magnete posizionato sulla girante. Per cui ti basta configurare il trigger dell'interrupt su un solo fronte: FALLING o RISING.
Mauro grazie d.ella risposta. Il segnalo lo prelevo diretramente tra due fasi del generatore tramite un diodo per isolate una semionda un partitore di tensione ed un zener.
Quel che non capisco, nel programma scarto impulsi distanti meno di 10ms ma lo stesso mi passano. Probabilmente la funzione milli non è usabile negli interrupt e bisogna isare micros come da te suggerito.
Oggi provo
Grazie e buona giornata
Ok, avevo intuito, anche in questo caso non è necessaria la gestione del rimbalzo.
Vedo pure io e non vorrei che ci sia un problema con le variabili nello stack, prova con variabili globali anteponendo volatile. Il problema con millis() è che non incrementa durante il tempo in cui la funzione agganciata all'interrupt viene eseguita, ma in questo caso non c'è problema poiché non c'è un while dentro la funzione. Qualcosa per adesso ci sfugge.
Mah, non so, io negli interrupt oltre ad usare sempre variabili "volatile" come sarebbe richiesto, cerco di evitare anche variabili locali e statiche. Inoltre in una ISR memorizzare millis() non serve perché al suo interno il valore di millis() non cambia.
Prova questo e fammi sapere:
Per prendere il segnale al passaggio per lo zero di una tensione sinusoidale serve un trigger di Schmitt, come uno degli inverter di un CD40106, se no il rumore fa prendere impulsi multipli.
Ho spostato tutto fuori dalla callback e fatto volatile e anche usatò micros ma cambia poco. Funziona benissimo solo se metto un tempo tipo 500ms ma a sto punto rischio di perdere impulsi utili. Il generatore fa 4 impulsi giro su ogni fase. E essendo una pala verticale credo max 240 rpm cioè 4 giri secondo 16 impulsi secondo 62ms, cioè eliminate impulsi rimbalzi sotto questo tempo.
Per i normali "bounce" non è possibile, quindi devi per prima cosa capire il tipo di segnale che ti arriva (magari non è una questione di "bounce" ma proprio di rumore) e con questo cercare di trovare una soluzione (hardware o software) altrimenti non ne vieni a capo.
Se hai un oscilloscopio, prova a vedere esattamente come è fatto quel segnale. In caso contrario puoi provare ad usare Arduino stesso con uno sketch di questo tipo collegando il sensore ad un pin analogico, ad esempio A0, ed attivando il plotter seriale (magari aumentando anche la velocità della seriale per evitare che questa possa rallentare il rilevamento):
Non direi, è una semplice soluzione per leggere il segnale con l'MCU. Piuttosto riguardando meglio la simulazione con tensioni diverse in ingresso C1 deve essere più grande, con 1uF sembra funzionare bene. Produce uno sfasamento del segnale, ma è irrilevante per lo scopo, e non credo sia importante squadrarlo più di tanto, gli input digitali hanno già un'isteresi di default.
Argh, hai ragione, stando alla descrizione che l'OP ha postato successivamente, il segnale non è di un sensore classico ma prende il segnale dalla fase del generatore. Quindi si, gli interrupt non c'entrano nulla e tantomeno il "debounce".
Ci fai vedere lo schema per favore? Altrimenti "miagoliamo nel buio" (cit.).
Ecco il partitore. Mi funziona bene per l'ingresso analogico dove misuro la tensione già raddrizzata dopo il ponte diodi trifase ma per il contagiri devo prelevare prima del ponte diodi tra due fasi.
Il stesso partitore lo suso per leggere la tensione da 0->50V max (le tensioni effettive saranno molto più basse)
Ah si, un po O.O.T., ho provato salire con la tensione e il zener non funziona! Mi trovo la tensione più alta. Come prova al posto della 560k ho messo una 10k per le prove e con l'alimentatore pian pianino son salito aspettandomi che all'uscita si fermi a 5.1V invece niente ! 6--7...8V poi mi son fermato (ovvio senza arduino collegato)