OLED (SSD1322) display goes blank when using h/w interrupts?!

Hi Everyone,

So not sure if anyone remembers, I bought this BuyDisplay 3.2inch SSD1322 over 6 months ago and had a hard time getting it to work using Oliver's (fantastic) u8g2 library. After troubleshooting it with him I had to set the clock speed down. All was well again in the world.

(Reference link below)

...

Fast forward to today, where I am continuing on with the next phase of my project - using hardware interrupts to measure RPM. I have bought the 12v signal down from the car to respectable levels for the arduino's input requirements. I am running a Mega and was using pin 18 as the PWM input pin.

When I start the Mega up, I commence a start up sequence screen that takes around 8 seconds or so and the screen during this time works flawlessly. However, as soon as it goes through the first few loops, the screen just goes completely blank and wont come back on without cycling the power.

I actually do get to see it reading the correct RPM on the screen for perhaps 1 second, before it just completely goes blank.

The reason I suspect its to do with the interrupts is, when I commented out the interrupt-related lines (one attachInterrupt line in the end of the setup() routine and the noInterrupts() and Interrupts() lines in the main loop). Once these are commented out, the screen will stay working (obviously not showing me my RPM).

Has anyone has any problems like this before? I've tried reducing the clock speed down significantly, tried only refreshing the screen every 5 or so loops, added delays to see if its something of that nature but nothing has worked, besides completely commenting out anything to do with interrupts. I've tried all pins from 18,19,20,21 but to no avail.

Any ideas? I can show you my code if you feel it might help analysing the issue.

Cheers,
Adam

If you can deal with only alpha numeric characters, use Bill Greimans SSD1306ASCII library. Its much smaller and may not get upset if interrupts are in use for other needs.

Hi John,
Thanks for the suggestion. Is that library able to easily print lines and boxes, etc? Reason being I do actually have an attractive aesthetics surrounding the display of the RPM as its replacing stock analogue gauges in a car so it also needs to look somewhat respectable. I'd really like to be able to get this working somehow using u8g2 as my preference. I'm so damn close yet this last 5% of effort currently eludes me... sigh
Cheers,

No it is only ASCII and only the first 128 char. Which is what allows it to be so small.

Hi All,
I've managed to get it to read correctly for about 5 seconds now, before the screen just goes blank and never comes back on unless is power cycled. Any ideas? The delay (500) was just at the end of the loop as a test. I had no delay and it makes no difference really.
Cheers,
Adam

#include <SPI.h>
#include <U8g2lib.h>

