anzeigeprobleme sh1106 oled *gelöst*

Moin Moin,

ich bin relativer arduino neuling und konnte bislang für alle meine probleme hier im forum eine lösung finden, aber bei meinem jetzigen problem scheine ich alle darzustehen.

kurz und knackig:

ich möchte ein 128x64 oled über i2c betreiben (zuerst einmal nur die beispiel skatches)

gestest an:
elegoo uno r3 & china nano klon → gleches problem
es sind zwei gleiche display vorhanden → beide das gleiche problem
mit der ssd_103 und GOFi2cOLED → gleiches problem

die anpassung in der ssd_103 ist mit bekannt-> gleiches problem

es wird auf beiden displays immer nur im oberen viertel angezeigt, dafür da aber sauber.
ich verstehe das einfach nicht -_-

sind die display einfach defekt oder habe ich was wesentliches übersehen?

Hallo,
wie sollen wir dir helfen, wenn du uns verschweigst, welches Display (Link des Displays) du verwendest und welche Library (Link zur Library) du verwendest.
Und dann darfst du einfach deinen verwendeten Sketch hier posten.

Setze den in Code-Tags (Schaltfläche <>) oben links im Editorfenster verwenden.

schon der erste aha effekt: ich dachte das es “nur den einen” driver gibt. damit ist schonmal klar das das eigentliche problem vor dem bildschirm sitzt :smiley:

das display:
http://www.ebay.de/itm/192046939365

in der beschreibung steht ja das “eine” adresse geändert werden soll, aber die des display kann es ja nicht gemeint sein da die daten dann nicht mehr ankommen.

zuzeit nutze ich dieses hier:

erster teil vom sketch

This is an example for our Monochrome OLEDs based on SSD1306 drivers

  Pick one up today in the adafruit shop!
  ------> http://www.adafruit.com/category/63_98

This example is for a 128x64 size display using I2C to communicate
3 pins are required to interface (2 I2C and one reset)

Adafruit invests time and resources providing this open source code, 
please support Adafruit and open-source hardware by purchasing 
products from Adafruit!

Written by Limor Fried/Ladyada  for Adafruit Industries.  
BSD license, check license.txt for more information
All text above, and the splash screen must be included in any redistribution
*********************************************************************/

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);

#define NUMFLAKES 10
#define XPOS 0
#define YPOS 1
#define DELTAY 2


#define LOGO16_GLCD_HEIGHT 16 
#define LOGO16_GLCD_WIDTH  16 
static const unsigned char PROGMEM logo16_glcd_bmp[] =
{ B00000000, B11000000,
  B00000001, B11000000,
  B00000001, B11000000,
  B00000011, B11100000,
  B11110011, B11100000,
  B11111110, B11111000,
  B01111110, B11111111,
  B00110011, B10011111,
  B00011111, B11111100,
  B00001101, B01110000,
  B00011011, B10100000,
  B00111111, B11100000,
  B00111111, B11110000,
  B01111100, B11110000,
  B01110000, B01110000,
  B00000000, B00110000 };

