adafruit / Adafruit-GFX-Library

Adafruit GFX graphics core Arduino library, this is the 'core' class that all our other graphics libraries derive from
https://learn.adafruit.com/adafruit-gfx-graphics-library
Other
2.42k stars 1.55k forks source link

SSD1351 skipping lines #288

Open caternuson opened 4 years ago

caternuson commented 4 years ago

Several cases:

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

makermelissa commented 4 years ago

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 commented 4 years ago

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.

CCDengineer commented 4 years ago

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.

nygma2004 commented 4 years ago

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

makermelissa commented 4 years ago

Thanks, I have a D1 mini.

makermelissa commented 4 years ago

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).

nygma2004 commented 4 years ago

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 
LittleSpark55 commented 4 years ago

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

}
makermelissa commented 4 years ago

@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 commented 4 years ago

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.

snail23 commented 1 year ago

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.

makermelissa commented 1 year ago

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.