Issues with display text persisting even after resetting arduino and display (1.5inch RGB OLED display 128x128px 16-bit)

Hello, I'm running into an issue with a 1.5inch RGB OLED display.

Setup details:

  • Arduino Nano Every
  • Waveshare 1.5RGB Oled
  • Driver/Library: Adafruit_SSD1351
  • Code I am using: Main git repo
    • SimpleUI - Basically a simple factory to act as a wrapper around creating new TextAnchor objects (which is done in the SimpleUI::newAnchor()
    • TextAnchor - This is where all of the logic is at. The SimpleUI is basically there to make it easy to create new TextAnchors with default settings. But the TextAnchor is what handles the prints, cursor, size, color, relocation, etc.

Problem: After uploading the sketch to the Nano Every, it works just fine. Here's how it looks:

But after resetting the Arduino Every (either unplugging the USB or hitting the reset button), it changes to this:

I created an Imgur album with some more photos, and it contains a video of the display as I reset it (video here).

I've tried several things:

  • Resetting the display after restarting the Arduino
  • Removing all but just one of the TextAnchor objects
  • Tried sending some of the SetRemap and StartLine commands manually, as well as using the FillScreen to black before even initializing the TextAnchor objects

I hate sharing the full code like this when asking for advice, since that usually makes it more difficult, but I honestly am not sure where the problem is exactly. If anyone wants to know some more specific details, just let me know and ill include/comment the specific code.

I feel like the display is maybe holding onto some of the old data that it was displaying before the reset, so I figured maybe resetting the oled itself (by grounding the reset pin) would work, or even just unplugging the entire thing for a couple seconds, then plugging it back in would work, but that doesn't seem to fix it at all.

Any input is appreciated. Thanks in advance.

-J

I think that this is a low level effect, affecting the basic display bitmap. Check the driver library for a "clear screen" command.

I did, the closest thing I could find is the fillScreen, and just filling everything to the background color. Related thread here.
In that thread, I saw:

The Adafruit library doesn't clear areas that have not changed,
it rewrites these areas with the same data.
If you selectively rewrite only areas that are modified there will be less flickering.

So just to see if that's what the issue was, I changed the setup() in the .ino file to the following:

void setup() {
  Serial.begin(115200);

  delay(1000);

  pinMode(ENCODER_CLK,INPUT);
  pinMode(ENCODER_DT,INPUT);
  pinMode(ENCODER_SW, INPUT);

  // Read the initial state of CLK
  lastStateCLK = digitalRead(ENCODER_CLK);

  // Call updateEncoder() when any high/low changed seen
  // on interrupt 0 (pin 2), or interrupt 1 (pin 3)
  attachInterrupt(digitalPinToInterrupt(ENCODER_CLK), updateEncoder, CHANGE);
  attachInterrupt(digitalPinToInterrupt(ENCODER_DT), updateEncoder, CHANGE);


  SUI.begin(0x95e7, 0x0000);

  Serial.println("Pausing for 1 sec..");
  delay(1000);
  oled.fillScreen(BLACK);

  oled.fillRect(0, 0, 128, 128, WHITE); 
  delay(500);
  oled.fillRect(0, 0, 128, 128, BLACK); 
  delay(500);

  MillisecondsLabel   = SUI.newAnchor(65, 15)->rightAlign(true)->setColor(DIMGRAY)->print("MS:");
  Milliseconds        = SUI.newAnchor(67, 15)->setColor(0xF800)->print("<ms>");

  MinutesLabel        = SUI.newAnchor(65, 25)->rightAlign(true)->setColor(DIMGRAY)->print("Min:");
  Minutes             = SUI.newAnchor(67, 25)->setColor(0x3666)->print("<min>");

  IterationsLabel     = SUI.newAnchor(65, 35)->rightAlign(true)->setColor(DIMGRAY)->print("Iterations:");
  Iterations          = SUI.newAnchor(67, 35)->setColor(0x4416)->print("<iter>");

  EncoderPosLabel     = SUI.newAnchor(65, 45)->rightAlign(true)->setColor(DIMGRAY)->setHighlightColor(MEDIUMSLATEBLUE)->print("Encoder:");
  EncoderPos          = SUI.newAnchor(67, 45)->setColor(DARKORANGE)
    //->setHighlightColor(ORANGERED)
    ->print("<enco>");

  delay(300);
}

Thinking maybe filling it with black, then using fillRect to fill it with white, then again using fillRect to fill it with black would surely work - it doesn't.
The screen goes black, white black, then the old characters still show, and the new data overwrites it (but is still visible behind it..)

Then they have been stored somewhere else.

Can it be that SUI.newAnchor() does not clear the allocated text buffer?

That could be it, but how can I clear it after a reset? I don't see how it could be cleared before the reset if someone just pulls the plug or hits the reset button.

Consult the library docs.

Yeah, I did, didn't see much in the library im using in regards to clearing the buffer or memory.

However, I may have narrowed it down a bit (maybe..). I have a rightAlign function that allows me to specify a location I want the text to end at, and it will align the right side of the text on that location.

All the rightAlign() function does is set a local private variable:

TextAnchor * TextAnchor::rightAlign( bool rightAlign ){
  if ( rightAlign == _rightAlign )
    return this;
  
  _rightAlign = rightAlign;
  print();

  return this;
}

Then in the print function, I will count how many characters are being printed, and move the cursor over that many characters to the left (thus terminating the print output on the decided location):

TextAnchor * TextAnchor::print( void ){
  // width, height, getRotation, getCursorX, getCursorY 
  uint16_t  colFg = _fgColor, 
            colBg = _bgColor;

  // Removed some irrelevant code about the color

  int diff = 0;

  // If the printed text isn't the same as the text printed last time, then check the difference
  // in length (to override the text that would otherwise show from the side), and update the 
  // _printerValPrev
  if ( strcmp( _printerVal, _printerValPrev ) != 0 ) {
    if ( strlen(_printerValPrev) > strlen( _printerVal ) ){
      diff = strlen(_printerValPrev) - strlen(_printerVal );
    }
  }

  // Pause interrupts while we set the font details and placement. This prevents other
  // updates that may be triggered via an interrupt from unintentionally injecting
  // print values into this location. For example, this happens if a text anchor is 
  // updated in an interrupt function triggered by an encoder (if the encoder is spun
  // too quickly). 
  if ( _allowInterruptPauses == true ) noInterrupts();

  GFXHandler->setTextSize( _textSize );
  GFXHandler->setFont( NULL );

  // If right align is enabled, then set X to be n characters to left of _x,
  // where n = length of _printerVal
  if ( _rightAlign == true ){
    GFXHandler->setCursor( _x - (strlen(_printerVal) + diff) * _fontCharWidth, _y );
  }
  else {
    GFXHandler->setCursor( _x, _y );
  }
  
  GFXHandler->setTextColor( colFg, colBg );

  if ( diff > 0  && _rightAlign == true ){
    for ( int i = 0; diff > i; i++ ){
      GFXHandler->print(" ");
    }
  }

  GFXHandler->print( _printerVal );

  if ( diff > 0  && _rightAlign == false ){
    for ( int i = 0; diff > i; i++ ){
      //std::cout << "\tAdding suffix space #" << i  << std::endl;
      GFXHandler->print(" ");
    }
  }

  // If the printed text isn't the same as the text printed last time, then check the difference
  // in length (to override the text that would otherwise show from the side), and update the 
  // _printerValPrev
  if ( strcmp( _printerVal, _printerValPrev ) != 0 ) {
    _lastChangeMs = millis();

    strcpy(_printerValPrev, _printerVal);
  }

  if ( _allowInterruptPauses == true ) interrupts();

  return this;
}

Im not sure if there's a better way to do right alignment though :-\

Edit: The right alignment only seems to fix the text issue. But it still seems to get stuck when trying to start up.
@DrDiettrich , The code I added to fill the screen with white, then black to clear it, makes it evident that's where it gets stuck as it just goes white, black, shows , then repeats.. Pretty odd.

That only changes the background color, not the text.

I did the fill screen and drew a rectangle from 0,0 to 128,128.

But the fact that it doesn't even start up right kinda tells me something more is going on. Ill do more troubleshooting tomorrow.

To erase these artifacts; Keep track of the data written and the screen location, then "overwrite" the part you want erased with the same data at the same location, but in the background color.

Here's a simulation showing this (just the changing number):

Thanks for this. I did try this on the Nano and it didn't seem to help anything.

However, when switching over to the Uno, it actually all works flawlessly. I intended on using the Uno for this eventually anyways, it's just odd that I couldn't get it working very well on the Nano.

Thanks!

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