Interrupts & Delays

Good Evening,

I’m slowly getting there with my Arduino aquarium monitor, however I’m now having issues capturing a flow rate and then displaying a message on an LCD depending on the value.

Here’s the code so far:

// Include Relevant Libraries
      #include <LiquidCrystal.h>

      const int LcdContrast = 9;

// Initialise LCD Display Pins
      LiquidCrystal lcd(12, 11, A1, A2, A3, A4);
      
int LcdBackLight = 10;
      
// Filter Flow Rate Aquisition & Calculation
      volatile int NbTopsFan;
      int Calc;                               
      int hallsensor = 2;
      int thrshld;
           void rpm ()
          { 
            NbTopsFan++;
          } 

void setup() {
  
// Set Baud Rate
      Serial.begin(9600);
      
// Initialise LCD With Rows & Columns
      lcd.begin(16, 2);

// Set LCD Contrast
      pinMode(LcdContrast, OUTPUT);
      analogWrite(LcdContrast, 20);


// Set Flow Sensor Input & Attach Interrupt
      pinMode(hallsensor, INPUT);
      attachInterrupt(0, rpm, RISING);

}


void loop() 
{
  
          lcd.clear();
        
// Flow Rate Aquisition & Calculation

        NbTopsFan = 0;
        sei();
        delay(1000);
        cli();
        Calc = (NbTopsFan * 60 / 7.5);
     
// Flow Rate Thershold Determination & LCD Display
        thrshld=Calc;
        if(thrshld<4)
        {
        lcd.setCursor(0,0);
        lcd.print("Filter Stopped");
        }
        lcd.setCursor(0,0);
        if(thrshld<8&&thrshld>4)
        {
        lcd.setCursor(0,0);
        lcd.print("Clean Filter");
       }
        if(thrshld<16&&thrshld>8)
        {
        lcd.setCursor(0,0);
        lcd.print("Filter Marginal");
        }
        if(thrshld>16)
        {
        lcd.setCursor(0,0);
        lcd.print("Filter OK");
        }
  
  // Refresh Display Data Every 60 Seconds
        delay (1000);
}

Now, I can display the messages fine using the above code & the Serial Monitor (using Serial.println instead of lcd.print); but when I try to output to the LCD I just have a blank screen.

Reading the forum I can see that I shouldn’t be using delay(1000); within an interrupt and changing this for delayMicroseconds() works (i.e. I get a message on the lcd). However this function is only good for 0.16 seconds and I need a 1 second delay.

So, my question is how can I get around this and have the relevant status message displayed on my lcd?

Many Thanks

Dan

I'm having real problems reconciling "aquarium" and "interrupt"

Ah, well the intention is to prevent 'aquarium interrupts' as the last time that happened I lost most of my fish :-).

Seriously though, perhaps I didn't explain well enough....

I have a hall-effect sensor based flow sensor that will (eventually) sit inline with the discharge from my aquarium filter and once interfaced with my Arduino the system will warn if the unit needs cleaning, or send an SMS should the filter stop (it will also provide temperature and level information and warnings and eventually manage automated water changes and filter flushing).

The code I am using has been adapted from http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1283065018 and I'm using the interrupt to capture the rising edge of the pulses from the sensor and total them over one second (hence the one second delay); I'll then multiply this by 60 to give an effective flow rate in litres per minute that I can then compare to the manufacturer's flow rate for my filter. The intention then is to display a status message on a tank-mounted LCD display and also trigger the backlight in the event of a 'Clean Filter' or 'Filter Stopped' warning to serve as a visual indication.

Hopefully this makes a bit more sense.

Cheers

Dan

As a rule of thum interupts should be handled as fast as possible. So you should not use ANY kind of delay in interrupts unless there is a very good reason for doing so.

You should stop enabling or disabling interrupts in loop(), You should get rid of the delay.

You should look at the blink with delay example. Periodically (that is, every pass through loop), see if a second (or more) has elapsed since last time you reset the interrupt incremented counter. If so, perform your calculation and reset the counter and the last time variable.