#if (SSD1306_LCDHEIGHT != 64)
#error("Height incorrect, please fix Adafruit_SSD1306.h!");
#endif

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

  // by default, we'll generate the high voltage from the 3.3v line internally! (neat!)
  display.begin(SSD1306_SWITCHCAPVCC, 0x3c);  // initialize with the I2C addr 0x3D (for the 128x64)
  // init done
  
  // Show image buffer on the display hardware.
  // Since the buffer is intialized with an Adafruit splashscreen
  // internally, this will display the splashscreen.
  display.display();
  delay(2000);

  // Clear the buffer.
  display.clearDisplay();

  // draw a single pixel
  display.drawPixel(10, 10, WHITE);
  // Show the display buffer on the hardware.
  // NOTE: You _must_ call display after making any drawing commands
  // to make them visible on the display hardware!
  display.display();
  delay(2000);
  display.clearDisplay();

  // draw many lines
  testdrawline();
  display.display();
  delay(2000);
  display.clearDisplay();

  // draw rectangles
  testdrawrect();
  display.display();
  delay(2000);
  display.clearDisplay();

  // draw multiple rectangles
  testfillrect();
  display.display();
  delay(2000);
  display.clearDisplay();

  // draw mulitple circles
  testdrawcircle();
  display.display();
  delay(2000);
  display.clearDisplay();

  // draw a white circle, 10 pixel radius
  display.fillCircle(display.width()/2, display.height()/2, 10, WHITE);
  display.display();
  delay(2000);
  display.clearDisplay();

  testdrawroundrect();
  delay(2000);
  display.clearDisplay();

  testfillroundrect();
  delay(2000);
  display.clearDisplay();

  testdrawtriangle();
  delay(2000);
  display.clearDisplay();
   
  testfilltriangle();
  delay(2000);
  display.clearDisplay();

  // draw the first ~12 characters in the font
  testdrawchar();
  display.display();
  delay(2000);
  display.clearDisplay();

  // draw scrolling text
  testscrolltext();
  delay(2000);
  display.clearDisplay();

  // text display tests
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(0,0);
  display.println("Hello, world!");
  display.setTextColor(BLACK, WHITE); // 'inverted' text
  display.println(3.141592);
  display.setTextSize(2);
  display.setTextColor(WHITE);
  display.print("0x"); display.println(0xDEADBEEF, HEX);
  display.display();
  delay(2000);
  display.clearDisplay();

  // miniature bitmap display
  display.drawBitmap(30, 16,  logo16_glcd_bmp, 16, 16, 1);
  display.display();
  delay(1);

  // invert the display
  display.invertDisplay(true);
  delay(1000); 
  display.invertDisplay(false);
  delay(1000); 
  display.clearDisplay();

  // draw a bitmap icon and 'animate' movement
  testdrawbitmap(logo16_glcd_bmp, LOGO16_GLCD_HEIGHT, LOGO16_GLCD_WIDTH);
}


void loop() {
  
}

zweiter teil vom sketch

void testdrawbitmap(const uint8_t *bitmap, uint8_t w, uint8_t h) {
  uint8_t icons[NUMFLAKES][3];
 
  // initialize
  for (uint8_t f=0; f< NUMFLAKES; f++) {
    icons[f][XPOS] = random(display.width());
    icons[f][YPOS] = 0;
    icons[f][DELTAY] = random(5) + 1;
    
    Serial.print("x: ");
    Serial.print(icons[f][XPOS], DEC);
    Serial.print(" y: ");
    Serial.print(icons[f][YPOS], DEC);
    Serial.print(" dy: ");
    Serial.println(icons[f][DELTAY], DEC);
  }

  while (1) {
    // draw each icon
    for (uint8_t f=0; f< NUMFLAKES; f++) {
      display.drawBitmap(icons[f][XPOS], icons[f][YPOS], bitmap, w, h, WHITE);
    }
    display.display();
    delay(200);
    
    // then erase it + move it
    for (uint8_t f=0; f< NUMFLAKES; f++) {
      display.drawBitmap(icons[f][XPOS], icons[f][YPOS], bitmap, w, h, BLACK);
      // move it
      icons[f][YPOS] += icons[f][DELTAY];
      // if its gone, reinit
      if (icons[f][YPOS] > display.height()) {
        icons[f][XPOS] = random(display.width());
        icons[f][YPOS] = 0;
        icons[f][DELTAY] = random(5) + 1;
      }
    }
   }
}


void testdrawchar(void) {
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(0,0);

  for (uint8_t i=0; i < 168; i++) {
    if (i == '\n') continue;
    display.write(i);
    if ((i > 0) && (i % 21 == 0))
      display.println();
  }    
  display.display();
  delay(1);
}

void testdrawcircle(void) {
  for (int16_t i=0; i<display.height(); i+=2) {
    display.drawCircle(display.width()/2, display.height()/2, i, WHITE);
    display.display();
    delay(1);
  }
}

void testfillrect(void) {
  uint8_t color = 1;
  for (int16_t i=0; i<display.height()/2; i+=3) {
    // alternate colors
    display.fillRect(i, i, display.width()-i*2, display.height()-i*2, color%2);
    display.display();
    delay(1);
    color++;
  }
}

void testdrawtriangle(void) {
  for (int16_t i=0; i<min(display.width(),display.height())/2; i+=5) {
    display.drawTriangle(display.width()/2, display.height()/2-i,
                     display.width()/2-i, display.height()/2+i,
                     display.width()/2+i, display.height()/2+i, WHITE);
    display.display();
    delay(1);
  }
}

