In den vorherigen Lektionen haben wir unter anderem gelernt, wie wir uns Signale im Seriellen Monitor unseres Editors anzeigen lassen können. Wir wissen, dass wir zum Auslesen des Signals den Seriellen Monitor auf unserem Computer öffnen müssen. Aber was machen wir eigentlich, wenn wir gerade keinen Computer zur Hand haben?
Auch hierfür gibt es in der Mikroelektronik eine einfache Lösung: wir verwenden Displays, auf denen wir einfache Ziffernfolgen (z.B. Worte oder Zahlenwerte) ausgeben können. Diese Displays sind im Vergleich zu herkömmlichen Computerbildschirmen günstig, wesentlich kleiner und dadurch auch flexibler verwendbar. Natürlich darf auch ein solches Display auf unserem Funduino Cube nicht fehlen!
In dieser Lektion möchten wir auf unserem OLED die in der Informatik weltweit bekannten Worte „Hello, World!“ darstellen.
Wir starten mit dem Hinzufügen des Blocks für unser OLED mit SSD1306 Treiberchip.
Den Block findest du in deiner ROBOTERKONFIGURATION unter „Aktion„, relativ weit unten.
Nachdem wir den Block zu unserer ROBOTERKONFIGURATION hinzugefügt haben, vergeben wir innerhalb des Blocks einen Namen.
In unserem Beispiel nennen wir den Block „OLED„.
Direkt unter dem Namensfeld befindet sich ein Feld mit dem Titel „Adresse„. In diesem Feld ist der Wert „0x3D“ voreingetragen.
Hinweis: Die OLED HEX-Adresse kann 0x3C oder 0x3D entsprechen. Sollte die Inbetriebnahme mit der HEX-Adresse 0x3D nicht funktionieren, bitte die HEX-Adresse 0x3C eintragen!
Es handelt sich bei diesem Feld um eine sogenannte HEX-Adresse. HEX-Adressen werden bei Modulen verwendet, die über eine sogenannte I²C (I2C) Schnittstelle kommunizieren.
Aber warum verwenden wir eine HEX-Adresse?
I²C Schnittstellen bieten für Programmierer einen wesentlichen Vorteil:
Hinter der I²C Schnittstelle verbirgt sich ein sogenanntes Bussystem. In diesem Fall ein Master-Slave-Bus. Über ein Bussystem werden Datenpakete von einem „Master“ an einen „Slave“ gesendet. Diese Datenpakete können dabei von einem Master zielgerichtet an unterschiedliche Slaves versendet werden, solange diese sich in dem selben Bussystem befinden.
Damit der „Master“ die „Slaves“ unterscheiden kann, werden die „Slaves“ mit einer HEX-Adresse versehen. In unserem Fall, soll der „Slave“ mit der HEX-Adresse 0x3D (OLED) Datenpakete von „Master“ (Mikrocontroller) erhalten.
Das ist nichts anderes, als wenn du eine wichtige E-Mail versendest. Du möchtest natürlich nicht, dass die Mail bei jemandem landet, der sie nicht lesen soll. Daher schreibst du in die Mail die Empfänger-Mailadresse und kannst sicher gehen, dass die Mail nicht woanders landet. In dem Fall bist du „Master“ und der Empfänger ist „Slave“.
Innerhalb des Blocks für das SSD1306 OLED befindet sich zwei weitere Punkte, die wir in den vorherigen Lektionen noch nicht kennengelernt haben.
Die beiden Punkte „SDA“ und „SCL“ werden ebenfalls für die Kommunikation über das I²C Bussystem benötigt.
Über den Pin „SDA“ werden die Datenpakete versendet.
Der Pin „SCL“ gibt das Taktsignal vor, in welchem die Datenpakete übermittelt werden. Der Takt wird über „SCL“ vom „Master“ festgelegt und lediglich vom „Slave“ gelesen. Die Übertragungsrichtung ist hierbei eindeutig festgelegt.
Auf dem SSD1306 OLED auf deinem Funduino Cube findest du diesen beiden Pins ebenfalls wieder. Wir tragen an den entsprechenden Stellen im Block also die Werte „A4“ für SDA und „A5“ für SCL ein.
Den Block für unser OLED mit SSD1306 Treiberchip finden wir im Menü auf der linken Seite innerhalb des OpenRoberta Lab.
Hierfür navigieren wir zunächst in die erweiterte Übersicht, indem wir auf „☆2″ klicken.
Anschließend wählen wir unter „Aktion“ das Menü „Anzeige“ aus und ziehen den Block in unser PROGRAMM.
Du wirst feststellen, dass dieser Block relativ übersichtlich gestaltet ist.
Im Block „Zeige Text„, für welchen der Wert „Hallo“ hinterlegt ist, tragen wir jetzt „Hello, World!“ ein.
Zusätzlich zum Text können wir innerhalb des Blocks noch festlegen, in welcher Spalte und in welcher Zeile der Text ausgegeben werden soll.
Wir legen hierbei jeweils den Startpunkt des ersten Zeichens fest.
Gratulation! Wir haben die Aufgabenstellung erfolgreich gelöst.
Nachdem du dein Programm auf deinen Funduino Cube hochgeladen hast, sollte jetzt der Text „Hello, World!“ erscheinen.
Frage: Schaffst du es, deinen Namen auf dem OLED anzeigen zu lassen?
In der Lektion 6 haben wir bereits für den WS2812B-Ring eine Bibliothek hinzugefügt. Eine solche Bibliothek
verwenden wir jetzt auch bei dem OLED-Display.
Wir erinnern uns: Bibliotheken dienen als Wissensspeicher, den wir mittels Befehlen in unseren Quellcode
einbinden können. In einem solchen Wissensspeicher sind im Regelfall komplexere Codeabschnitte enthalten.
Damit wir uns ein wenig Codearbeit sparen können, greifen wir an einigen Stellen auf diesen Wissensspeicher
zurück. Um die Bibliothek zu unserem Quellcode hinzuzufügen, verwenden wir wieder den Ausdruck „#include„
und schreiben in die spitzen Klammern den Bibliotheksnamen.
Für unser Projekt benötigen wir die Bibliotheken <Wire.h>, <SSD1306Ascii.h> und <SSD1306AsciiWire.h> .
Im ersten Schritt fügen wir diese Bibliotheken zu unserem Quellcode hinzu. Wie das funktioniert, kannst du der
nachfolgenden Abbildung entnehmen.
/* Bibliotheken */
#include
#include
#include
Um Inhalte auf dem OLED-Display anzeigen zu können, benötigen wir im Sketch ein sogenanntes Objekt.
Objekte verhalten sich ähnlich wie Variablen, die du bereits aus den früheren Lektionen kennst. Ein Objekt ist im Grunde gesagt also ein Datenspeicher, den wir mit einer Information füllen möchten.
Diesen Datenspeicher definieren wir in unserem Programmcode mit Hilfe des Ausdrucks „SSD1306AsciiWire“. Das Objekt benennen wir „oled“, passend zu unserem OLED-Display.
/* Bibliotheken */
#include
#include
#include
/* Variablen */
SSD1306AsciiWire oled;
Wenn du dir die Beschriftung der Pins deines OLEDs auf deinem Funduino Cube genauer ansiehst, wirst du einen Unterschied zu den Modulen aus den vorherigen Lektionen erkennen können. Anders als du es zum Beispiel aus der Lektion Nr. 10 kennst, findest du neben den Pins 5V und GND die beiden Pins SCL und SDA wieder.
Die Daten und somit auch die Signale zwischen dem Mikrocontroller und dem Display werden über den SDA Pin ausgetauscht. Der SDA-Pin überträgt die Daten in beide Richtungen, er kann also Daten empfangen und senden.
Die Geschwindigkeit, der welcher die Datenübertragung stattfindet, wird über den SCL-Pin definiert.
Du kannst dir ein solches System wie eine Straße vorstellen, auf der Fahrzeuge in unterschiedliche Richtungen fahren. Jedes Fahrzeug stellt ein Datenpaket dar, das Informationen transportiert. Diese Informationen werden in unserem Fall entweder vom Mikrocontroller zum OLED, oder vom OLED zum Mikrocontroller transportiert. Die Geschwindigkeit, in der unsere Fahrzeuge auf dieser Straße fahren dürfen, wird über den SCL-Pin vorgegeben.
Diese Kommunikationsmethode wird auch aus Bussystem bezeichnet. In diesem Fall handelt es sich um einen I2C-Bus. Mit Hilfe eines Bussystems können mehrere unterschiedliche Bauteile in einem System gleichzeitig miteinander kommunizieren.
Die Kommunikation über den I2C-Bus erfolgt mit dem Mikrocontroller auf deinem Funduino Cube über die analogen Pins A4 (SCL) und A5 (SDA).
/* Bibliotheken */
#include
#include
#include
/* Variablen */
SSD1306AsciiWire oled;
Wir wissen also jetzt, was ein I2C-Bussystem ist und wofür dieses in technischen Systemen benötigt wird.
Höchste Zeit also, uns anzusehen, wie man dieses Bussystem in einen Programmcode einbettet.
Zunächst müssen wir dem Mikrocontroller vermitteln, dass Datenpakete über den I2C-Bus erwartet werden. Dies gelingt, indem wir die Programmzeile „Wire.begin();“ in unser Setup schreiben.
Den Begriff „Wire“ kennst du bereits aus dem ersten Schritt dieser Lektion. Wir haben dort eine Bibliothek mit dem Namen „Wire.h“, also einen Wissensspeicher, zu unserem Programm hinzugefügt.
Diesen Wissensspeicher rufen wir mit der Programmzeile „Wire.begin()“ auf und teilen dem Mikrocontroller dadurch mit, dass Datenpakete über den I2C-Bus erwartet werden.
/* Bibliotheken */
#include
#include
#include
/* Variablen */
SSD1306AsciiWire oled;
/* setup */
void setup()
{ // start setup
Wire.begin();
}
Die Aufgabenstellung dieser Lektion sieht vor, dass wir auf unserem OLED die berühmte Textzeile „Hello, World!“ anzeigen lassen möchten.
Wenn du deinen Namen auf ein Blatt Papier schreibst, tust du dies auf eine einzigartige Art und Weise, nämlich mit deiner persönlichen Schriftart: Deiner Handschrift.
Oftmals nehmen wir dies gar nicht richtig wahr, aber jeder Text wird in einer Schriftart dargestellt. Auch unser OLED benötigt eine solche Schriftart.
Genau hierfür haben wir die Bibliothek <SSD1306Ascii.h> zu unserem Programmcode hinzugefügt. Diese Bibliothek enthält viele verschiedene Schriftarten, die wir jetzt abrufen können.
In unserem Beispiel entschieden wir uns für die Schriftart „System5x7“ und legen diese mit dem „setFont“-Befehl fest. Die exakte Programmzeile kannst du aus der nachfolgenden Abbildung entnehmen.
/* Bibliotheken */
#include
#include
#include
/* Variablen */
SSD1306AsciiWire oled;
/* setup */
void setup()
{ // start setup
Wire.begin();
oled.setFont(System5x7);
} // ende setup
Nachdem wir also die I2C-Kommunikation gestartet und eine Schriftart für den Text auf unserem OLED ausgewählt haben, müssen jetzt noch festlegen, welche Auflösung unser OLED hat.
Die Auflösung legt fest, wie viele Pixel sich auf unserem OLED befinden. In unserem Fall sind das 128 x 64 Pixel.
Die erste Zahl steht dabei immer für die Breite, die zweite für die Höhe. Unser OLED ist demnach 128 Pixel breit und 64 Pixel hoch.
Wenn man diese beiden Zahlen miteinander multipliziert, kann man herausfinden, wie viele Pixel sich insgesamt auf unserem OLED befinden. Insgesamt können wir 8192 Pixel ansteuern – eine ganz schön große Menge!
Diese Information müssen wir jetzt noch unserem Mikrocontroller vermitteln. Dafür verwenden wir den Befehl „oled.begin„ (dts. starte OLED). In die Klammer des Befehls tragen wir zuerst die Größe des Displays ein. Dafür verwenden wir den Ausdruck „&Adafruit128x64“.
Wenn du dir die Codezeile in unserem Programm genauer ansiehst, wirst du feststellen, dass wir hinter „&Adafruit128x64“ noch eine weitere Kombination aus Buchstaben und Zahlen aufgeführt haben: „0x3C“.
Bei dem Ausdruck „0x3C“ handelt es sich um eine sogenannte Adresse. Diese Adresse wird benötigt, damit wir die Datenblöcke in unserem I2C-Bussystem zielgerichtet steuern können. Du kannst dir diese Adresse wie eine Hausnummer auf einer Straße vorstellen.
Und genau das macht ein Bussystem so spannend: Dadurch, dass jedes Datenpaket mit einer solchen Adresse versehen wird, können wir ganz viele Datenpakete zielgerichtet an unterschiedliche Adressen versenden – und das über nur eine einzige Datenleitung.
Hinweis: Die OLED HEX-Adresse kann 0x3C oder 0x3D entsprechen. Sollte die Inbetriebnahme mit der HEX-Adresse 0x3D nicht funktionieren, bitte die HEX-Adresse 0x3C eintragen!
Mit diesem letzten Schritt schließen wir die Konfiguration unseres OLEDs vollständig ab.
/* Bibliotheken */
#include
#include
#include
/* Variablen */
SSD1306AsciiWire oled;
/* setup */
void setup()
{ // start setup
Wire.begin();
oled.setFont(System5x7);
oled.begin(&Adafruit128x64, 0x3C);
} // ende setup
Jetzt wird es spannend: Im Loop beginnen wir jetzt damit, Texte an das OLED zu schicken. Hierfür verwenden wir die beiden Befehle „println“ und „print“.
Beide Befehle kennst du bereits aus dem seriellen Monitor.
Zur Erinnerung: Mit dem Befehl „println„ werden Texte in einzelnen Textzeilen ausgegeben. Mit dem Befehl „print„ werden Texte nacheinander in der selben Textzeile ausgegeben.
Laut der Aufgabenstellung wollen wir den Text „Hello World!“ auf dem Display ausgeben. Lasst uns diesen Text über zwei Zeilen verteilt schreiben. In der ersten Zeile verwenden wir den Befehl „println“ und wir schreiben „Hello“ in die Klammer. In der zweiten Zeile nutzen wir den „print“-Befehl und schreiben „World!“ in die Klammer.
Testet diesen Code jetzt mal aus. Fällt euch etwas auf?
/* Bibliotheken */
#include
#include
#include
/* Variablen */
SSD1306AsciiWire oled;
/* setup */
void setup()
{ // start setup
Wire.begin();
oled.setFont(System5x7);
oled.begin(&Adafruit128x64, 0x3C);
} // ende setup
/* loop */
void loop()
{ // start loop
oled.println("Hello");
oled.print("World!");
}
Ups, Buchstabensalat!
Der Text auf unserem OLED wird zu häufig ausgegeben. Das liegt am „Loop“ unseres Programmes, in dem die Inhalte fortlaufend wiederholt werden.
Damit wir wirklich nur einmal „Hello, World!“ auf dem Display lesen, müssen wir nach jedem Durchlauf des „Loop“ das Display aufräumen. Dies lösen wir, indem wir die Codezeile „oled.clear()“ (dts. OLED reinigen) in unserem Programm ergänzen.
Zusätzlich ergänzen wir eine Pause von zwei Sekunden. Ohne diese Pause würde das Display nur flackern und wir könnten den Text „Hello, World“ nicht gut lesen.
#include
#include
#include
/* Variablen */
SSD1306AsciiWire oled;
/* setup */
void setup()
{ // start setup
Wire.begin();
oled.setFont(System5x7);
oled.begin(&Adafruit128x64, 0x3C);
} // ende setup
/* loop */
void loop()
{ // start loop
oled.println("Hello");
oled.print("World!");
delay(2000);
oled.clear();
} // ende loop
Falls du Unterstützung bei der Verwendung deines Funduino Cubes benötigen solltest, steht dir unser kompetentes Support Team jederzeit gerne zur Verfügung!
Du erreichst uns am Besten per Mail unter info@funduino.de oder von Montags bis Freitags, zwischen 09:00 und 17:00 Uhr unter der Rufnummer (+49) 5921 9704030.