/**************************************************************************
Beispiele für monochrome OLEDs mit SSD1306 Treiber
Hier wird ein 128x64 Pixel Display mit I2C Schnittstelle verwendet.
Date: Okt 2024, BuM
**************************************************************************/
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128 // OLED display Breit in Pixels
#define SCREEN_HEIGHT 64 // OLED display Höhe in Pixels
// Pinbelegung ESP32: GPIO21(SDA), GPIO22(SCL) without PullUp, I2C-Adresse: 0x3C
#define SCREEN_ADDRESS 0x3C
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire);
#define LOGO_HEIGHT 16
#define LOGO_WIDTH 16
// Bitmaske für eigene Grafik/Logo
static const unsigned char PROGMEM logo_bmp[] =
{ 0b00000001, 0b10000000,
0b00000011, 0b11000000,
0b00000111, 0b11100000,
0b00000111, 0b11100000,
0b00000011, 0b11000000,
0b00110001, 0b10001100,
0b01111000, 0b00011110,
0b11111100, 0b00111111,
0b11111100, 0b00111111,
0b01111000, 0b00011110,
0b00110001, 0b10001100,
0b00000011, 0b11000000,
0b00000111, 0b11100000,
0b00000111, 0b11100000,
0b00000011, 0b11000000,
0b00000001, 0b10000000 };
void setup() {
Serial.begin(9600);
if(!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) // SSD1306_SWITCHCAPVCC = Anpassung an 3,3V Verorgung
{
Serial.println(F("SSD1306 allocation failed"));
while(1); // loop forever means stop
}
// Bildspeicher löschen
display.clearDisplay();
// Einzelne Pixel ausgeben
for(int i = 8; i < 128; i = i + 8)
{
display.drawPixel(i, 10, SSD1306_WHITE);
display.display();
delay(100);
}
delay(1000);
// display.display() gibt den Inhalt des Bildspeichers auf dem OLED aus. Dieser Schritt darf nicht
// vegessen werden, ist aber auch nur dann notwendig, wenn die Darstellung upgedatet werden muss.
// Hier ein paar Testprogramme die die Handhabung verdeutlichen:
testdrawline(); // Linien zeichnen
testdrawrect(); // Rechtecke zeichnen
testfillrect(); // Rechteckflächen zeichnen
testdrawcircle(); // Kreise zeichnen
testfillcircle(); // Kreisflächen zeichnen
testdrawroundrect(); // Rechtecke mit runden Ecken zeichnen
testfillroundrect(); // Rechteckflächen mit runden Ecken zeichnen
testdrawtriangle(); // Dreiecke zeichnen
testfilltriangle(); // Dreieckflächen zeichnen
testdrawchar(); // Einzelne Textzeichen ausgeben (Default-Font)
testdrawstyles(); // Verschiedene Textstile anwenden
testdrawbitmap(); // Kleine Pixelgrafiken (Logos) ausgeben
// Darstellung wird invertiert:
display.invertDisplay(true);
delay(1000);
display.invertDisplay(false);
delay(1000);
}
void loop() {
}
void testdrawline() {
display.clearDisplay();
// Parameter: y, x, Breite, Höhe, colour
display.drawLine(0, 0, display.width(), display.height(), SSD1306_WHITE);
display.display();
delay(500);
display.drawLine(0, display.height(), display.width(), 0, SSD1306_WHITE);
display.display();
delay(500);
display.drawLine(display.width()/2, 0, display.width()/2, display.height(), SSD1306_WHITE);
display.display();
delay(500);
display.drawLine(0, display.height()/2, display.width(), display.height()/2, SSD1306_WHITE);
display.display();
delay(500);
}
void testdrawrect(void) {
display.clearDisplay();
// Parameter: y, x, Breite, Höhe, 'Farbe'
display.drawRect(2, 2, display.width()-4, display.height()-4, SSD1306_WHITE);
display.display();
delay(500);
display.drawRect(10, 10, display.width()-20, display.height()-20, SSD1306_WHITE);
display.display();
delay(500);
}
void testfillrect(void) {
display.clearDisplay();
// Parameter: y, x, Breite, Höhe, 'Farbe'
// The INVERSE color is used so rectangles alternate white/black
display.fillRect(20, 20, display.width()-40, display.height()-40, SSD1306_INVERSE);
display.display(); // Update screen with each newly-drawn rectangle
delay(500);
}
void testdrawcircle(void) {
display.clearDisplay();
// Parameter: y, x, Radius, 'Farbe'
display.drawCircle(display.width()/2, display.height()/2, 40, SSD1306_WHITE);
display.display();
delay(500);
display.drawCircle(display.width()/2, display.height()/2, 60, SSD1306_WHITE);
display.display();
delay(500);
}
void testfillcircle(void) {
display.clearDisplay();
// Parameter: y, x, Radius, 'Farbe' Hier: INVERSE negiert die Darstellung
display.fillCircle(display.width() / 2, display.height() / 2, 20, SSD1306_INVERSE);
display.display();
delay(500);
display.fillCircle(display.width() / 2, display.height() / 2, 10, SSD1306_INVERSE);
display.display();
delay(500);
}
void testdrawroundrect(void) {
display.clearDisplay();
// Parameter: y, x, Breite, Höhe, Radius der Ecken, 'Farbe'
display.drawRoundRect(2, 2, display.width()-2, display.height()-2, display.height()/8, SSD1306_WHITE);
display.display();
delay(500);
display.drawRoundRect(10, 10, display.width()-20, display.height()-20, display.height()/4, SSD1306_WHITE);
display.display();
delay(500);
}
void testfillroundrect(void) {
display.clearDisplay();
// Parameter: y, x, Breite, Höhe, roundingRadius der Ecken, 'Farbe'
display.fillRoundRect(2, 2, display.width()-2, display.height()-2, display.height()/8, SSD1306_WHITE);
display.display();
delay(500);
display.fillRoundRect(10, 10, display.width()-20, display.height()-20, display.height()/4, SSD1306_INVERSE);
display.display();
delay(500);
}
void testdrawtriangle(void) {
display.clearDisplay();
// Parameter: 1EckeX, 1EckeY, 2EckeX, 2EckeY, 3EckeX, 3EckeY, 'Farbe'
display.drawTriangle(display.width()/2 , display.height()/2, 1,1,128,1, SSD1306_WHITE);
display.display();
delay(500);
display.drawTriangle(display.width()/2 , display.height()/3, 1,1,128,1, SSD1306_WHITE);
display.display();
delay(500);
}
void testfilltriangle(void) {
display.clearDisplay();
// Parameter: 1EckeX, 1EckeY, 2EckeX, 2EckeY, 3EckeX, 3EckeY, 'Farbe'
display.fillTriangle(display.width()/2 , display.height()/2, 1,1,128,1, SSD1306_WHITE);
display.display();
delay(500);
display.fillTriangle(display.width()/2 , display.height()/3, 1,1,128,1, SSD1306_INVERSE);
display.display();
delay(500);
}
void testdrawchar(void) {
display.clearDisplay();
display.setTextSize(1); // Einfache Fontgröße
display.setTextColor(SSD1306_WHITE); // Text ausgeben
display.setCursor(0, 0); // Startpunkt der Textausgabe
display.cp437(true); // Verwende 'Code Page 437' Font
// Zu viele Zeichen werden mangels Platz nicht ausgegeben
for(int16_t i=48; i<69; i++) { display.write(i); } // Writes ASCII Code
display.display();
delay(2000);
display.setTextSize(2); // Zweifache Fontgröße
for(int16_t i=69; i<79; i++) { display.write(i); }
display.display();
delay(2000);
display.setTextSize(3); // Dreifache Fontgröße
for(int16_t i=79; i<87; i++) { display.write(i); }
display.display();
delay(2000);
}
void testdrawstyles(void) {
display.clearDisplay();
display.setTextSize(1); // Einfache Fontgröße
display.setTextColor(SSD1306_WHITE); // Text ausgeben
display.setCursor(0,0); // Startpunkt der Textausgabe
display.println("Hello, world!");
display.setTextColor(SSD1306_BLACK, SSD1306_WHITE); // Text wird invertiert dargestellt
display.println(245396736);
display.setTextSize(2);
display.setTextColor(SSD1306_WHITE);
display.print("0x"); display.println(0xDEADBEEF, HEX);
display.display();
delay(2000);
}
void testdrawbitmap(void) {
display.clearDisplay();
// Parameter: y, x, Zeiger auf Bitmap-Array, Logobreite, Logohöhe, Farbe
display.drawBitmap(64, 10, logo_bmp, LOGO_WIDTH, LOGO_HEIGHT, 1);
display.display();
delay(1000);
}