zurück zum Artikel

PicAsSo-Adventskalender: Wir basteln am zweiten Advent fleißig weiter

Michael Gaus, Miguel Köhnlein

Diesen Sonntag lernen wir, ein kleines Display via Picaxe anzusprechen und ihm Bilddateien zu schicken – ganz klassisch mit Weihnachtsmotiv.

Weiter geht's: Diesen Adventssonntag kommt ein OLED-Modul zu unserem Breadboard-Aufbau dazu. Es hat ein I2C-Interface, das sich mit wenig Hardware-Aufwand an den Picaxe anschließen lässt. Wenn man die Ansteuerung softwareseitig geschickt auslegt, werden relativ wenig Ressourcen des Picaxe benötigt und man erhält so eine kleine und kostengünstige Anzeigemöglichkeit. Eine Zeichenfont zur Ausgabe von Texten lässt sich ebenfalls in die Firmware einbauen.

Make PICAXE Special

Mehr zum Thema gibt es im Make: PICAXE Special.

Rückseite OLED: I2C-Adresse ist 0x78

Das OLED verfügt über den integrierten Controller SSD1306. Seine Auflösung beträgt 128×64 Pixel. Es ist bereits ein 3,3-Volt-Spannungsregler (U2 auf der Platinenrückseite) aufgelötet, sodass das Modul mit 5 Volt versorgt werden kann. An Pin 1 liegt GND und an Pin 2 VCC. Das sollte unbedingt vor dem Einbau kontrolliert werden, da es auch Module mit verdrehten Versorgungspins gibt. Auf der Platinenrückseite ist die I2C-Adresse 0×78 (bzw. geshiftet 0×3C) voreingestellt.

Der Schaltplan für unser Projekt.

Zur Ansteuerung des OLEDs ist nur wenig Schaltungsaufwand nötig. Beim Picaxe 14M2 ist die Datenleitung SDA des I2C-Interfaces am Pin B.4 (auf dem Nano-Axe entspricht das der Beschriftung B3) und die Taktleitung SCL am Pin B.3 (auf dem Nano-Axe entspricht das der Beschriftung B2) herausgeführt. Auf dem OLED sind bereits 4k7 Pullup-Widerstände vorhanden. Jedoch sind diese gegen 3,3 Volt geschaltet und nicht gegen 5 Volt. So wäre der HIGH-Pegel nicht ausreichend hoch, damit der mit 5 Volt Spannung betriebene Picaxe sicher eine logische Eins erkennen kann. Es gibt aber die Möglichkeit, in der Firmware den System Management Bus (SMBus) Mode zu aktivieren. Der SMBus wurde für stromsparende Kommunikation entwickelt und ermöglicht dem Picaxe, an den I2C-Pins einen High-Pegel ab 2,1 Volt zu erkennen – damit reichen die Pullupwiderstände gegen 3,3 Volt völlig aus.

PicAsSo-Adventskalender

Vier Türchen statt 24: Mit dem Nano-Axe-Board bauen wir vier Adventssonntage lang ein leuchtendes und klingendes Projekt zum Mitmachen.

Die Fritzing-Skizze für die Steckverbindungen.

Das OLED hat herstellerseitig bereits eine 4-polige Stiftleiste angelötet, sodass es direkt ins Steckboard passt. Wir schließen es mit vier Drähten in den Farben weiß (SDA), gelb (SCL), rot (+5V) und blau (GND) an.

Der fertige Steckbrett-Aufbau am 2. Adventssonntag

Wer jetzt direkt das OLED testen und eine Grafik ausgeben will, für den haben wir Beispielprogramme vorbereitet, die hier samt Bitmaps heruntergeladen werden können [7] . Im Picaxe-Editor öffnen wir das Projekt picasso2_make_logo.bas und laden es in den Picaxe. Auf dem OLED sollte dann ein wohlbekanntes Logo zu sehen sein. Es verschwindet nach gut zwei Sekunden mit einer Animation, bei der schrittweise je ein Viertel des Displays gelöscht wird. Das ganze wiederholt sich in einer Endlosschleife.

