Hi,
I have problem with read falling impuls with width 40ms edge via interrupt and INPUT_PULLUP (like optical interface). The issue is in shape impuls. Impuls has not shape square but trapezoid and then value for all counter is not 1000imp (real value) but 3766 imp (count from arduino UNO)
RISING Edge about 1,5ms (capacitor)
FALLING Edge about 100us
Can you tell mi how set ISR for ignoration RISING a Falling edge for real impuls and get count true value or exist only HW solution ?
Jimmus:
I think you will have issues with bounce. You will have to debounce it on both the falling and rising edges.
Yes - Bingo - My only "now" solution is set interrupt like CHANGE and check level between last and current state edge.
But this solution is very dificutil for processing becouse contains more temporary value and conditions. So i think , that better solution is read only falling edge but issue is value in falling edge. The falling edge is not value like LOW but LOW,LOW,LOW or LOW,LOW , ... and that is problem with native counter in ISR function.
Your code seems to be missing some important parts. Where are oldTime and value declared? scope?
The variable scope is declared like internal value in object via setter
void Reader::setScope(long time = 1000) {
scope=time;
}
And variable oldTime is internal value on Reader which fill via ISR
The way I understand it, this kind of bounce problem is related to the Arduino's definition of high and low. This may vary from chip to chip, but the spec sheet says the "highest value where the pin is guaranteed to be read low" is 0.3 volts, and the "lowest value where the pin is guaranteed to be read high" is 0.6 volts. So there's a range between 0.3 and 0.6 volts where it can't tell if it is high or low. It registers random values. I'm not sure exactly how long your 1.5 mSec rising edge could be in that range, but I would guess about 60 uSec. That is a long time. You may or may not get both rising and falling edge triggers somewhat randomly during that entire time. The only guarantee you have is that there will be at least one rising edge trigger. There may or may not be many more. And there may or may not be many corresponding falling edge triggers as well.
You'll probably get both rising and falling edge triggers on your 100 uSec falling edge, but not as often. And not always.
The way I would handle it is to capture both rising and falling triggers. Keep a status flag so that you know whether you're expecting the next trigger to be rising or falling, and time stamp them. Ignore anything within, say 2 or 5 mSec of the last time stamp.
Also, you can't rely on the current state of the pin. Eventually there will come a time when it will have changed between the time it triggered the interrupt and the time you read it.
Something like this:
Solution via CHANGE mode
void Reader::counter() {
static boolean stateFlag;
unsigned long nowTime = millis();
if (nowTime - oldTime > 5)
{
stateFlag = !stateFlag; // You don't really care what this is. You just have to toggle it.
if (stateFlag)
++value;
}
oldTime = nowTime;
}
Jimmus:
The way I understand it, this kind of bounce problem is related to the Arduino's definition of high and low. This may vary from chip to chip, but the spec sheet says the "highest value where the pin is guaranteed to be read low" is 0.3 volts, and the "lowest value where the pin is guaranteed to be read high" is 0.6 volts. So there's a range between 0.3 and 0.6 volts where it can't tell if it is high or low. It registers random values. I'm not sure exactly how long your 1.5 mSec rising edge could be in that range, but I would guess about 60 uSec. That is a long time. You may or may not get both rising and falling edge triggers somewhat randomly during that entire time. The only guarantee you have is that there will be at least one rising edge trigger. There may or may not be many more. And there may or may not be many corresponding falling edge triggers as well.
You'll probably get both rising and falling edge triggers on your 100 uSec falling edge, but not as often. And not always.
Hi,
goof idea ia testing with other frequency no issue. So finall solution is:
void Reader::counter() { /// => portS0.counter();
static boolean stateFlag;
unsigned long nowTime = millis();
if (nowTime - oldTime > 1)
{
stateFlag = !stateFlag; // You don't really care what this is. You just have to toggle it.
if (stateFlag)
++value;
}
oldTime = nowTime;
}