OLED-Display dunkel schalten

Hallo zusammen,
nachdem schon andere User eine Möglichkeit zum Dunkel schalten eines OLED-Displays gesucht haben, stelle ich euch meine Lösung vor. Bekanntermaßen brennt ein OLED-Display mit der Zeit ein, wenn es immer eingeschaltet ist. Der Stromverbrauch ist dabei keine Thema, sondern eher die Lebensdauer des Displays. In meinem Beispiel-Sketch kann man zur Demo das Display mit einer Taste einfach dunkel schalten. Ein Invertieren des Vorganges ist natürlich auch möglich. Im praktischen Einsatz bieten sich Monoflop, FlipFlop o. ä. an. Bei meinem Projekt (geht am Wochenende endlich in Betrieb) ist das Display standardmäßig dunkel und wird durch eine Taste für 5 Minuten eingeschaltet. Diese Zeit reicht mir zum Ablesen der Messwerte. Das Script ist einfach gestrickt und kann sicher verbessert werden. Für Anfänger (wie mich) ist es so besser zu durchschauen. Vielleicht hat jemand Verwendung dafür.

/*
  OLED-Display dunkel schalten
  by m266
  19.01.2022
  Taste zur Demo an D2 angeschlossen (nicht entprellt)
  Dunkelsteuerung über Pin 2 mit Taste, Schalter, Monoflop, FlipFlop o. ä.
*/

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

