Adafruit-GFX-Library icon indicating copy to clipboard operation
Adafruit-GFX-Library copied to clipboard

SSD1351 skipping lines

Open caternuson opened this issue 5 years ago • 12 comments

Several cases:

  • https://forums.adafruit.com/viewtopic.php?f=47&t=165405
  • https://forums.adafruit.com/viewtopic.php?f=47&t=163320
  • https://forums.adafruit.com/viewtopic.php?f=19&t=162264

with SSD1351 based 1.5" color OLED: https://www.adafruit.com/product/1431

caternuson avatar May 14 '20 19:05 caternuson

Something I noticed looking at those posts, it looks like this is specific to 8-bit processors (drawing code varies by proc type sometimes).

makermelissa avatar Jun 08 '20 17:06 makermelissa

I have been unable to reproduce this yet. I have tried an ESP32, Metro 328, and even an old Arduino Diecimila (I don't own a genuine uno or nano). I've tried the graphics test using both hardware and software SPI and the imagereader examples and those all worked perfectly. So there must be something I'm missing here.

makermelissa avatar Jun 08 '20 22:06 makermelissa

I have this issue with a new genuine UNO Rev3. The problem seems to have been introduced between versions 1.1.1 and 1.2.0 of the ssd1351 library. The test program works fine if I revert back to the 1.1.1 version.

CCDengineer avatar Jun 09 '20 15:06 CCDengineer

I received my SSD1351 1.5 recently, and I am having the same issue. I have the 1.2.4 version installed. I am testing it on a Wemos D1 mini with the following pin assignments: #define SCLK_PIN 14 #define MOSI_PIN 13 #define DC_PIN 5 #define CS_PIN 4 #define RST_PIN 3

nygma2004 avatar Jun 11 '20 20:06 nygma2004

Thanks, I have a D1 mini.

makermelissa avatar Jun 11 '20 20:06 makermelissa

Tested with D1 Mini and it still is not skipping lines. This is an odd one that seems to affect only certain displays. Unless there were a couple different versions of the display or something, I'm not sure what the difference would be. I mean I guess it's possible somebody's libraries or Board Support Package may not be completely up to date. Another possibility is perhaps there's an older set of libraries overriding these such as the outdated ones that were being included with the Teensy software (I'm not sure if they still are).

makermelissa avatar Jun 16 '20 22:06 makermelissa

Hi Melissa, I did not know that these can have such an impact on the compiled code. So I have updated everything. I downloaded the latest version of IDE which is 1.8.13 at the moment. I have gone into the board manager and updated all the board manager definitions and also updated all my libraries (even though the Adafruit was already up-to-date). I recompiled the code and it is working now.

Just for reference to anyone else, I am using this 1.5 inch 128x128 OLED screen from ICStation.com. And for anyone who stumbles upon this issue, this is the wiring I used, and these are the only lines that I have modified in the example sketch:

// Wiring on a Wemos D1 Mini (ESP8266)
// GND -> GND
// Vcc -> 3.3v
#define SCLK_PIN 14   // SCL -> D5
#define MOSI_PIN 13   // SCA -> D7
#define DC_PIN   5    // DC  -> D1
#define CS_PIN   4    // CS  -> D2
#define RST_PIN  3    // RES -> RX 

nygma2004 avatar Jun 17 '20 06:06 nygma2004

Hello good people, I am somewhat a newbie here... making a solar-powered bike computer here for a trip around the Okefenokee swamp. https://en.wikipedia.org/wiki/Okefenokee_Swamp

I've copied and slightly modified some code and got it to work on small .96 OLED using the ssd1306 library. Then got a larger 1.5in (128x128), ssd1351 OLED. My screen needs to be refreshed and redrawn (code line 124) but it fails and gives me an "'class Adafruit_SSD1351' has no member named 'display' " and display.clear(); also errors out. How do I clear without flickering? I read that "The Adafruit library doesn't clear areas that have not changed, it rewrites these areas with the same data."

// 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 OLED display
// 6/17/2020

// Screen dimensions
#define SCREEN_WIDTH  128
#define SCREEN_HEIGHT 128 

// U8GLIB_SSD1351_128X128_332 u8g(   13,        11,      8,      9,         7); 
// Arduino UNO: SW SPI Com:    SCK = 13, MOSI = 11, CS = 8, A0 = 9, RESET = 7 

// 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


 
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   [email protected]
               */

  //-----  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
{  
  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


  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
      }
  
}

LittleSpark55 avatar Jun 19 '20 06:06 LittleSpark55

@LittleSpark55, for issues with updating your code, the forums would probably be better suited to your needs and doesn't appear to be related to this issue.

As for the failing lines of code, I don't think you need to call the display() function, nor does it exist and maybe try calling display.fillScreen(BLACK); to clear the screen. I think the main difference is that the SSD1306 probably uses a FrameBuffer due to being small and monochrome whereas this one doesn't. I'd suggest looking at the included examples for how it's done for this display.

Also, I formatted your code so it was easier to read on here.

makermelissa avatar Jul 27 '20 16:07 makermelissa

I'm going to close this issue because it seems to be related to using outdated dependencies and I have been unable to reproduce otherwise. With updated libraries it solves the issue, so there's not really anything we can do on the library itself. It's possible that there are some outdated versions of libraries installed with other packages such as the Teensy and these should probably be evaluated on a case-by-case basis.

makermelissa avatar Jul 27 '20 17:07 makermelissa

This issue still exists in 2023 using all of the latest library versions. Board is a Daisy Seed, STM32H7 MCU, and WaveShare SSD1351 display. I draw bitmaps as well as text on my device and this issue is happening with both.

snail23 avatar Feb 16 '23 00:02 snail23

Hi @snail23, I can open this again for now. Just to see if the issue has reappeared, I can test it out on one of our SSD1351 displays and maybe something like the Adafruit Feather STM32F405 Express. However, if I'm not seeing the lines issue, it may either be related to the STM32H7 or WaveShare's display, of which I have neither nor can officially support.

I'm working on wrapping up some other projects and I don't have easy access to either board at the moment due to limited mobility, so it may be a bit before I can actually get around to testing.

makermelissa avatar Feb 16 '23 16:02 makermelissa