void testfilltriangle(void) {
  uint8_t color = WHITE;
  for (int16_t i=min(display.width(),display.height())/2; i>0; i-=5) {
    display.fillTriangle(display.width()/2, display.height()/2-i,
                     display.width()/2-i, display.height()/2+i,
                     display.width()/2+i, display.height()/2+i, WHITE);
    if (color == WHITE) color = BLACK;
    else color = WHITE;
    display.display();
    delay(1);
  }
}

void testdrawroundrect(void) {
  for (int16_t i=0; i<display.height()/2-2; i+=2) {
    display.drawRoundRect(i, i, display.width()-2*i, display.height()-2*i, display.height()/4, WHITE);
    display.display();
    delay(1);
  }
}

void testfillroundrect(void) {
  uint8_t color = WHITE;
  for (int16_t i=0; i<display.height()/2-2; i+=2) {
    display.fillRoundRect(i, i, display.width()-2*i, display.height()-2*i, display.height()/4, color);
    if (color == WHITE) color = BLACK;
    else color = WHITE;
    display.display();
    delay(1);
  }
}
   
void testdrawrect(void) {
  for (int16_t i=0; i<display.height()/2; i+=2) {
    display.drawRect(i, i, display.width()-2*i, display.height()-2*i, WHITE);
    display.display();
    delay(1);
  }
}

void testdrawline() {  
  for (int16_t i=0; i<display.width(); i+=4) {
    display.drawLine(0, 0, i, display.height()-1, WHITE);
    display.display();
    delay(1);
  }
  for (int16_t i=0; i<display.height(); i+=4) {
    display.drawLine(0, 0, display.width()-1, i, WHITE);
    display.display();
    delay(1);
  }
  delay(250);
  
  display.clearDisplay();
  for (int16_t i=0; i<display.width(); i+=4) {
    display.drawLine(0, display.height()-1, i, 0, WHITE);
    display.display();
    delay(1);
  }
  for (int16_t i=display.height()-1; i>=0; i-=4) {
    display.drawLine(0, display.height()-1, display.width()-1, i, WHITE);
    display.display();
    delay(1);
  }
  delay(250);
  
  display.clearDisplay();
  for (int16_t i=display.width()-1; i>=0; i-=4) {
    display.drawLine(display.width()-1, display.height()-1, i, 0, WHITE);
    display.display();
    delay(1);
  }
  for (int16_t i=display.height()-1; i>=0; i-=4) {
    display.drawLine(display.width()-1, display.height()-1, 0, i, WHITE);
    display.display();
    delay(1);
  }
  delay(250);

  display.clearDisplay();
  for (int16_t i=0; i<display.height(); i+=4) {
    display.drawLine(display.width()-1, 0, 0, i, WHITE);
    display.display();
    delay(1);
  }
  for (int16_t i=0; i<display.width(); i+=4) {
    display.drawLine(display.width()-1, 0, i, display.height()-1, WHITE); 
    display.display();
    delay(1);
  }
  delay(250);
}

void testscrolltext(void) {
  display.setTextSize(2);
  display.setTextColor(WHITE);
  display.setCursor(10,0);
  display.clearDisplay();
  display.println("scroll");
  display.display();
  delay(1);
 
  display.startscrollright(0x00, 0x0F);
  delay(2000);
  display.stopscroll();
  delay(1000);
  display.startscrollleft(0x00, 0x0F);
  delay(2000);
  display.stopscroll();
  delay(1000);    
  display.startscrolldiagright(0x00, 0x07);
  delay(2000);
  display.startscrolldiagleft(0x00, 0x07);
  delay(2000);
  display.stopscroll();
}

Du wirst die Lib anpassen müssen. Leider ist das nicht (oder nur schlecht..) dokumentiert, schau mal rein. Da irgendwo in der Bibliothek gibts ne Zeile fürs 32er und eine fürs 34er.

bastel_heini: ... scheine ich alle darzustehen.

Stimmt nicht. Ich habe selbst mit diesem Display gespielt. Meine selbstgestrickte Bibliothek findest Du hier, hier und hier..

Guck Dir die Inhalte dieser Dateien an, streiche nicht benötigte Variablen (z. B. „moin“) und hab Spaß am Spielen :-)