U8G2_SSD1322_NHD_256X64_F_4W_HW_SPI oled_obd(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
//U8G2_SSD1322_NHD_256X64_F_4W_SW_SPI oled_obd(U8G2_R0, /* clock=*/ 52, /* data=*/ 51, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);  // Enable U8G2_16BIT in u8g2.h

#define temp_width 25
#define temp_height 22
static const unsigned char temp[] U8X8_PROGMEM = {
  0x00, 0x38, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00,
  0x00, 0xF8, 0x03, 0x00, 0x00, 0xF8, 0x03, 0x00, 0x00, 0x38, 0x00, 0x00,
  0x00, 0x38, 0x00, 0x00, 0x00, 0xF8, 0x03, 0x00, 0x00, 0xF8, 0x03, 0x00,
  0x00, 0x38, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0xF8, 0x03, 0x00,
  0x00, 0xF8, 0x03, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00,
  0x00, 0x7C, 0x00, 0x00, 0x9E, 0x7C, 0xF2, 0x00, 0xE1, 0x7C, 0x0E, 0x01,
  0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9C, 0xEF, 0x73, 0x00,
  0xE0, 0x38, 0x0E, 0x00,
};

#define e36_width 91
#define e36_height 57
static const unsigned char e36[] U8X8_PROGMEM = {
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0xC0, 0xFF, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x00, 0x00, 0x00,
  0x00, 0x00, 0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x00, 0x00, 0x00,
  0x00, 0x00, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0x00, 0x00,
  0x00, 0x00, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00,
  0x00, 0x00, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00,
  0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x00,
  0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x00,
  0x00, 0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00,
  0x00, 0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00,
  0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0x00, 0x00,
  0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0x00, 0x00,
  0x00, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x00, 0x00,
  0x00, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x00, 0x00,
  0xC0, 0xC3, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0x1E, 0x00,
  0xE0, 0xCF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x9F, 0x3F, 0x00,
  0xE0, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDF, 0x3F, 0x00,
  0xE0, 0xE7, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x3F, 0x3F, 0x00,
  0xC0, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x1F, 0x00,
  0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x03, 0x00,
  0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0x00,
  0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00,
  0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00,
  0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00,
  0x00, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x02, 0x00,
  0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x04, 0x00,
  0x00, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x04, 0x00,
  0x80, 0x40, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x07, 0x00, 0x10, 0x08, 0x00,
  0x80, 0xF0, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0x7F, 0x08, 0x00,
  0x80, 0xF8, 0x70, 0x18, 0xFC, 0x07, 0xFF, 0xC1, 0x70, 0xF8, 0x08, 0x00,
  0x40, 0x7C, 0x26, 0x10, 0xAA, 0x8A, 0xAA, 0x42, 0x20, 0xF3, 0x11, 0x00,
  0x40, 0x7C, 0xAF, 0x10, 0xAA, 0x8A, 0xAA, 0x42, 0xA8, 0xF7, 0x11, 0x00,
  0x40, 0x7E, 0x26, 0x13, 0xAA, 0x8A, 0xAA, 0x42, 0x26, 0xF3, 0x13, 0x00,
  0x60, 0xFF, 0x70, 0x08, 0xAA, 0x8A, 0xAA, 0x82, 0x70, 0xF8, 0x37, 0x00,
  0x20, 0x00, 0x00, 0x00, 0xAA, 0x8A, 0xAA, 0x02, 0x00, 0x00, 0x20, 0x00,
  0xE0, 0xFF, 0xFF, 0x7F, 0xFC, 0x07, 0xFF, 0xF1, 0xFF, 0xFF, 0x3F, 0x00,
  0x20, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x20, 0x00,
  0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x00,
  0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x00,
  0x30, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0x7F, 0x00, 0x00, 0x00, 0x60, 0x00,
  0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00,
  0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00,
  0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00,
  0xF0, 0x03, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x07, 0x00, 0x00, 0x7E, 0x00,
  0x70, 0xFC, 0xCF, 0x83, 0xFF, 0xFF, 0xFF, 0x0F, 0x9E, 0xFF, 0x71, 0x00,
  0x70, 0xE0, 0xDF, 0x87, 0xFF, 0xFF, 0xFF, 0x0F, 0xDF, 0x3F, 0x70, 0x00,
  0x70, 0xC0, 0xDF, 0x07, 0xFF, 0xFF, 0xFF, 0x07, 0xDF, 0x1F, 0x70, 0x00,
  0x70, 0x80, 0x9F, 0x07, 0xFE, 0xFF, 0xFF, 0x03, 0xCF, 0x0F, 0x70, 0x00,
  0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00,
  0xF0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x00,
  0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x00,
  0xE0, 0xFF, 0xFF, 0x3F, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0xFF, 0x3F, 0x00,
  0xC0, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x1F, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};


unsigned long tempInTime = 0;
int rpm;
unsigned long curMillis;

volatile uint32_t g_isrElapsedTicks;
volatile bool g_bTachTickFlag;
uint32_t g_ElapsedTicks;
float fRPM;

void setup()
{
  tempInTime = millis() - 31000;

  SPI.setDataMode(SPI_MODE0);
  //SPI.setClockDivider(SPI_CLOCK_DIV128);
  oled_obd.setBusClock(1800000);

  SetPinOutputMode();

  attachInterrupt(digitalPinToInterrupt(18), CalcPeriod, RISING);

  oled_obd.begin();
  oled_obd.clear();
  oled_obd.setContrast(0);
  oled_obd.setFontMode(0);

  InitSequenceA();
  delay(800);
  InitRpmLeds();
  InitSequenceB();

  oled_obd.clearBuffer();
}

void CalcPeriod()
{
  static bool g_bFirstTickFlag = true;            
  static uint32_t lastTick;                           
  uint32_t nowTick;

  if (g_bFirstTickFlag == true)
  {
    lastTick = micros();
    g_bFirstTickFlag = false;
  }
  else
  {
    nowTick = micros();
    g_isrElapsedTicks = nowTick - lastTick;
    lastTick = nowTick;
    g_bTachTickFlag = true;
  }
}

void loop()
{
  if (g_bTachTickFlag)
  {
    detachInterrupt(digitalPinToInterrupt(18));
    g_bTachTickFlag = false;
    g_ElapsedTicks = g_isrElapsedTicks;
    attachInterrupt(digitalPinToInterrupt(18), CalcPeriod, RISING);

    fRPM = 30.0 * ( 1.0 / ((float)g_ElapsedTicks * 1.0e-06) );
    if ( fRPM <= 450.0 )
      fRPM = 0.0;

  }

  curMillis = millis();

  oled_obd.setFont(u8g2_font_artossans8_8r);

  // Just diplay the RPM and some temps..
  oled_obd.drawStr(165, 57, "RPM");

  oled_obd.drawLine(28, 5, 159, 5);
  oled_obd.drawLine(28, 5, 28, 9);
  oled_obd.drawLine(61, 5, 61, 9);
  oled_obd.drawLine(94, 5, 94, 9);
  oled_obd.drawLine(126, 5, 126, 9);
  oled_obd.drawLine(159, 5, 159, 9);

  oled_obd.drawLine(28, 56, 159, 56);
  oled_obd.drawLine(28, 56, 28, 52);
  oled_obd.drawLine(61, 56, 61, 52);
  oled_obd.drawLine(94, 56, 94, 52);
  oled_obd.drawLine(126, 56, 126, 52);
  oled_obd.drawLine(159, 56, 159, 52);

  oled_obd.drawStr(177, 12, "EXT --");
  oled_obd.drawStr(233, 12, "C");

  if (curMillis - tempInTime > 30000)
  {
    tempInTime = curMillis;
    oled_obd.drawStr(177, 27, "INT");
    oled_obd.setCursor(209, 27);
    int val;                  //Create an integer variable
    int intemp;               //Variable to hold a temperature value
    val = analogRead(0);      //Read the analog port 0 and store the value in val
    intemp = Thermister(val); //Runs the fancy math on the raw analog value
    oled_obd.print(intemp);
  }

  oled_obd.drawStr(233, 27, "C");
  oled_obd.setFont(u8g2_font_4x6_tr);
  oled_obd.drawStr(227, 8, "o");
  oled_obd.drawStr(227, 23, "o");

  oled_obd.setFont(u8g2_font_7Segments_26x42_mn);

  rpm = (int)fRPM;
  if (rpm > 0 && rpm < 1000)
  {
    String rpmStr = String(rpm);
    rpmStr = String("0" + rpmStr);
    oled_obd.setCursor(33, 52);
    oled_obd.print(rpmStr);
  }
  else
  {
    oled_obd.setCursor(33, 52);
    oled_obd.print(rpm);
  }

  oled_obd.drawXBMP(210, 36, temp_width, temp_height, temp);
  oled_obd.sendBuffer();

  delay(500);

  DrawLeds(rpm);
}

int Thermister(int RawADC) {  //Function to perform the fancy math of the Steinhart-Hart equation
  double Temp;
  Temp = log(((10240000 / RawADC) - 10000));
  Temp = 1 / (0.001129148 + (0.000234125 + (0.0000000876741 * Temp * Temp )) * Temp );
  Temp = (Temp - 273.15);              // Convert Kelvin to Celsius
  //Temp = (Temp * 9.0)/ 5.0 + 32.0; // Celsius to Fahrenheit - comment out this line if you need Celsius
  return (int)Temp;
}

void SetPinOutputMode()
{
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(7, OUTPUT);
  pinMode(11, OUTPUT);
  pinMode(12, OUTPUT);

  pinMode(10, OUTPUT);
  pinMode(9, OUTPUT);
  pinMode(8, OUTPUT);
}

void InitSequenceA()
{
  // Splash screen
  oled_obd.drawXBMP(27, 3, e36_width, e36_height, e36);
  oled_obd.sendBuffer();
  delay(300);
  oled_obd.setFont(u8g2_font_artossans8_8r);
  oled_obd.drawStr(122, 14, "BMW DIGITAL");
  oled_obd.drawStr(122, 24, "SYSTEMS 1996");
  oled_obd.sendBuffer();
  delay(300);
  oled_obd.drawLine(108, 28, 221, 28);
  oled_obd.sendBuffer();
  oled_obd.drawLine(221, 24, 221, 28);
  oled_obd.sendBuffer();
  delay(250);
  oled_obd.setFont(u8g2_font_10x20_tf);
  oled_obd.drawStr(126, 51, "1 GUP 563");
  oled_obd.sendBuffer();
}

void InitSequenceB()
{
  // Just diplay the RPM and some temps..
  oled_obd.clear();
  oled_obd.setFont(u8g2_font_artossans8_8r);
  oled_obd.drawStr(165, 57, "RPM");
  oled_obd.drawStr(177, 27, "INT");
  oled_obd.drawStr(177, 12, "EXT");
  oled_obd.drawXBMP(210, 36, temp_width, temp_height, temp);
  oled_obd.sendBuffer();
  delay(50);

  oled_obd.drawLine(28, 5, 159, 5);
  oled_obd.sendBuffer();
  delay(50);

  oled_obd.drawLine(28, 56, 159, 56);
  oled_obd.sendBuffer();
  delay(50);

  oled_obd.drawLine(28, 5, 28, 9);
  oled_obd.drawLine(28, 56, 28, 52);
  oled_obd.sendBuffer();
  delay(50);

  oled_obd.drawLine(61, 5, 61, 9);
  oled_obd.drawLine(61, 56, 61, 52);
  oled_obd.sendBuffer();
  delay(50);

  oled_obd.drawLine(94, 5, 94, 9);
  oled_obd.drawLine(94, 56, 94, 52);
  oled_obd.sendBuffer();
  delay(50);

  oled_obd.drawLine(126, 5, 126, 9);
  oled_obd.drawLine(126, 56, 126, 52);
  oled_obd.sendBuffer();
  delay(50);

  oled_obd.drawLine(159, 5, 159, 9);
  oled_obd.drawLine(159, 56, 159, 52);
  oled_obd.sendBuffer();
  delay(50);

  oled_obd.setFont(u8g2_font_7Segments_26x42_mn);
  oled_obd.drawStr(33, 52, "0   ");
  oled_obd.sendBuffer();
  delay(50);
  oled_obd.drawStr(33, 52, " 1  ");
  oled_obd.sendBuffer();
  delay(50);
  oled_obd.drawStr(33, 52, "  2 ");
  oled_obd.sendBuffer();
  delay(50);
  oled_obd.drawStr(33, 52, "   3");
  oled_obd.sendBuffer();
  delay(50);
  oled_obd.drawStr(33, 50, "  4 ");
  oled_obd.sendBuffer();
  delay(50);
  oled_obd.drawStr(33, 52, " 5  ");
  oled_obd.sendBuffer();
  delay(50);
  oled_obd.drawStr(33, 52, "6   ");
  oled_obd.sendBuffer();
  delay(50);
  oled_obd.drawStr(33, 52, " 7  ");
  oled_obd.sendBuffer();
  delay(50);
  oled_obd.drawStr(33, 52, "  8 ");
  oled_obd.sendBuffer();
  delay(50);
  oled_obd.drawStr(33, 52, "   9");
  oled_obd.sendBuffer();
  delay(50);
  oled_obd.drawStr(33, 52, "    ");
  oled_obd.sendBuffer();
  delay(50);
}

void DrawLeds(int rpm)
{
  if (rpm >= 0 && rpm < 1000) {
    analogWrite(2,  20);
    analogWrite(3,  0);
    analogWrite(4,  0);
    analogWrite(5,  0);
    analogWrite(6,  0);
    analogWrite(7,  0);
    analogWrite(11, 0);
    analogWrite(12, 0);
  }
  else if (rpm >= 1000 && rpm < 1500) {
    analogWrite(2,  20);
    analogWrite(3,  20);
    analogWrite(4,  0);
    analogWrite(5,  0);
    analogWrite(6,  0);
    analogWrite(7,  0);
    analogWrite(11, 0);
    analogWrite(12, 0);
  }
  else if (rpm >= 1500 && rpm < 2000) {
    analogWrite(2,  20);
    analogWrite(3,  20);
    analogWrite(4,  20);
    analogWrite(5,  0);
    analogWrite(6,  0);
    analogWrite(7,  0);
    analogWrite(11, 0);
    analogWrite(12, 0);
  }
  else if (rpm >= 2000 && rpm < 3000) {
    analogWrite(2,  20);
    analogWrite(3,  20);
    analogWrite(4,  20);
    analogWrite(5,  20);
    analogWrite(6,  0);
    analogWrite(7,  0);
    analogWrite(11, 0);
    analogWrite(12, 0);
  }
  else if (rpm >= 3000 && rpm < 4000) {
    analogWrite(2,  20);
    analogWrite(3,  20);
    analogWrite(4,  20);
    analogWrite(5,  20);
    analogWrite(6,  15);
    analogWrite(7,  0);
    analogWrite(11, 0);
    analogWrite(12, 0);
  }
  else if (rpm >= 4000 && rpm < 5000) {
    analogWrite(2,  20);
    analogWrite(3,  20);
    analogWrite(4,  20);
    analogWrite(5,  20);
    analogWrite(6,  15);
    analogWrite(7,  15);
    analogWrite(11, 0);
    analogWrite(12, 0);
  }
  else if (rpm >= 5000 && rpm < 6000) {
    analogWrite(2,  20);
    analogWrite(3,  20);
    analogWrite(4,  20);
    analogWrite(5,  20);
    analogWrite(6,  15);
    analogWrite(7,  15);
    analogWrite(11, 15);
    analogWrite(12, 0);
  }
  else if (rpm >= 6000 && rpm < 7000) {
    analogWrite(2,  20);
    analogWrite(3,  20);
    analogWrite(4,  20);
    analogWrite(5,  20);
    analogWrite(6,  15);
    analogWrite(7,  15);
    analogWrite(11, 15);
    analogWrite(12, 15);
  }
  else {
    analogWrite(2,  0);
    analogWrite(3,  0);
    analogWrite(4,  0);
    analogWrite(5,  0);
    analogWrite(6,  0);
    analogWrite(7,  0);
    analogWrite(11, 0);
    analogWrite(12, 0);
  }
}

void InitRpmLeds()
{
  // cycle on
  analogWrite(2,  20); delay(125);
  analogWrite(3,  20); delay(125);
  analogWrite(4,  20); delay(125);
  analogWrite(5,  20); delay(125);
  analogWrite(6,  15); delay(125);
  analogWrite(7,  15); delay(125);
  analogWrite(11, 15); delay(125);
  analogWrite(12, 15); delay(125);

  // cycle off
  analogWrite(12, 0); delay(125);
  analogWrite(11, 0); delay(125);
  analogWrite(7,  0); delay(125);
  analogWrite(6,  0); delay(125);
  analogWrite(5,  0); delay(125);
  analogWrite(4,  0); delay(125);
  analogWrite(3,  0); delay(125);
  analogWrite(2,  0); delay(125);
}

What are you doing here ?

unsigned long tempInTime = 0;
. . .
void setup()
{
  tempInTime = millis() - 31000;
  . . .
}

tempInTime will be a very large number when millis() is close to 0, as it would be at the beginning of setup().

I am intrigued by the vast quantity of repeated sequences.
You will find life much easier if you write helper functions and simple loops.

You seem to have a Mega2560. So there is plenty of SRAM for a full 2048 byte SSD1322 buffer. And plenty of room for "vast" code.

I would avoid using String. U8glib expects char[ ] or uint8_t[ ]. And there are much nicer ways of formatting the rpmStr. Just say what you actually want e.g. 001, 01, 099, 0100, ...

David.

Hi, it looks like it was my feeble attempt at making something only happen every 30 seconds or so. Completely commenting this out looks to have no bearing on the issue.

Lol, thanks for your intrigue. Life is quite easy actually when you write it yourself. a) I'm not writing this code for a production release of something professional and b) I'm not even remotely finished. I've just hit a roadblock that I'm unable to get past and thought id post my code to see if something is glaringly obvious.

Regarding sending a full buffer and it being a Mega, I was under the impression i'm already sending a full buffer, hence the use of the F constructor at the top (U8G2_SSD1322_NHD_256X64_F_4W_HW_SPI) and using sendBuffer() instead of doing it paging style. If you are unclear on why I drawStr many times and then do sendBuffer in chunks, its for visual effect during the start up sequence.

Thanks for the tip on avoiding using String with u8g2. Seems to work just fine though?

It frustrates me to post in here sometimes. I ask about a certain question and don't get any response to do with the problem at hand. Just responses protesting violations against programming principles. Anyway thanks for your response. I still have the same problem I had before but I guess I learnt something about string usage, how to name variables appropriately, and that I should use functions and loops when appropriate.

If anyone is interested, it seems that putting setPowerSave(0) at the end of the loop allows the screen to start working again once it goes dark/blank! This is not ideal as it "flashes" when it stops then starts working again. It does this perhaps once every 10 or so seconds (random) but as soon as I start to rev the engine to say 2500 or past 3000 the screen violently blinks randomly on and off with much quicker frequency, all the while an accurate rpm is being displayed in between flashes. Strange.