Debounced Interrupt Failing counter, Help needed

Hi Guys. I have an interesting project im working on and I cant seem to to get the concept working. I have a flow meter that produces 5-10ms pulses which represents flow rate. I want to measure the pulses with a failing interrupt but make sure its accurate so im trying to use denounced counter to see if it will work.

Setup.
I have a stand alone UNO running blink sketch 5ms on 5ms off out off pin two. Then i have another uno running the following code. The two uno's pin 2s and grounds are connected to each other.

 const byte ledPin = 13;
const byte interruptPin = 2;
volatile byte state = LOW;
volatile int counter;

void setup() {
  Serial.begin(9600);
  pinMode(ledPin, OUTPUT);
  pinMode(interruptPin, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(interruptPin), blink, FALLING);
}

void loop() {
  digitalWrite(ledPin, state);
  my_interrupt_handler();
  Serial.println(counter);
}

void blink() {
  state = !state;
}
void my_interrupt_handler()
{
 static unsigned long last_interrupt_time = 0;
 unsigned long interrupt_time = micros();
 int time_Value = interrupt_time - last_interrupt_time;
 if ( time_Value > 3500 &&  time_Value <20000 ) 
 {
   counter++;
 }
 last_interrupt_time = interrupt_time;
 
}

Its not pretty but its just a test. what im expecting to see in the serial window is the counter counting up reliably but all i get is Zero.

Declare counter as volatile

Hello

declared in volatile same result

Your "interrupt handler" just tests the loop time, not the interrupt time.

aarg:
Your "interrupt handler" just tests the loop time, not the interrupt time.

I see what you mean, but im not sure how to fix it.

Rustie0125:
I see what you mean, but im not sure how to fix it.

You have to keep track of time in the ISR code.

Your "interrupt_handler" does not handle interrupts.

The actual interrupt handler is named blink, and doesn't blink or do anything else useful (like check the time or count).

Why are you confusing yourself with such a strange approach to counting?

I tried to use the interrupt example on the arduino reference page.

does this look better ?

void setup() {
  Serial.begin(9600);
  pinMode(ledPin, OUTPUT);
  pinMode(interruptPin, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(interruptPin), my_interrupt_handler, FALLING);
}

void loop() {
  digitalWrite(ledPin, state);
  Serial.println(counter);
}

void blink() {
  state = !state;
}
void my_interrupt_handler()
{
 static unsigned long last_interrupt_time = 0;
 unsigned long interrupt_time = micros();
 int time_Value = interrupt_time - last_interrupt_time;
 if ( time_Value > 3500 &&  time_Value <20000 ) 
 {
   counter++;
 }
 last_interrupt_time = interrupt_time;
}

Rustie0125:
does this look better ?

It's closer to your stated intent. Does it work? You didn't post the complete program.

No does work.

here is the complete code. Im confusing myself now. :confused:

const byte ledPin = 13;
const byte interruptPin = 2;
volatile byte state = LOW;
volatile int counter;

void setup() {
  Serial.begin(9600);
  pinMode(ledPin, OUTPUT);
  pinMode(interruptPin, INPUT_PULLUP);
  attachInterrupt(2, my_interrupt_handler, FALLING);
}

void loop() {
  digitalWrite(ledPin, state);
  Serial.println(counter);
}

void my_interrupt_handler()
{
 static unsigned long last_interrupt_time = 0;
 unsigned long interrupt_time = micros();
 int time_Value = interrupt_time - last_interrupt_time;
 if ( time_Value > 3500 &&  time_Value <20000 ) 
 {
   counter++;
 }
 last_interrupt_time = interrupt_time;
}
if ( time_Value > 3500 &&  time_Value <20000 )

will ignore pulses with a frequency of greater than 20 seconds...

is that what you really want?

three and a half seconds is an eon in a microcontroller. it seems like you really want something like this:

void my_interrupt_handler()
{
 static unsigned long lastInterruptTime = 0;  // use camel case
 unsigned long interruptTime = micros();
 if ( interruptTime - lastInterruptTime > 50) // start here with 50 milliseconds
 {
   counter++;
   lastInterruptTime = interruptTime;  // reset the timer only if you incremented counter
 }
}

mmm im working in micros not millis so 3500 is not 3,5seconds.

Rustie0125:
mmm im working in micros not millis so 3500 is not 3,5seconds.

yeah, my mistake!

you still should not put the upper limit on the sensor

BulldogLowell:

if ( time_Value > 3500 &&  time_Value <20000 )

will ignore pulses with a frequency of greater than 20 seconds...

is that what you really want?

three and a half seconds is an eon in a microcontroller. it seems like you really want something like this:

void my_interrupt_handler()

{
static unsigned long lastInterruptTime = 0;  // use camel case
unsigned long interruptTime = micros();
if ( interruptTime - lastInterruptTime > 50) // start here with 50 milliseconds
{
  counter++;
  lastInterruptTime = interruptTime;  // reset the timer only if you incremented counter
}
}

The pulses to be counted is 5-10ms in width. so i want to make sure i only catch pulses between 4 to 11ms in width, thats why im working in micros and the 20000 was just to test.

So just trying the code now as suggested by bulldog, and changed the timing to 10ms but im still getting no response from the counter. stays "0" and i know my pulses coming from the other uno is 5ms

const byte ledPin = 13;
const byte interruptPin = 2;
volatile byte state = LOW;
volatile int counter;

void setup() {
  Serial.begin(9600);
  pinMode(ledPin, OUTPUT);
  pinMode(interruptPin, INPUT_PULLUP);
  attachInterrupt(2, my_interrupt_handler, FALLING);
}

void loop() {
  digitalWrite(ledPin, state);
  Serial.println(counter);
}

void my_interrupt_handler()
{
 static unsigned long lastInterruptTime = 0;  // use camel case
 unsigned long interruptTime = micros();
 if ( interruptTime - lastInterruptTime < 10000) // start here with 50 milliseconds
 {
   counter++;
   lastInterruptTime = interruptTime;  // reset the timer only if you incremented counter
 }
}

you reversed the test:

if ( interruptTime - lastInterruptTime < 10000) // start here with 50 milliseconds

should be:

if ( interruptTime - lastInterruptTime > 10000) // now 10 milliseconds

right? you want to ignore any signal that comes in before 10milliseconds have elapsed since the last trigger.

No I want to catch all signal between 5ms and 10ms window. for now i want to catch all pulses shorter then 10ms.

Rustie0125:
No I want to catch all signal between 5ms and 10ms window. for now i want to catch all pulses shorter then 10ms.

your ISR is detecting the FALLING edge. so, you are measuring the frequency of the pulse, not the length of the pulse.

Is this a continuous signal that simply varies the pulse width?

if so, you ought to consider using pulseIn() and polling the sensor on a regular interval.

Let me give you the application.

The flow sensor gives me pulses the pulse change in frequency the faster the flow. every pulse is x cubic meters of water and each pulse is 5ms in width. So i want to count all the pulses and make sure that there is no missed or false pulses. o and maximum output of the senor is 100hz

Rustie0125:
Let me give you the application.

The flow sensor gives me pulses the pulse change in frequency the faster the flow. every pulse is x cubic meters of water and each pulse is 5ms in width. So i want to count all the pulses and make sure that there is no missed or false pulses.

ok, then you want to capture and count every pulse (you can use the rising or falling edge). My experience says that these do not behave like switches and you don't need to debounce. did you try just incrementing your counter on the falling edge?

void my_interrupt_handler()
{
   counter++;
}

what happens?