Gruß

Gregor

PS: Zum Vergleichen, ein Foto.

viel danke für eure hilfe. das oled mit dem ssh1106 ist scheinbar noch eine nummer zu groß für mich.

während für mich als anfänger ein lcd 20x4 über i2c noch schnell verständlich war, verzweifel ich an dem oled -_-

@gregorss: danke für die libary, aber ehrlich gesagt weiß nicht so recht wie ich damit umgehen soll.

die libary einbinden stellt kein problem dar, aber da kein beispiel sketch dabei ist, weiß ich nicht wie ich damit umgehen soll :disappointed_relieved:

das hier ist mein erster versuch mit einem oled, ich bin einfach mal davon ausgegangen 'kann ja nicht viel schieriger sein als ein 20x4 lcd'

tja falsch gedacht

im prinzip möchte ich über das oled nur werte ausgeben, hat da jemand für den ssh1106 einen kleinen beispielsketch für mich?

es wäre natürlich super wenn ich mich eurer hilfe das display zum laufen kriege, ansonsten habe ich eher durch zufall vor ein paar wochen noch ein 128x32 ssd1306 oled bestellt, damit sollte dann wohl alles klappen

bastel_heini: @gregorss: danke für die libary, aber ehrlich gesagt weiß nicht so recht wie ich damit umgehen soll.

Die libary einbinden stellt kein problem dar, aber da kein beispiel sketch dabei ist, weiß ich nicht wie ich damit umgehen soll

Wie damit umzugehen ist, erfährst Du, wenn Du einen Blick in die Header-Datei wirfst. Dort befindet sich die Klassendefinition mit den Signaturen der Methoden. Was setPixel und unsetPixel machen, sollte schon am Namen zu erkennen sein. Das Gleiche gilt für line(), circle(), rectangle() usw. Es gibt allerdings auch Funktionen, die überhaupt noch nicht oder nicht fertig programmiert sind (z. B. putSS(), das sollte eine spezielle putS()-Variante werden, die einen sehr langen Text korrekt umbricht bzw. korrekt in mehreren Zeilen darstellt). putC() malt ein einzelnes Zeichen, putS() gibt eine ganze Zeichenkette aus (nur eben nicht umbrochen). Und damit die Änderungen auch auf dem Display erscheinen, musst Du zum Schluss immer ein update() machen, damit der im RAM gepufferte Bildschirminhalt auch tatsächlich erscheint.

Den Beispielsketch musst Du Dir also selbst schreiben, was jedoch nicht schlimm sein dürfte, weil Du ja sowieso irgendwas lesen und lernen musst. Ob das nun ein Beispielsketch ist oder der Code meiner Bibliothek. Mit meiner Bibliothek kann man zwar nicht alles machen, was eine Adafruit-Bibliothek kann, aber dafür ist sie so kurz, dass man sie schnell durch und durch kennt und daher leicht um eigene Sachen erweitern kann.

Gruß

Gregor

vielen dank für deine hilfe Gregor, aber nach einigen misserfolgen war mal wieder ein lichtblick nötig im die motivation aufrecht zu erhalten. mir ist moment noch überhaput nicht klar wie mit einem oled umgehen soll deine lib werd ich aufjedenfall im hinterkopf (und auf der festplatte) behalten :)

kurz zusammen gefasst: nach vier erfolglosen tagen das display ordenlich zum laufen zu bekommen bin ich auf ein youtube video gestoßen, welches DIE Lösung war:

https://www.youtube.com/watch?v=5DByDu5hDHU https://code.google.com/p/u8glib/

die u8g libary runterladen, einbinden, beispiel sketch auswählen und den passenden driver auswählen (uncomment)

alle beispiel sketch's laufen wunderbar :)

Na das ist doch mal eine gute Nachricht. Aber achte darauf, diese Library benötigt sehr viel Speicher des Atmega.

bastel_heini: ... nach einigen misserfolgen war mal wieder ein lichtblick nötig im die motivation aufrecht zu erhalten.

Das ist vollkommen verständlich. Wenn man beim Basteln oder Programmieren immer wieder gegen massive Wände rennt, kann einen das ganz schön entmutigen. Fluchen hilft :-)

Gruß

Gregor

PS: Schön, dass es jetzt funktioniert!