#define SCREEN_WIDTH 128 // OLED display width,  in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
#define OLED_WIDTH 128
#define OLED_HEIGHT 64
#define OLED_ADDR   0x3C
Adafruit_SSD1306 display(OLED_WIDTH, OLED_HEIGHT);
// declare an SSD1306 display object connected to I2C
Adafruit_SSD1306 oled(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

int switchPin = 2;

void setup() {
 Serial.begin(9600);
 Serial.print("Sketch:   ");   Serial.println(__FILE__);
 Serial.print("Uploaded: ");   Serial.println(__DATE__);
 Serial.println("Start");
 pinMode(switchPin, INPUT_PULLUP);
 display.begin(SSD1306_SWITCHCAPVCC, OLED_ADDR);
 display.clearDisplay();
 display.display();
}

void oledDisplay()
{
 display.clearDisplay();
 display.setTextSize(2);
 if (digitalRead(switchPin) == LOW) // OLED-Display dunkel schalten
 {
   display.setTextColor(BLACK);
 }
 else
 {
   display.setTextColor(WHITE);
 }
 display.setCursor(0, 0);
 display.println("Hallo");
 display.print("Welt!");
 display.display();
}
void loop() {
 oledDisplay();
}

Da Du bei realen veränderlichen Daten sowieso nach dem hell schalten alles neu und aktuell schreiben musst, dürfte ein clear() zum Dunkelschalten doch ausreichen.

Gruß Tommy

Hat bei mir nicht funktioniert.

Bei der Lib normal mit

display.clearDisplay();
display.display();

Nicht vergessen das die Befehle nur den von der Lib gebildeten Anzeigenspeicher bedienen. Erst das... display.display(); überträgt den Inhalt (in dem Fall ein dunkles Display) an das eigentliche Display.

Richtig. Das er das weiß war wohl meine Fehleinschätzung.

Gruß Tommy

mir fällt da aber noch was auf. Dein Skript schaltet ja nicht dunkel sondern auf invertierten Text. was man mit
display.invertDisplay(true);und display.invertDisplay(false); erreichen kann ohne den Anzeigenspeicher löschen zu müssen.

Wenn du die aktuelle Lib nutzt, lauten die Befehle für normalen und invertierten Text auch anders...

display.setTextColor(SSD1306_WHITE);        // Draw white text
display.setTextColor(SSD1306_BLACK, SSD1306_WHITE); // Draw 'inverse' text

Mit der Bibliothek habe ich mich nicht näher befasst, aber jedenfalls wird der Bildschirm richtig schwarz, also dunkel. Spricht etwas gegen meine Lösung?

Ich wollte nur damit angemerkt haben, das es eine Änderung in der Schreibweise bei dieser Lib gab. In älteren Versionen wurde wie von dir benutz ....

display.setTextColor(BLACK);
display.setTextColor(WHITE);

und ist gleichbedeutend mit

display.setTextColor(SSD1306_WHITE);
display.setTextColor(SSD1306_BLACK, SSD1306_WHITE);

in der aktuellen Version.
Ich babe die Vermutung, das wenn jemand eine ältere Version der Lib benutzt mit deinem Skript der Text tatsächlich invertiert ausgegeben wird und kein dunkles Display.

In welcher Version könnte das zum Problem werden? Dann probiere ich es aus und ändere ggf. das Script ab.

Das kann ich dir nicht genau sagen, wann diese Umstellung passiert ist. Mit ist es nur vor ein paar Tagen selber auf die Füße gefallen. Hatte vor 2-3 Jahren was mit dieser Lib gemacht und da war es deine Schreibweise. Jetzt hatte ich mal wieder ein Projekt für die Displays (hatte noch welche rumliegen) und es paßte so einiges nicht mehr nachdem die Lib aktualisiert wurde. Hatte die tollsten Effekte auf dem Display mit meinen alten Skripten und mußte mir vieles wieder neu erarbeiten. Dadurch ist mir das nur aufgefallen.

Danke für die Info. Ich probiere es morgen aus und berichte dann.

Hier? (oder noch früher?)

Mir fiel das nicht auf, weil ich die aktuelle Version der Lib geladen hatte.

Das scheint so nicht zu stimmen. Wenn ich die beiden Zeilen wie von dir vorgeschlagen ändere...

void oledDisplay()
{
  display.clearDisplay();
  display.setTextSize(2);
  if (digitalRead(switchPin) == LOW) // OLED-Display dunkel schalten
  {
    display.setTextColor(SSD1306_BLACK, SSD1306_WHITE);
  }
  else
  {
    display.setTextColor(SSD1306_WHITE);
  }
  display.setCursor(0, 0);
  display.println("Hallo");
  display.print("Welt!");
  display.display();
}

habe ich bei Version 2.5.0 und 2.5.1 invertierten Text. Bei mir war Version 2.5.0 installiert.

Mit beiden Versionen (2.5.0. bzw. 2.5.1) funktioniert mein ursprünglicher Code einwandfrei:

void oledDisplay()
{
  display.clearDisplay();
  display.setTextSize(2);
  if (digitalRead(switchPin) == LOW) // OLED-Display dunkel schalten
  {
    display.setTextColor(BLACK);
  }
  else
  {
    display.setTextColor(WHITE);
  }
  display.setCursor(0, 0);
  display.println("Hallo");
  display.print("Welt!");
  display.display();
}

Ergo brauche ich auch nichts zu ändern. Ich benutze für meine Tests ein OLED-Display 0,96 Inch von AZDelivery. Wer die Möglichkeit hat, kann das gerne nachvollziehen.

Nachtrag:

Dein Vorschlag hat mich irritiert. Die zweite Zeile muss wie folgt lauten:

display.setTextColor(SSD1306_BLACK);

Dann klappt es auch mit neueren Versionen der Lib.

Ich habe nun weitere Tests durchgeführt. Alte Versionen bis mindestens 1.2.5 bringen unabhängig von meinem Code sofort Fehler der Lib. Ab Version 2.0.0 läuft es mit meinem Code einwandfrei. M. E. wird kein User uralte Versionen der Lib benutzen. Daher kann ich den Sketch so belassen.

Hui, das wundert mich gerade, weil ich den Quelltext so direkt aus der originalen Beispieldatei genommen hatte. Sei es drum, wer sagt denn das die da nicht auch mal einen Fehler machen.
Obwohl...
Nur mal angenommen du würdest etwas machen wie eine Zeile überschreiben mit...

display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
display.print("Hallo");
display.setTextColor(SSD1306_BLACK);
display.setCursor(0, 0);
display.print("Welt!");

... würde er ja beide Texte übereinander in der selben Zeile im Display anzeigen.
Mit...

display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
display.print("Hallo");
display.setTextColor(SSD1306_BLACK, SSD1306_WHITE);
display.setCursor(0, 0);
display.print("Welt!");

... würde vermutlich nur negativ Welt! da stehen weil ein expliziter Hintergrund angegeben ist.

Bliebe mal zu testen, habe ich aber gerade keine Zeit für. Vom logischen her würde es Sinn machen den zweiten Wert an zu geben, wenn man etwas überschreiben will.

Aber gut, das hat mit deinem Sketch nix zu tun und ich danke dir für deine Mühe und die Info das dies so funktioniert.

Ne. Da fehlt "ln".
Es müsste dann so lauten, damit eine neue Zeile darunter eingefügt wird:

display.println("Hallo");

Nein, da mißverstehst du mich. Es sollte mutwillig die selbe Position sein, damit er die beiden Texte aufeinander geblendet an der selben Position anzeigt, oder eben nicht mit angegebenen Hintergrund.
So was kann man gut brauchen, wenn man in einer Anzeige nur einen Meßwert aktualisieren will, ohne den alten Meßwert vorher weg nehmen zu müssen.

OK. Alles klar. Für meinen Zweck ist es OK.