Interrupt function not working on MEGA2560

Hi,

I have a rain gauge attached to an Arduino MEGA2560.
The rain gauge switches a hall-effect sensor (A3144).
Under normal circumstances the output is LOW. When the tipping bucket rain gauge tips it brings the Signal pin 18 momentarily to HIGH.
When this happens an interrupt function is called which in turn sets the flag to 1.
Every second a function is called which checks the status of the flag. In case the flag is set it will then add one tip to the total of tips. Well, at least that's the plan. However, I can't see to have it working, no matter what I try. I would really appreciate if somebody can take a look over my code and guide me in the right direction.

My code is part of a much bigger program, which operates without any problems.
Here are the snippets of the relevant code:

For the variable declaration:

//TBRG
  volatile int tbrgPin = 18;      //The TBRG hall-effect switch is connected to this pin
  int tbrgTips = 0;               //TBRG tips counter  
  float tbrgTotal;                //Total amount of precipitation in mm
  int tbrgEvent = 0;              //Flag to be set by interrupt function

For the setup part:

//TBRG
  pinMode(tbrgPin, INPUT_PULLUP);
  bouncer.attach(tbrgPin);
  bouncer.interval(100);      //Interval in ms

For the interrupt:

//Interrupt for when TBRG made a tip
  attachInterrupt(digitalPinToInterrupt(tbrgPin), tbrgISR, FALLING);

For the loop function:

void loop(){
DateTime now = rtc.now(); //get the current date-time    
    if((now.second()) !=  prevSecond ){
    RTC();
    SDDailyStats();  //Call the SDDailyStats function and write to SD-card
    checkForNewDayFunction();
    tbrgFunction();   
     }
    prevSecond = now.second();
    rtc.clearINTStatus();
}

For the ISR:

void tbrgISR() {
    tbrgEvent == 1;  //Set the flag
      if (bouncer.update() && bouncer.read() == LOW) {//Check whether this needs to stay inside the ISR
   tbrgEvent = ! tbrgEvent;
   digitalWrite(tbrgPin, tbrgEvent); }
}

And for the function itself:

void tbrgFunction() { 
   if (tbrgEvent == 1)  {
    Serial.print("It works");
     tbrgTips = tbrgTips++; //Add 1 to current amount of TBRG tips
     tbrgTotal = tbrgTips * 0.2; }  
   tbrgEvent == 0; //Reset the flag and wait for next interrupt to happen
}

I don't know whether the following information could be relevant or not, so, I will include it anyway.
I have a rotary encoder attached as well (To change LCD menus). This works great and has the following code:

//Interrupt for rotary encoder
  PCICR |= (1 << PCIE2);
  PCMSK2 |= (1 << PCINT18) | (1 << PCINT19);//18, 19
  sei();

I copied this code from the forum but don't really understand how it works. However, the end result is great, so, I don't think there's a problem with this.
Anyway, many thanks for your upcoming responses.
Cheers,

Luc

It’s tbrgEvent that needs to be “volatile”, not tbrgPin...

And is that tipping so lightning fast you can't just poll it?

Most HEFs pull LOW when activated, you say yours goes HIGH, but you have your interrupt set to trigger on FALLING. :confused:

To westfw: Thank you so much for this hint; this might well be the problem as my ISR was never called during a tipping event!
I will check and verify tomorrow (When I'm back in the shed)

To septillion: I am scanning 15 sensors every second. Rainfall is sporadic here in Melbourne and when a tip happens it might be in the process of reading other sensors at that time.
It only makes a tip every 5 seconds at the most but the tip happens rather fast before it goes back to low.

To outsider:
I have tried all different options: HIGH, LOW and FALLING. None of them made a difference.
When a tip happens it goes from LOW to HIGH and then to LOW again after a couple of milliseconds.
This has been verified by a digital signal testing probe.

Karma added to all! Many thanks for your help!
Cheers,

Luc

Why are you setting up the interrupt handler the hard way? The attachInterrupt() function does all that stuff for you, AND is KNOWN to do it properly.

     tbrgTips = tbrgTips++; //Add 1 to current amount of TBRG tips

This is undefined behavior.

Use

   tbrgTips++;

or

   tbrgTips = tbrgTips + 1;

If the interrupt handler was not being called, it was NOT because the pin variable was declared volatile. It was because the interrupt handler was not set up correctly, or the hardware is faulty.

OK, I can see that, when the tipper is balanced, the magnet is over the HEF keeping it pulled LOW, when it tips, the magnet is pulled away momentarily letting the HEF go HIGH, but why the INPUT_PULLUP?

To PaulS: I took your advice on board and have changed the code to "tbrgTips = tbrgTips + 1;", thanks!
I'm not sure what you mean by "Why are you setting up the interrupt handler the hard way?" I have to admit I'm not an expert in this at all but have used similar interrupt procedures before and with good results. What would be your recommendation to improve calling this ISR handler?

To outsider: In the normal position the magnet could be sitting either side of the hall-effect sensor and therefore the status on the interruptpin 18 would be LOW. When a tip occurs the magnet moves past the HEF and takes the signal momentarily to HIGH. Once it's passed the HEF it will then go back to LOW.
What would you recommend in this case? Should I make the parameter HIGH, LOW or FALLING? (I read somewhere that RISING is not an accepted condition).
I use INPUT_PULLUP to avoid noise interfering with the pin. It might be overkill but I can't see why it should have an affect on the signal (Unless you tell me otherwise).

Thanks to all!

I made the recommeded changes to my sketch but to no avail.

Here's the program as it is now:

Libraries

#include <OneWire.h>              //DS18B20 temperature sensors
#include <DallasTemperature.h>    //DS18B20 temperature sensors
#include <Wire.h>                 //BME280, RTC DS3231 and LCD 20x4 display
#include "cactus_io_BME280_I2C.h" //BME280
#include "Sodaq_DS3231.h"         //RTC DS3131
#include <SPI.h>                  //SD-Card reader and nRF24L01
#include <SD.h>                   //SD-Card reader
#include <Bounce2.h>              //TBRG debouncing of switch
#include <LiquidCrystal_I2C.h>    //LCD 20x4 display
#include <rotary.h>               //Rotary encoder

Variables

//TBRG
  int tbrgPin = 18;               //The TBRG hall-effect switch is connected to this pin
  int tbrgTips = 0;               //TBRG tips counter  
  float tbrgTotal;                //Total amount of precipitation in mm
  volatile int tbrgEvent = 0;     //Flag to be set by interrupt function

Setup

//TBRG
  pinMode(tbrgPin, INPUT_PULLUP);
  bouncer.attach(tbrgPin);
  bouncer.interval(100);      //Interval in ms

Interrupt

//Interrupt for when TBRG made a tip
  attachInterrupt(digitalPinToInterrupt(tbrgPin), tbrgISR, RISING); //Was FALLING

Loop

void loop(){
DateTime now = rtc.now(); //get the current date-time    
    if((now.second()) !=  prevSecond ){
    RTC();
    SDDailyStats();  //Call the SDDailyStats function and write to SD-card
    checkForNewDayFunction();
    readTempSCFunction();  //Read the temperature sub-routine
    tempMinSCFunction();
    tempMaxSCFunction();
    readHumidityRotronicFunction();
    humidityMaxFunction();
    humidityMinFunction();
    dewPointFunction();
    dewPointMaxFunction();
    dewPointMinFunction();
    blackGlobeFunction();    
    airPressureFunction();
    airPressureMaxFunction();
    airPressureMinFunction();  
    windSpeedFunction();    
    windMaxFunction();
    windRunFunction();
    tbrgFunction();   
    selectLCDMode();
    serialPrint(); //Print to the serial monitor sub-routine
    encoderSwitchMonitor();
    readTempSoilFunction();
    tempMaxSoilFunction();
    tempMinSoilFunction();
    battVoltage(); }
    prevSecond = now.second();
    rtc.clearINTStatus();
}

ISR

void tbrgISR() {
    tbrgEvent == 1;  //Set the flag
      if (bouncer.update() && bouncer.read() == LOW) {//Check whether this needs to stay inside the ISR
   tbrgEvent = ! tbrgEvent;
   digitalWrite(tbrgPin, tbrgEvent); }
}

Function

void tbrgFunction() { 
   if (tbrgEvent == 1)  {
    //Serial.print("It works");
    tbrgTips = tbrgTips + 1;        //Add 1 to current amount of TBRG tips
    tbrgTotal = tbrgTips * 0.2; }  
   tbrgEvent == 0;                  //Reset the flag and wait for next interrupt to happen
}

I have the TBRG connected to pin 18; Is that a true interrupt pin?
Any ideas why it's still not working?
Cheers,

Luc

Is there any reason you have so blinking much code when you have a fundamental problem?

Is there some reason you refuse to test whether attachInterrupt() makes your code work?