2 years, 6 months ago.

Display some data LCD in interrupt routine.

Hi ! Recently, I start to use Nucleo-f303RE Board. and I'm trying interrupt method. I read Mbed document and others.

How to display LCD in interrupt Right way? My case, LCD now working & Stucked..

my code is below.

Interrupt function

void flip()
{
   //my calculate code here 

    if (counter == 20 && data_effect) {
        counter = 0;
        sum();
        lcd_print(); //display textLCD

    } else if (counter != 20 && data_effect) {
        counter++;
        led = !led;
    } else {
        counter = 0;
        data_effect = 1;
    }
}

display lcd function

void lcd_print()
{
    lcd.locate(1,0);
    lcd.printf("HR : %d", heart_rate);
}

Sum function before display lcd

void sum()
{
    if (data_effect) {
        heart_rate = 1200000 / (temp[20] - temp[0]); //60*20*1000/20_total_time
        //Serial.print("Heart_rate_is:\t");
        //printf("%d\n\r", heart_rate);
        //lcd_print(heart_rate);
        //hr_signal.rise(&flip);
        //hr_signal.rise(NULL);
        //lcd.locate(0,0);
        //lcd.printf("HR : %d", heart_rate);
       // !!! all way is stucked
    }
    data_effect = 1; //sign bit
    //hr_signal.rise(&flip);
}

Main Function

int main()
{
    t.start();
    arrayInit();
    hr_signal.rise(&flip);
    lcd.setBacklight(TextLCD::LightOn);
  
    lcd.cls();
    lcd.locate(0,1);
    lcd.printf("HR : %d", i);

    while(1) {
    }
}
  • I'm not able to test your code because some variables are not declared and some functions not defined -> It does not compile.
  • Could you please explain in more details what does

Quote:

"LCD now working & Stucked.."

mean?

posted by Zoltan Hudak 08 Mar 2018

I believe it is still the case, that you should not call printf from inside an interrupt (assuming you are using mbed 5 with rtos). The mutexs protecting it do not work from within an interrupt context. Rule of thumb for an interrupt routine is to do absolutely as little work as possible. Get in, handle signal, and get out. What is hr_signal? If possible, just poll this from the main while loop.

while(1) {   
 if (hr_signal == 1){
    // do stuff
  }
  Thread::wait(10);
}

If you have to use Interrupt, then use the ISR to set a boolean variable. e.g. bool signal = true; Make the variable global and volatile. Then poll this variable in main - similar idea to above except you are using the ISR to ensure you capture the rising edge. I think the rtos events class can be used to do something similar. Can also use a queue as well as a way to defer work out of an ISR context. Make a new thread that waits on the queue and just handles new events when they happen.

posted by Graham S. 09 Mar 2018

Thanks All !

posted by PARK JAICHANG 21 Mar 2018
Be the first to answer this question.