Flickering too much ... help! SSD1351 128X128 RGB OLED Arduino UNO

During the quarantine/riot and trash our monuments season of 2020, I decided to go on the trip around the Okefenokee Swamp (in south Georgia, USA) on my solar powered 1kW bike. I always wanted to see the beautiful birds and wildlife around the area. This is my chance.

I want to see the incoming/outgoing current and battery voltage on the 128x128 RGB OLED SSD_1351 display. I got the code working on a smaller display (.92 ssd_1306 I2C) but when I went with a bigger screen (128x128 RGB ssd_1351 SPI) same code would not work anymore. The refresh/redrawing of the graphs causes the flickering effect. I am told that Adafruit display library code is supposed to clear only the new information and leave old information such as graph axis without changes thus reducing flicker.

Please help or at least point me to a right direction- I promise to name a bird after you! :slight_smile:

PS. Below is an approximation of what I want to see on my screen.

// This program is for drawing a chart and moving dots (illusion of moving wave) to display voltages or current levels
// Arduino UNO and SSD1351 128X128 RGB OLED display
// 6/17/2020
// Screen dimensions
#define SCREEN_WIDTH  128
#define SCREEN_HEIGHT 128 
  // You can use any (4 or) 5 pins 
#define SCLK_PIN 13
#define MOSI_PIN 11
#define DC_PIN   9
#define CS_PIN   8
#define RST_PIN  7
  // Color definitions
#define BLACK           0x0000
#define BLUE            0x001F
#define RED             0xF800
#define GREEN           0x07E0
#define CYAN            0x07FF
#define MAGENTA         0xF81F
#define YELLOW          0xFFE0  
#define WHITE           0xFFFF
#include <SPI.h>
#include <Wire.h>
#include "SPI.h"                    // YT Includes library for SPI communication of display
#include <Adafruit_GFX.h>           //Includes core graphics library
#include <Adafruit_SSD1351.h>       //Includes hardware specific library
  //Library declaration
Adafruit_SSD1351 display = Adafruit_SSD1351(SCREEN_WIDTH, SCREEN_HEIGHT, &SPI, CS_PIN, DC_PIN, RST_PIN);
byte count;
byte sensorArray[128];
byte drawHeight;
char filled = 'D'; //decide either filled or dot display (F or D = dot, any else filled)
char drawDirection = 'R'; //decide drawing direction, from right or from left (L=from left to right, any else from right to left)
char slope = 'W'; //slope colour of filled mode white or black slope (W=white, any else black. Well, white is blue in this dispay but you get the point)
     
void setup(void) 
  {
       Serial.begin(9600);
       //Serial.print("InSETUP");
       display.begin();
       display.fillScreen(0x0000);  // This clears entire screen (BLACK)
  }

void loop() {      
  //This section puts moving dots on chart (voltage or current levels)  
  drawHeight = map(analogRead(A0), 0, 1023, 4, 64 );  //  0Min/1023Max (on chart), 4Min/64Max (limits of moving dots) 
  sensorArray[0] = drawHeight;                        //vertical limit of moving dots

  for (count = 1; count <= 80; count++ )              //80  Position of moving chart start
  {
    if (filled == 'D' || filled == 'd')
    {
      if (drawDirection == 'L' || drawDirection == 'l')
      {
        display.drawPixel(count, 64 - sensorArray[count - 1], BLUE);      // BLACK,BLUE,RED,GREEN,CYAN,MAGENTA,YELLOW,WHITE              
      }
      else //else, draw dots from right to left
      {
        display.drawPixel(80 - count, 64 - sensorArray[count - 1], CYAN); //  <--- active BLACK,BLUE,RED,GREEN,CYAN,MAGENTA,YELLOW,WHITE
      }
    }
    else
    {
      if (drawDirection == 'L' || drawDirection == 'l')
      {
        if (slope == 'W' || slope == 'w')
        {
          display.drawLine(count, 64, count, 64 - sensorArray[count - 1], WHITE);  // BLACK,BLUE,RED,GREEN,CYAN,MAGENTA,YELLOW,WHITE
        }
        else
        {
          display.drawLine(count,  1, count, 64 - sensorArray[count - 1], WHITE);    
        }
      }
      else
      {
        if (slope == 'W' || slope == 'w')
        {
          display.drawLine(80 - count, 64, 80 - count, 64 - sensorArray[count - 1], WHITE); // BLACK,BLUE,RED,GREEN,CYAN,MAGENTA,YELLOW,WHITE
        }
        else
        {
          display.drawLine(80 - count,  1, 80 - count, 64 - sensorArray[count - 1], WHITE);  
        }
      }
    }
   }
  
 draw_Chart_Axis();  //Draws chart borders & tickmarks  
  //######################################
  //*********   PROBLEM AREA       PROBLEM AREA             PROBLEM AREA            
  //display.display();        //exit status 1 'class Adafruit_SSD1351' has no member named 'display'
  //display.clearDisplay();   //error: 'class Adafruit_SSD1351' has no member named 'clearDisplay'; did you mean 'invertDisplay'?
            //*********   PROBLEM AREA       PROBLEM AREA             PROBLEM AREA        
  //display.display();        //needed before anything is displayed.. from  <Adafruit_SSD1306.h> library //this works on smaller OLED  
  //display.clearDisplay();   //clear before new drawing..            from  <Adafruit_SSD1306.h> library //this works on smaller OLED              
               /* Clearing the entire display causes flickering.
                  This is why the Adafruit library has less flicker. 
                  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.- 
                  Bill Greiman   fat16lib@sbcglobal.net
               */
  //-----  trying to "clear" screen without causing graph to flicker --------
  //tft.fillScreen(0x0000);               //Attempt 1: blacks out graph...still flickers
  //tft.fillRect(0, 0, 128, 128, BLACK);  //Attempts2: blacks out graph...still flickers
  //######################################
  for (count = 80; count >= 2; count--)   // count down from 160 to 2           
    {
    sensorArray[count - 1] = sensorArray[count - 2];
    }
}

 void draw_Chart_Axis()         // Draws chart axis.
{  
  display.setCursor(90, 0);     // changing all display. to tft.
  display.setTextSize(1);
  display.setTextColor(WHITE);  // BLACK,BLUE,RED,GREEN,CYAN,MAGENTA,YELLOW,WHITE
  display.print(drawHeight-4);  // Numerical value  
  display.setCursor(90, 8);
  display.setTextSize(1);
  display.setTextColor(WHITE);  // BLACK,BLUE,RED,GREEN,CYAN,MAGENTA,YELLOW,WHITE
  display.print("KM/h");        // Label will change to volts
  display.drawLine( 0, 0,  0, 60, WHITE);   //  64//32 );  // Left  Vert line on graph Horiz/Vertical
  display.drawLine(80, 0, 80, 60, WHITE);   //  64//32 );  // Right Vert line on graph
  for (count = 0; count < 70; count += 10)   //40-> 60  //Number of horiz marks
      {
    display.drawLine(80, count, 75, count, WHITE);   //Length / Position of RIGHT horiz marks,
    display.drawLine( 5, count,  0, count, WHITE);   //Length / Position of LEFT  horiz marks,
      }
  for (count = 10; count < 80; count += 10)   //80  Num of Horiz Pixels 
      {
    display.drawPixel(count,  0 , WHITE);   // Horizontal dots on graph
    display.drawPixel(count, 30 , WHITE);   //30
    display.drawPixel(count, 60 , WHITE);   //60
      }
}