Dieses Logo dürfte bekannt sein ...

Hierfür muss das Bild in passende Datenbytes konvertiert werden, die per I2C an das OLED gesendet werden können. Das funktioniert folgendermaßen:

1) Eine Bitmap der Größe 128×64 Pixel mit 2 Farben (Schwarz-Weiß) erstellen, beispielsweise mit Paint oder einem anderen Bildbearbeitungsprogramm.

2) Das Online-Tool image2cpp [8] aufrufen. Dort bei 1. Select image die Bitmap auswählen. Bei 2. Image settings die Option invert image colors ankreuzen. Bei 4. Output als Format plain bytes und bei Draw mode die Auswahl vertical treffen. Anschließend werden durch Klick auf Generate code die Daten erzeugt. Da die Auflösung 128×64 Pixel beträgt und pro Pixel 1 Bit Speicherplatz benötigt wird, entstehen genau 1024 Bytes, die das Tool in 64 Datenzeilen mit jeweils 16 Datenbytes im Hexadezimal-Format aufteilt. Die müssen nun alle markiert und in die Zwischenablage kopiert werden.

Mehr von Make Mehr von Make [9]

3) Im Picaxe-Editor löscht man den Bereich zwischen den Kommentarzeilen start of logo und end of logo und fügt dort stattdessen die Daten aus der Zwischenablage ein. In der ersten eingefügten Zeile (// 'make_logo_128×64', 128×64px) müssen wir am Anfang ein Semikolon setzen, damit der Picaxe-Editor sie als Kommentar erkennt. Das Quellcode- Fenster ziehen wir so breit, dass die nachfolgenden Datenzeilen jeweils komplett in eine Editorzeile passen, also keine Umbruch-Pfeilchen am Zeilenende zu sehen sind.

Damit der Picaxe-Editor die 64 Zeilen als zusammenhängenden Befehl erkennt, ist am Ende jeder Zeile ein Unterstrich notwendig. Dieser markiert einen manuellen Zeilenumbruch.

Wie kann man alle Zeilen gleichzeitig bearbeiten?

Um alle Zeilen gleichzeitig bearbeiten zu können, setzt man den Mauscursor auf das Ende der ersten Zeile und hält dann die Alt-Taste gedrückt. Anschließend markiert man mit gedrückter linker Maustaste den Bereich bis zur letzten Datenzeile, wobei die Markierung nur ein Zeichen breit sein muss. Danach lässt man zuerst die Maustaste los, dann die Alt-Taste. Oben im Menü des Picaxe-Editors erscheinen wegen der zuvor gedrückten Alt-Taste ein paar Buchstabenfelder zur Auswahl, die durch das Drücken der Alt-Taste ignoriert werden können. Nun tippt man ein Leerzeichen und einen Unterstrich ein. Durch anschließendes Betätigen der ESC-Taste wird die Markierung aufgehoben.

Vor der ersten Datenzeile wird eine Zeile mit folgendem I2C-Ausgabebefehl eingefügt: hi2cout (0x40,_

Der Wert 0x40 kennzeichnet, dass Daten zum OLED gesendet werden sollen. Nach der letzten eingefügten Zeile muss der hi2cout-Befehl abgeschlossen werden, indem eine Zeile mit einer schließenden runden Klammer ) getippt wird. Nun kann man endlich im Picaxe-Editor auf Check klicken. Sollte hier eine Fehlermeldung erscheinen, dann hat man beim Anpassen der Datenzeilen irgendwo ein Fehler gemacht. Nach dem Download des Codes in den Picaxe sollte nun das neu gewählte Bild auf dem OLED auftauchen.

Natürlich ist das Vorgehen nur eine experimentelle Methode, um ein Bild im Picaxe zu speichern und auf das OLED übertragen zu können. Die Bilddaten belegen einen Großteil des Picaxe- Programmspeichers. Wenn man ein zweites Bild speichern und darstellen möchte, kann es sein, dass der Speicher dafür nicht mehr ausreicht. Das ist stark von den Bildinhalten abhängig, da der Picaxe-Befehl abhängig von den Bytes mehr oder weniger Speicher benötigt.

Nun spielen wir eine kleine Diashow auf dem OLED ab. Wir haben zwei Bilder so gewählt, dass es möglich ist, beide gleichzeitig im Picaxe-Speicher unterzubringen. Außerdem wenden wir noch einen Trick an: Der Picaxe 14M2 hat zwei Programm-Slots: Slot 0 und Slot 1. So steht im Prinzip der doppelte Speicher zur Verfügung. Insgesamt kann man also vier Bilder speichern. Nach dem Einschalten wird default-mäßig Slot 0 gestartet. Mit dem run-Befehl können die Slots zur Laufzeit gewechselt werden.

Mehr Informationen über die Slots gibt es unter https://picaxe.com/basic-commands/directives/hash-slot/ [10] und https://picaxe.com/basic-commands/advanced-picaxe-configuration/run/ [11] – Mit run wird einfach der gerade auszuführende Slot festgelegt.

Zunächst laden wir das Programm picasso_2_diashow_slot1.bas in den Picaxe-Editor und übertragen es per Download auf den Picaxe. Oben im Quellcode steht der Befehl #slot 1, der festlegt, dass das Programm im Slot 1 gespeichert werden soll. Der Befehl #no_data in der nächsten Zeile gibt an, dass der Datenspeicher nicht neu übertragen werden soll. Alle Variablen sind gesharet, sodass die Programme in den beiden Slots Daten austauschen können. Durch den run-Befehl wird das Programm immer von Anfang an in dem entsprechenden Slot gestartet. Der Mechanismus funktioniert also nicht wie die Anweisung gosub, die eine Rückkehr an die Programmstelle vorsieht, an der ein Programm mit gosub verlassen wurde.

Da das Programm in den Slot 1 geladen wurde, dieser aber bisher noch nicht gestartet wird, ist noch keine Veränderung der OLED-Ausgabe sichtbar. Deshalb laden wir das Programm picasso_2_diashow_slot0.bas in den Picaxe-Editor und übertragen es per Download auf den Picaxe. Nun sollte eine Diashow mit vier Bildern angezeigt werden, die etwa alle zwei Sekunden wechseln. Die ersten beiden Bilder werden durch das Programm in Slot 0 ausgegeben, die anderen beiden durch Slot 1.

Passend zum 2. Advent zwei Kerzen

... und zwei Sterne.

Es dauert zwar noch ein paar Wochen bis Weihnachten, aber man kann trotzdem schon eine kleine weihnachtliche Animation auf dem OLED abspielen. Das Prinzip ist ähnlich wie bei der Diashow. Es werden vier Bilder generiert, die nacheinander abgespielt mit ca. 250ms Pause eine kleine bewegte Sequenz ergeben.

Zunächst laden wir das Programm picasso_2_santa_anim_slot1.bas in den Picaxe-Editor und übertragen es per Download auf den Picaxe. Anschließend wiederholen wir das ganze mit dem Programm picasso_2_santa_anim_slot0.bas. Und was erscheint?

Weihnachtliche Animation (4 Bilder) [12]

[13]
Ein Rentier

Damit die Ausgabe der Daten an das OLED möglichst schnell geschieht, wird die Taktgeschwindigkeit des Picaxe mit dem Befehl setfreq auf 32 MHz erhöht (symbol PICAXE_SPEED = m32). Dadurch ändern sich auch andere Timings, z.B. die I2C-Taktgeschwindigkeit oder die Zeitdauer beim pause-Befehl. Anstatt i2cfast muss beispielsweise i2cfast_32 verwendet werden. Bei pause muss der 8-fache Wert übergeben werden, da die Taktgeschwindigkeit acht mal höher ist als die nominalen 4 MHz. Über die Symbole PICAXE_SPEED, I2C_SPEED und DELAY sind die entsprechenden Werte definiert.

Nach Anlegen der Versorgungsspannung muss man das OLED-Modul zunächst initialisieren. Das passiert über das Unterprogramm oledInit. Dort wird durch das Makro i2c_enable_oled als erstes das I2C-Interface des Picaxe als I2C-Host mit einer Übertragungsrate von ca. 400 kHz (Fast-Mode) konfiguriert und als Client die I2C-Adresse des SSD1306 angegeben, einstellbar über Symbol SSD1306_ADDR. Makros und die Initialisierung von Displays beschreiben wir auch im Make Picaxe Special im Detail – im Artikel "Lotto Olé!". [14] Dort nutzen wir das gleiche OLED für einen Lottotipp-Generator.

Außerdem wird mit dem Befehl pokesfr das Register SSP1STAT des Picaxe beschrieben. In diesem Register befindet sich an Bitposition 6 das Bit CKE, um im I2C-Interface den SMBus Mode zu aktivieren, damit die I2C-Pins bereits bei 2,1 Volt einen HIGH-Pegel erkennen.Achtung: Dieses Bit muss nach jedem hi2csetup Befehl gesetzt werden, da es dort wieder auf Null gesetzt wird!

Dafür brauchen wir noch die Adresse von SSP1STAT. Im Picaxe-14M2 arbeitet ein PIC16F1825-Controller, in dessen Datenblatt die Adressen der Spezialregisterfunktionen (SFR) im Abschnitt DEVICE MEMORY MAPS zu finden sind. Das Register SSP1STAT befindet sich an Adresse 0x214 in Bank4. Beim Befehl pokesfr location, data setzt sich die Angabe location wie folgt zusammen:

So ergibt sich der binäre Wert 10010100 bzw. hexadezimal 0x94, den wir als Symbol angeben:

symbol SSP1STAT_SFR = 0x94

Für die OLED-Initialisierung sind eine Reihe von Befehlen notwendig. Diese werden jeweils mit dem Picaxe-Befehl hi2cout in Form von zwei Bytes übertragen, wobei das erste Byte immer Null sein muss und das zweite Byte das entsprechende Kommando überträgt. Bei jedem Aufruf von hi2cout wird automatisch am Anfang ein I2C-Start sowie die Clientadresse und am Ende ein I2C-Stop gesendet.

Nach der Initialisierung wird über das Unterprogramm oledClearDisplay der Bildschirm gelöscht. Hierzu muss zunächst über die OLED-Befehle SSD1306_PAGEADDR und SSD1306_COLUMNADDR ein Fenster mit Angabe der linken oberen sowie der rechten unteren Koordinate aufgezogen werden. Die x-Werte können dabei im Bereich von 0 bis 127 und die y-Werte im Bereich von 0 bis 7 liegen. Die x-Werte beziehen sich auf 128 jeweils 1-Pixel breite Spalten, aber die y-Werte geben eine acht Pixel hohe Zeile an, sodass sich bei 64 Pixeln insgesamt acht mögliche Zeilen ergeben. Der Pixel in der linken obersten Ecke des Displays hat die Koordinate (0,0).

Um das Display zu löschen, setzen wir die Fensterkoordinaten auf (0,0) und (127,7), um den kompletten Displaybereich zu verwenden. Nun können Datenbytes übertragen werden, die durch den SSD1306 fortlaufend in den definierten Anzeigebereich geschrieben werden. Hirbei wird bei Erreichen des rechten Fensterrands automatisch in der nächsten Zeile am linken Fensterrand weitergeschrieben. Dabei wird jedes Datenbyte als acht vertikale Anzeigepixel interpretiert, wobei sich das Bit 0 (LSB) oben befindet. Wenn also 128 Null-Bytes gesendet werden, wurde die oberste Zeile gelöscht. Für alle acht Zeilen sind also insgesamt 128*8 = 1024 Nullbytes notwendig.

Wir verwenden im Aufruf nur 32 Bytes und wiederholen das Schreiben per Schleife 32 mal, um insgesamt auf 1024 Bytes zu kommen. Bei jeder Schreibsequenz muss als erstes Byte 0x40 gesendet werden, damit der SSD1306 die Bytes korrekt als Daten und nicht als Befehle interpretiert.

Um Daten in bestimmte Displaybereiche zu schreiben, kann man die Makros OLED_CURSOR oder OLED_WINDOW verwenden. Hierbei werden als Startkoordinate die x (0..127) und y (0..7, eine Zeile umfasst 8 vertikale Pixel) Werte übergeben, so dass ähnlich wie beim Löschen des Bildschirms ein Fensterbereich aufgezogen wird mit (x,y) als linke obere Ecke. OLED_CURSOR setzt automatisch den letzten Displaypixel unten rechts, wohingegen bei OLED_WINDOW der gewünschte zweite Eckpunkt mit angegeben wird. So kann ein beliebig großes Rechteckfenster ausgewählt werden.

Mithilfe des Makros OLED_DATA können die gewünschten Daten geschrieben werden, die immer als 8 vertikale Pixel zeilenweise dargestellt werden. Solange wir mit Vielfachen von 8 Pixeln vertikal arbeiten, können wir wahlfrei auf das Display schreiben, ohne dass in der Picaxe-Firmware ein Displaybuffer benötigt wird. Ein solcher Buffer müsste für den kompletten Anzeigebereich 128 * 8 = 1024 Bytes groß sein, was jedoch die Ressourcen des Picaxe-14M2 sprengen würde. Stattdessen wird hier einfach nur in den Speicher des SSD1306 geschrieben.

Damit haben wir unseren ersten Test des OLEDs erfolgreich absolviert! Am dritten Advent werden wir uns anschauen, wie man mehr Bilder extern speichern kann und wie die Bilder komfortabler in den Speicher kommen.

Wir wünschen einen schönen 2. Advent! (stri [15])


URL dieses Artikels:
https://www.heise.de/-4978718

Links in diesem Artikel:
[1] https://shop.heise.de/make-picaxe-special-2020/Print
[2] https://www.heise.de/news/PicAsSo-Picaxe-Advents-Sonntagskalender-4948897.html
[3] https://www.heise.de/ratgeber/PicAsSo-Adventskalender-Wir-oeffnen-das-erste-Tuerchen-4970839.html
[4] https://www.heise.de/hintergrund/PicAsSo-Adventskalender-Wir-basteln-am-zweiten-Advent-fleissig-weiter-4978718.html
[5] https://www.heise.de/hintergrund/PicAsSo-Adventskalender-Das-dritte-Tuerchen-darf-endlich-geoeffnet-werden-4980711.html
[6] https://www.heise.de/hintergrund/PicAsSo-Adventskalender-Weihnachts-Basteln-am-vierte-Advent-4988861.html
[7] https://www.heise.de/downloads/18/3/0/1/3/2/3/8/Picaxe_Code_und_oled_bitmaps.zip
[8] http://javl.github.io/image2cpp/
[9] https://www.heise.de/make/
[10] https://picaxe.com/basic-commands/directives/hash-slot/
[11] https://picaxe.com/basic-commands/advanced-picaxe-configuration/run/
[12] https://www.heise.de/bilderstrecke/bilderstrecke_4976646.html?back=4978718
[13] https://www.heise.de/bilderstrecke/bilderstrecke_4976646.html?back=4978718
[14] https://shop.heise.de/make-picaxe-special-2020-inkl.-nano-axe-board-picaxe-08m2/
[15] mailto:stri@make-magazin.de