attachInterrupt problem?

Hi, are there any known problems with attachInterrupt?

I think I may have found one while working on my weather station project, but I know I need to demonstrate it in the simplest possible way, so that there is no doubt (in my head or anyone else’s) that the problem really exists. I’ve run out of time to do that tonight, so I thought I’d just ask the question and work on it tomorrow evening.

The problem may be:

attachInterrupt(rainGuagePin, rainGuageEvent, RISING);

seems to behave exactly the same as:

attachInterrupt(rainGuagePin, rainGuageEvent, CHANGE);

in that the interrupt seems to be getting triggered on both rising and falling edges, when I only want rising.

I have a rain guage attached to pin D3. The rain guage contains a “see-saw” mechanism which causes a magnet to sweep past a reed switch. My interrupt function contains code to debounce the sensor:

volatile unsigned long rainEvents = 0;
volatile unsigned long nextRainEvent = 0;

void rainGuageEvent() {
    unsigned long m = millis();
    if (m > nextRainEvent) {
        rainEvents++;
        nextRainEvent = m + 10;
    }
}
...
    pinMode(rainGuagePin, INPUT_PULLUP);
    attachInterrupt(rainGuagePin, rainGuageEvent, RISING);

Each time the rain guage “tips”, it should cause 1 rising and 1 falling edge, as long as my debounce code is working. So rainEvents should get incremented by 1 each time the see-saw tips. But it increments by 2. If I change “RISING” to “CHANGE”, it behaves exactly the same.

Tomorrow I will try to demonstrate the issue with the simplest possible circuit and code I can devise. I will attach a digital pin (set as OUTPUT) to another digital pin (set as an INPUT, with interrupt attached). I can then write a very small program to toggle the output pin and see how many times the interrupt is triggered.

If I’m making a fool of myself, could someone please point this out before I waste time chasing any wild geese!

Paul

@PaulRB
I haven’t dug into this example/problem much, but shouldn’t the pin be set to a PULLDOWN if one expects to trigger interrupts on rising edge?

Hi @mohit,

No, not necessarily. If the switch pulls the pin to ground, you need PULLUP. If the switch pulls the pin to +V, you need PULLDOWN. (In my case, the sensor pulls the pin to ground.) Either way, you should be able to trigger an interrupt on the RISING only, FALLING only or both edges as required.

So, this evening I have set up an incredibly simple circuit. With the spark on an otherwise empty breadboard, I connected D0 and D2 together, then flashed this code:

void interruptFunction() {
    
    Serial.println("Interrupt!");
}


void setup() {
    
    Serial.begin(38400);
    
    pinMode(D2, OUTPUT);
    digitalWrite(D2, LOW);
    
    pinMode(D0, INPUT);
    attachInterrupt(D0, interruptFunction, RISING);

}

void loop() {
    
    Serial.println("Setting D2 HIGH...");
    digitalWrite(D2, HIGH);
    Serial.println("Setting D2 LOW...");
    digitalWrite(D2, LOW);
    Serial.println("Done.");
    delay(5000);

}

And here are the results:

Setting D2 HIGH...
Interrupt!
Setting D2 LOW...
Done.

And for "CHANGE" instead of "RISING", the results are:

Setting D2 HIGH...
Interrupt!
Setting D2 LOW...
Interrupt!
Done.

So in fact its working exactly as it should. I need to go back to my debounce code and do some more adjusting...

Please accept my humble apologies for the false alarm!

And well done and thanks to you and the whole team for this excellent product you've worked so hard on.

Paul

I think if you connected an oscilloscope or logic analyzer to your interrupt pin, you would see your reed switch bouncing for longer than the 10 milliseconds you allow for. Typically, the gauge measures 4 points per “see-saw” (or at least that’s what mine does) so even in heavy rain, I don’t think you need to sweat milliseconds too much.

I agree with @pra, most mechanical switches need at least 30ms debounce time to be safe in my experience. But like anything you want working well, you have to analyze exactly what problem you are trying to overcome… and make it as failsafe as it needs to be :wink:

Hi @pra,
It took a debounce period of around 100ms to prevent double-counts from the rain guage. I am using the same period for the anemometer at the moment, which is giving 4 interrupts per revolution. I am concerned that such a long period could become a problem at high wind speeds, so I will experiment with lowering it.

Thanks for the advice.

4 Legitimate interrupts per revolution or is that what you are getting via debounces? I imagine the reed switch bouncing occurs as the magnet approaches and then leaves the region of the switch when the magnetic ield is relatively weak. With the range gauge these periods will be relatively constant, but with a variable speed anemometer they will change with wind speed. It will require some investigation and fine tuning to get right. I assume you have a different interrupt pin for the anemometer so you can have different debounce timing for each. You might also investigate using a hall effect transistor as the magnetic detector instead of a reed switch and that would probably get rid of the debounce issue completely.

I believe I read somewhere that with this type of sensor there are two regions in a revolution where the magnet actuates the reed switch. So I am getting an interrupt on entry and exit of each of the 2 regions.

Maybe, maybe. I wanted to get the whole thing working with a simple and inexpensive sensor, then eventually, in the future, think about building a more interesting sensor. Building an ultrasonic, combined windspeed & direction sensor might be interesting. Or a Rotorvane Anemometer.