LCD display inside a TimerInterrupt

In my program on Arduino I use a TimerInterrupt. In this TimerIntrrupt I try to display on a LCD the values returned by the methods I call. Unfortunately nothing is displayed on the LCD and I don't know where the error is in my program. Does anyone have an idea of the error? How can I handle to solve the problem?

class Sensor {

    float _flowRateTrinkwasser;
    unsigned long _wasserMengeTrinkwasser;
    float _flowRateReinwasser;
    unsigned long _wasserMengeReinwasser;

  public:
    Sensor( float flowRateTrinkwasser,  unsigned long wasserMengeTrinkwasser,  float flowRateReinwasser,  unsigned long wasserMengeReinwasser) {           // Konstruktor
      _flowRateTrinkwasser = flowRateTrinkwasser;
      _wasserMengeTrinkwasser = wasserMengeTrinkwasser;

      _flowRateReinwasser = flowRateReinwasser;
      _wasserMengeReinwasser = wasserMengeReinwasser;

    }

    int get_f_ml1 () {
      _flowRateTrinkwasser = 120;    // Formel zur Berechnung von Flow Rate
      _wasserMengeTrinkwasser = 50;
      int f_ml1 = _flowRateTrinkwasser +  _wasserMengeTrinkwasser ;
      return f_ml1;
    }


    int get_f_ml () {
      _flowRateReinwasser = 70;
      _wasserMengeReinwasser = 40;
      int f_ml = _flowRateReinwasser +  _wasserMengeReinwasser ;
      return f_ml;
    }

};

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include "test.h"

//Durchflussmessung Variable Trinkwasser//
float flowRateTrinkwasser;
unsigned long wasserMengeTrinkwasser;

//Durchflussmessung Variable Trinkwasser//

//Durchflussmessung Variable Reinwasser//

float flowRateReinwasser;
unsigned long wasserMengeReinwasser;

//Durchflussmessung Variable Reinwasser//

Sensor sensorOne(  flowRateTrinkwasser, wasserMengeTrinkwasser, flowRateReinwasser, wasserMengeReinwasser );  // Objekt vom Konstruktor Sensor1

LiquidCrystal_I2C lcd(0x27, 20, 4);

void setup() {
  Serial.begin(9600);
  lcd.init();
  lcd.backlight();
  lcd.setCursor(0, 0);
  lcd.println("Willkommen bei Truu");
  delay(2000);
  lcd.clear();

  cli(); // disable interrupts
  // reset
  TCCR1A = 0; //set TCCR1A register to 0000
  TCCR1B = 0; //set TCCR1B register to 0
  TCNT1 = 0; // reset counter value
  OCR1A = 15624; //compare match register für 1 Sekunde (15624pulse vorher)
  // set prescaler
  TCCR1B |= (1 << CS12) | (1 << CS10);
  TCCR1B |= (1 << WGM12); //turn on CTC mode
  TIMSK1 |= (1 << OCIE1A); // enable timer compare interrupt
  sei(); //allow interrupts
}

void loop() {
 
}

ISR(TIMER1_COMPA_vect) { // function which will be called when an interrupt occure at timer 1
 lcd.setCursor(0,0);
 lcd.println(sensorOne.get_f_ml1());
 lcd.setCursor(0,1);
  lcd.println(sensorOne.get_f_ml());
  delay(50);
}

The problem is almost certainly that the LCD library uses interrupts and they are disabled when in an ISR

Have the ISR set a flag variable and do the LCD output in loop()

My concern is that in the loop I will write the program for the operation of a system. The TimerInterrupt allows me to perform measurements of certain parameters in parallel at specific time intervals. LCD help me to show values of the measures parameter

You can still use the timer to make the measurements at specific time intervals then display the results in loop() when a new measurement has been made

You will, of course, be writing the loop() function such that it does not block the execution of the program which would prevent the timely display of the values

1 Like

If these measurements also involves the I2C bus (as the LCD does) you cannot do them in the interrupt handler because inside these handlers interrupts are disabled and many library functions (p.e. Wire, Serial, etc.) depend on interrupts to work. If you ignore that your sketch may freeze at any time.

The solution UKHeliBob pointed out requires you to have a responsive loop(), so use millis() instead of delay() (see example BlinkWithoutDelay for details).

You shouldn't need interrupts. As long as you write your loop() function not to block (like using delay() or calling a function that uses delay()) you can accomplish a lot using millis() to compare to previous stored milliseconds in order to accomplish timed operations.

Indeed, NOTHING happens in parallel unless you have a multi-core processor, which you do not. Even interrupts interrupt the code currently processing, hence the term "interrupt". Interrupts should execute as fast as possible. Interrupts allow fast response to latency sensitive events. For example, removing a value from a comm buffer before it gets full.

thanks everybody for your explanations. I change my programm and diplay the values in the loop. Now it work very good

And NEVER use delay() in an ISR! That can cause your whole program to hang.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.