T3.5 IntervalTimer stopping main loop?

Status
Not open for further replies.

pwhitrow

Member
Hi,

I'm trying to run and update 2 displays using U8G2lib independently of the main program loop using intervalTimer, but this seems to be blocking the main loop or stops it running after the first pass.

Can anyone cast an eye and see what I'm doing wrong, pretty please?


Code:
#include <SPI.h>
#include "U8g2lib.h"

IntervalTimer Displays_Run;

U8G2_SSD1306_128X32_UNIVISION_1_HW_I2C Main_Display(U8G2_R0, SCL, SDA, U8X8_PIN_NONE);
U8G2_SSD1306_64X32_1F_1_SW_I2C Sub_Display(U8G2_R0, 16, 17, U8X8_PIN_NONE);

void setup() {

  Serial.begin(9600);
  while (!Serial && millis() < 2000) ; // wait

  Serial.println("Blah..");

  Main_Display.begin();
  Main_Display.clearDisplay();
  Main_Display.firstPage();
  do {
    Main_Display.setDisplayRotation(U8G2_R2);
    Main_Display.setFont(u8g_font_10x20r);
    Main_Display.drawStr(0, 13, "1");
  } while ( Main_Display.nextPage() );

  Sub_Display.begin();
  Sub_Display.clearDisplay();
  Sub_Display.firstPage();
  do {
    Sub_Display.setFont(u8g_font_10x20r);
    Sub_Display.drawStr(0, 15, "2");
  } while ( Sub_Display.nextPage() );

  delay(1000);

  Displays_Run.begin(Sub_Display_Run, 2500);
  Displays_Run.priority(250);

}

void loop() {
  
  Serial.println("TEST");
  delay(250);

}


void Sub_Display_Run()
{

  Sub_Display.firstPage();
  do {
    Sub_Display.setFont(u8g_font_10x20r);
    Sub_Display.drawStr(0, 15, "3");
  } while ( Sub_Display.nextPage() );

}
 
Looking at : pjrc.com/teensy/td_timing_IntervalTimer.html

this "Displays_Run.begin(Sub_Display_Run, 2500);" is requested to run every 2.5ms … that is 400 times per second. Probably at least 10-20 times too fast depending on the nature of the screen updates.

Unless the display routine is unrealistically fast or only running occasionally it is likely never completing and leaving the interrupt before the next interrupt is ready to be run - so it never gets free time to run loop().

As an interrupt it is generally bad to do such operations within the interrupt - this is an example of one reason as when it takes too long then the rest of the system is frozen and it is not apparent why.

Most likely the delay(250); in loop is just for example purposes - but it is best to never use delay() to stop the loop() from running as fast as it can, but rather watch a time value { like elapsedMillis } for a fixed time passing and then respond. Without that delay the loop() code might cycle hundreds of thousands of times per second on a T_3.5. So the intervalTimer _isr() could set a flag and the display update code could respond for the update. Alternatively the intervalTimer could be skipped and another elspadedMillis value could be watched for display update timing.
 
Timing is everything!

Stupid of me not to realize that, but sometimes you can't see the woods for the trees.

Thank you bud, sorted.
 
Status
Not open for further replies.
Back
Top