IMG_1356.jpg

OK, so you already know two problems. :grinning:

One is clearing the entire display when you only want to change part of it.

The other is drawing something on every pass through the loop, rather than determining whether you need to actually draw anything which was already there on the last pass through the loop. You only ever draw anything when you need to alter the display.

Finally read the instructions (point No. 7) to understand how to post code. :roll_eyes:

Paul__B:
understand how to post code.

And getting rid of some of that insulting whitespace would be a good idea.

Nick_Pyner:
And getting rid of some of that insulting whitespace would be a good idea.

Well, I was using the shorthand version.

Here is the full version: :grinning:


OK, first things first.

You need to go and read the forum instructions so that you can go back and modify your original post (not re-post it) - using the "More -> Modify" option below the right hand corner of your post - to mark up your code as such using the "</>" icon in the posting window. Just highlight each section of code (or output if you need to post that) from the IDE and click the icon.

In fact, the IDE itself has a "copy for forum" link to put these markings on a highlighted block for you so you then just paste it here in a posting window. But even before doing that, don't forget to use the "Auto-Format" (Ctrl-T) option first to make it easy to read. If you do not post it as "code" it can easily be quite garbled and is always more difficult to read due to the font.

It is inappropriate to attach it as a ".ino" file unless it is clearly too long to include in the post proper. People can usually see the mistakes directly and do not want to have to actually load it in their own IDE. And even that would also assume they are using a PC and have the IDE running on that PC.

Also tidy up your blank space. Do use blank lines, but only single blanks between complete functional blocks.

Hello littlespark55,
I had the same problem with text. Not sure if this helps with graphics but for text use for example:

display.setTextColor(WHITE, BLACK);

BLACK being the background colour. When you do that the background is set to black and text to white, no need to clear anything just print what you want without first clearing what was there before. The background will be correctly cleared, no flashing.

If I get a better answer for graphics I'll post that too.

I confirm everything, indeed it is necessary to make sure that the "sketch" only works if a digit of the number is changed compared to before,
then overwrite it with the background color and then rewrite it as usual

elrospo:
then overwrite it with the background color and then rewrite it as usual

You should read reply #4 more closely.

Nick_Pyner:
You should read reply #4 more closely.

however I have solved it! everything that must be displayed and that is different from what already exists on the display is "deleted" by writing it with the background color and then writing the new value,
no matter if it is a number, a word or the two flashing dots of a digital clock,
obviously the code is much more complicated to write, and on this display it is the only acceptable system I have found (for now)

The code in #0 just uses the regular Adafruit_GFX 7x5 system font.
setTextColor(foreground_color, background_color) will draw a fresh background with each letter.

The Adafruit_GFX FreeXXX fonts can only be drawn in transparent mode. You have no choice. You have to repaint the background color before writing new text.

Yes, it is more fiddly. But you only have to write a single "helper" function.

David.

elrospo:
it is the only acceptable system I have found (for now)

Indeed, and when you have read reply#4 again, twice, you are likely to find a better system. You may be right about the digital clock dots but, even then, not necessarily. That may depend on whether the dots are a colon or a graphic.

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