|
|
(31 dazwischenliegende Versionen des gleichen Benutzers werden nicht angezeigt) |
Zeile 55: |
Zeile 55: |
| == mark-gladding /packed-font == | | == mark-gladding /packed-font == |
| Quelle: https://github.com/mark-gladding/packed-font | | Quelle: https://github.com/mark-gladding/packed-font |
| + | |
| + | == peterhinch /micropython-font-to-py== |
| + | Quelle: https://github.com/peterhinch/micropython-font-to-py |
| + | |
| + | Peter Hinsch hat eine Klasse '''Writer''' geschrieben, die es ermöglicht andere als den Standardfont in den Frambuffer zu schreiben.Dazu wird für jeden benötigten Font eine eigene Instanz der Klasse Writer geschrieben. Über diese kann dann Text in dem entsprechenden Font erstellt werden. |
| + | |
| + | === Die Dateien=== |
| + | Die dazu erforderlichen Dateien können unter der o.a. URL mit Klick auf '''Code''' (grüner Reiter rechts oben) und dann '''Download Zip''' herunter geladen werden. |
| + | |
| + | Uns interessieren die Dateien im Verzeichnis '''writer''': |
| + | * writer.py |
| + | * courier20.py |
| + | * font10.py |
| + | * font6.py |
| + | * freesans20.py |
| + | * ssd1306_setup.py |
| + | |
| + | Außerdem ist noch Treiberdatei '''ssd1306.py''', die hier (https://github.com/micropython/micropython-lib/blob/master/micropython/drivers/display/ssd1306/ssd1306.py) heruntergeladen werden kann, erforderlich. |
| + | |
| + | Diese Dateien werden in das Verzeichnis '''/lib''' des Pico kopiert. |
| + | |
| + | Voraussetzung für den Einsatz der Klasse '''Writer''' ist, das der Displaytreiber ('''ssd1306.py''') die Klasse '''Framebuffer''' erbt. |
| + | |
| + | Peter hat noch eine weitere Datei hinzugefügt: '''ssd1306_setup.py'''. Diese Datei stellt die Funktion '''setup()''' bereit. In dieser ist das Einrichten der Schnittstelle (I2C oder SPI) und die Erstellung der Displayinstanz (hier '''ssd''') zusammengefasst. Hier müssen die entsprechenden Pins eingetragen und die Parameter der Aufrufe dem verwendeten Microcontroller entsprechend angepasst werden. Die Originaldatei ist für das '''Pyboard''' geschrieben. |
| + | |
| + | Bei der Auswahl der Schnittstellen kann man zwischen einer Hardwareschnittstelle und einer Software Inplementierung wählen. Peter schreibt, das die I2C-Hardware nicht funktioniert. Das beruht auf einem Fehler in der '''ssd1306_setup.py.''' Dazu gleich mehr. |
| + | |
| + | === ssd1306_setup.py einrichten=== |
| + | Hier der Inhalt von ssd1306_setup.py |
| + | <pre> |
| + | import machine |
| + | from ssd1306 import SSD1306_SPI, SSD1306_I2C |
| + | |
| + | WIDTH = const(128) |
| + | HEIGHT = const(64) |
| + | |
| + | def setup(use_spi=False, soft=True): |
| + | if use_spi: |
| + | # Pyb SSD |
| + | # 3v3 Vin |
| + | # Gnd Gnd |
| + | # X1 DC |
| + | # X2 CS |
| + | # X3 Rst |
| + | # X6 CLK |
| + | # X8 DATA |
| + | pdc = machine.Pin('X1', machine.Pin.OUT_PP) |
| + | pcs = machine.Pin('X2', machine.Pin.OUT_PP) |
| + | prst = machine.Pin('X3', machine.Pin.OUT_PP) |
| + | if soft: |
| + | spi = machine.SPI(sck=machine.Pin('X6'), mosi=machine.Pin('X8'), miso=machine.Pin('X7')) |
| + | else: |
| + | spi = machine.SPI(1) |
| + | ssd = SSD1306_SPI(WIDTH, HEIGHT, spi, pdc, prst, pcs) |
| + | else: # I2C |
| + | # Pyb SSD |
| + | # 3v3 Vin |
| + | # Gnd Gnd |
| + | # Y9 CLK |
| + | # Y10 DATA |
| + | if soft: |
| + | pscl = machine.Pin('Y9', machine.Pin.OPEN_DRAIN) |
| + | psda = machine.Pin('Y10', machine.Pin.OPEN_DRAIN) |
| + | i2c = machine.I2C(scl=pscl, sda=psda) |
| + | else: |
| + | i2c = machine.I2C(2) |
| + | ssd = SSD1306_I2C(WIDTH, HEIGHT, i2c) |
| + | return ssd |
| + | </pre> |
| + | |
| + | ==== Fehler beseitigen==== |
| + | Peter hat die Einrichtung der I2C-Pins in die IF-Anweisung geschrieben. Dadurch sind sie bei der Hardware Initialisierung nicht vorhanden: |
| + | <pre> |
| + | if soft: |
| + | pscl = machine.Pin('Y9', machine.Pin.OPEN_DRAIN) |
| + | psda = machine.Pin('Y10', machine.Pin.OPEN_DRAIN) |
| + | i2c = machine.I2C(scl=pscl, sda=psda) |
| + | else: |
| + | i2c = machine.I2C(2) |
| + | ssd = SSD1306_I2C(WIDTH, HEIGHT, i2c) |
| + | </pre> |
| + | Die korrigierte Fassung sieht so aus: |
| + | <pre> |
| + | pscl = machine.Pin('Y9', machine.Pin.OPEN_DRAIN) |
| + | psda = machine.Pin('Y10', machine.Pin.OPEN_DRAIN) |
| + | |
| + | if soft: |
| + | i2c = machine.I2C(scl=pscl, sda=psda) |
| + | else: |
| + | i2c = machine.I2C(2) |
| + | ssd = SSD1306_I2C(WIDTH, HEIGHT, i2c) |
| + | </pre> |
| + | und funktioniert. |
| + | |
| + | ==== Parameter dem µC anpassen==== |
| + | Die initialisierung der I2C-Schnittelle erfolgt folgendermaßen: |
| + | |
| + | =====Raspberry Pi Pico - SoftI2C:===== |
| + | <pre> |
| + | from machine import Pin, SoftI2C |
| + | |
| + | i2c = SoftI2C(scl=Pin(5), sda=Pin(4), freq=100_000) |
| + | </pre> |
| + | =====Raspberry Pi Pico - HardI2C:===== |
| + | <pre> |
| + | from machine import Pin, I2C |
| + | |
| + | i2c = I2C(0) # default assignment: scl=Pin(9), sda=Pin(8) |
| + | i2c = I2C(1, scl=Pin(3), sda=Pin(2), freq=400_000) |
| + | </pre> |
| + | |
| + | =====ESP32 - SoftI2C:===== |
| + | <pre> |
| + | from machine import Pin, SoftI2C |
| + | |
| + | i2c = SoftI2C(scl=Pin(5), sda=Pin(4), freq=100000) |
| + | </pre> |
| + | =====ESP32 - HardI2C:===== |
| + | <pre> |
| + | from machine import Pin, I2C |
| + | |
| + | i2c = I2C(0) |
| + | i2c = I2C(1, scl=Pin(5), sda=Pin(4), freq=400000) |
| + | </pre> |
| + | |
| + | === ssd1306_setup.py für das Demoboard=== |
| + | Hier wird nur der veränderte Ausschnitt für I2C für das Demoboard gezeigt. |
| + | <pre> |
| + | import machine |
| + | from ssd1306 import SSD1306_SPI, SSD1306_I2C |
| + | |
| + | ... |
| + | |
| + | # Diese beiden Zeilen sind nicht erforderlich |
| + | # pscl = machine.Pin('Y9', machine.Pin.OPEN_DRAIN) |
| + | # psda = machine.Pin('Y10', machine.Pin.OPEN_DRAIN) |
| + | |
| + | if soft: |
| + | i2c = SoftI2C(scl=Pin(21), sda=Pin(20), freq=100_000) |
| + | else: |
| + | i2c = I2C(0, sda=Pin(20), scl=Pin(21)) |
| + | ssd = SSD1306_I2C(WIDTH, HEIGHT, i2c) |
| + | </pre> |
| + | === ssd1306_setup.py benutzen=== |
| + | Natürlich ist die Einrichtung der I2C-Schnittstelle und das Erzeugen der Display-Instanz auch auf herkömmliche Weise möglich. |
| + | |
| + | Wenn die '''ssd1306_setup.py''' verwendet werden soll geschieht das wie folgend:<br> |
| + | * '''setup()''' ist eine Funktion und wird als solche aufgerufen. |
| + | * Als Parameter muss ihr '''use_spi = True/False''' übergeben werden. |
| + | * Der Parameter '''soft''' ist optional, da er schon mit '''True''' vorbelegt ist. |
| + | * Will man die Hardware-Schnittstelle verwenden, so muss auch '''soft=False''' übergeben werden. |
| + | * Zurückgegeben wird das Display-Objekt. |
| + | |
| + | =====def setup:===== |
| + | <pre> |
| + | def setup(use_spi=False, soft=True): |
| + | </pre> |
| + | |
| + | <pre> |
| + | from ssd1306_setup import WIDTH, HEIGHT, setup |
| + | |
| + | use_spi=False |
| + | ssd = setup(use_spi) |
| + | </pre> |
| + | |
| + | <pre style="color: red"> |
| + | Testen ob setup() funktioniert. |
| + | </pre> |
| + | |
| + | === Die Fonts=== |
| + | |
| + | Diese 4 Fonts sind in dem Dateienpaket enthalten: |
| + | * courier20.py |
| + | * font10.py |
| + | * font6.py |
| + | * freesans20.py |
| + | Leider enthalten Sie keine Umlaute und manche Sonderzeichen fehlen. |
| + | |
| + | Fonts werden ins Programm durch einen Import eingeführt. Sie belegen dann ggf. viel Speicherplatz: |
| + | <pre> |
| + | import courier20 |
| + | </pre> |
| + | |
| + | <pre style="color: red"> |
| + | Testen ob andere Fonts von obigen Projekten funktionieren. |
| + | </pre> |
| + | |
| + | === Writer-Instanzen erstellen=== |
| + | Wenn ein oder mehrere Fonts importiert sind, können wir Writer-Instanzen erzeugen, die diese Fonts verwenden: |
| + | <pre> |
| + | |
| + | </pre> |
| + | |
| + | === Ein Erster Test=== |
| + | |
| + | |
| + | === Die Demo-Programme ausprobieren=== |
| + | |
| + | |
| + | ==== writer_gui.py'==== |
| + | |
| + | Die Dauer für das Zeichnen von einem Kreis mit der '''circle'''-Funktion aus '''writer_gui.py''' im Vergleich zur '''ellipse'''-Funktion von '''Framebuffer''': |
| + | <pre> |
| + | Schleifen_dauer = 5.1 µS |
| + | Zeit_circle = 3813.384 µS |
| + | Zeit_ellipse = 162.312 µS |
| + | </pre> |
| + | Die Zeit der Schleife wurde herausgerechnet.<br> |
| + | Der Radius betrug in beiden Fällen 24 Pixel. |
| + | |
| + | === Neue Fonts erzeugen=== |
| + | |
| + | |
| + | == Links== |
| + | https://github.com/zuku/font16seg |
Aktuelle Version vom 14. April 2024, 15:10 Uhr
maysrp /ssd1306_font
Quelle: https://github.com/maysrp/ssd1306_font
Diese Lösung erscheint auf den ersten Blick interessant. Leider funktioniert sie bei meinem ersten Test nicht.
Problem
in font.py werden die Files ASC16 ... 32 geöffnet (mit open). Sie werden aber nicht wieder geschlossen.
Ob das der Grund der Fehlermeldung ist weiß ich nicht. Es gibt jedenfalls eine Fehlermeldung, die ich nicht beseitigen kann. Deshalb scheidet diese Lösung aus.
magnums /MicroPython-Oled-ssd1306-largeFont
Quelle: https://github.com/magnums/MicroPython-Oled-ssd1306-largeFont
Diese Lösung funktioniert.
Allerdings ist eine Anpassung für das Demoboard erforderlich.
Anpassung für das Demoboard:
In main.py muss von SoftI2C auf I2C umgestellt werden. Dazu sind die beiden folgenden Zeilen so umzuändern, wie hier dargestellt:
Zeile 3:
from machine import Pin, I2C
Zeile 13:
i2c = I2C(0, scl=Pin(21), sda=Pin(20))
In Thonny erscheint die folgende Ausgabe wenn main.py ausgeführt wird:
>>> %Run -c $EDITOR_CONTENT
MPY: soft reboot
Orientation: horiz Reversal: False
>>>
Die Zeile: Orientation: horiz Reversal: False wird in writer.py erzeugt. Ihre Ausgabe wird verhindert, wenn in Zeile 19
def __init__(self, device, font, verbose=False):
verbose auf False gesetzt wird, wie oben dargestellt.
Nachteil
Es wird nur ein Font mitgeliefert.
nickpmulder /ssd1306big
Quelle: https://github.com/nickpmulder/ssd1306big
Hierbei handelt es sich um eine Erweiterung von ssd1306.py.
Die Buchstaben werden hier mit Grafikbefehlen gezeichnet. Deshalb scheidet diese Lösung für mich aus.
mark-gladding /packed-font
Quelle: https://github.com/mark-gladding/packed-font
peterhinch /micropython-font-to-py
Quelle: https://github.com/peterhinch/micropython-font-to-py
Peter Hinsch hat eine Klasse Writer geschrieben, die es ermöglicht andere als den Standardfont in den Frambuffer zu schreiben.Dazu wird für jeden benötigten Font eine eigene Instanz der Klasse Writer geschrieben. Über diese kann dann Text in dem entsprechenden Font erstellt werden.
Die Dateien
Die dazu erforderlichen Dateien können unter der o.a. URL mit Klick auf Code (grüner Reiter rechts oben) und dann Download Zip herunter geladen werden.
Uns interessieren die Dateien im Verzeichnis writer:
- writer.py
- courier20.py
- font10.py
- font6.py
- freesans20.py
- ssd1306_setup.py
Außerdem ist noch Treiberdatei ssd1306.py, die hier (https://github.com/micropython/micropython-lib/blob/master/micropython/drivers/display/ssd1306/ssd1306.py) heruntergeladen werden kann, erforderlich.
Diese Dateien werden in das Verzeichnis /lib des Pico kopiert.
Voraussetzung für den Einsatz der Klasse Writer ist, das der Displaytreiber (ssd1306.py) die Klasse Framebuffer erbt.
Peter hat noch eine weitere Datei hinzugefügt: ssd1306_setup.py. Diese Datei stellt die Funktion setup() bereit. In dieser ist das Einrichten der Schnittstelle (I2C oder SPI) und die Erstellung der Displayinstanz (hier ssd) zusammengefasst. Hier müssen die entsprechenden Pins eingetragen und die Parameter der Aufrufe dem verwendeten Microcontroller entsprechend angepasst werden. Die Originaldatei ist für das Pyboard geschrieben.
Bei der Auswahl der Schnittstellen kann man zwischen einer Hardwareschnittstelle und einer Software Inplementierung wählen. Peter schreibt, das die I2C-Hardware nicht funktioniert. Das beruht auf einem Fehler in der ssd1306_setup.py. Dazu gleich mehr.
ssd1306_setup.py einrichten
Hier der Inhalt von ssd1306_setup.py
import machine
from ssd1306 import SSD1306_SPI, SSD1306_I2C
WIDTH = const(128)
HEIGHT = const(64)
def setup(use_spi=False, soft=True):
if use_spi:
# Pyb SSD
# 3v3 Vin
# Gnd Gnd
# X1 DC
# X2 CS
# X3 Rst
# X6 CLK
# X8 DATA
pdc = machine.Pin('X1', machine.Pin.OUT_PP)
pcs = machine.Pin('X2', machine.Pin.OUT_PP)
prst = machine.Pin('X3', machine.Pin.OUT_PP)
if soft:
spi = machine.SPI(sck=machine.Pin('X6'), mosi=machine.Pin('X8'), miso=machine.Pin('X7'))
else:
spi = machine.SPI(1)
ssd = SSD1306_SPI(WIDTH, HEIGHT, spi, pdc, prst, pcs)
else: # I2C
# Pyb SSD
# 3v3 Vin
# Gnd Gnd
# Y9 CLK
# Y10 DATA
if soft:
pscl = machine.Pin('Y9', machine.Pin.OPEN_DRAIN)
psda = machine.Pin('Y10', machine.Pin.OPEN_DRAIN)
i2c = machine.I2C(scl=pscl, sda=psda)
else:
i2c = machine.I2C(2)
ssd = SSD1306_I2C(WIDTH, HEIGHT, i2c)
return ssd
Fehler beseitigen
Peter hat die Einrichtung der I2C-Pins in die IF-Anweisung geschrieben. Dadurch sind sie bei der Hardware Initialisierung nicht vorhanden:
if soft:
pscl = machine.Pin('Y9', machine.Pin.OPEN_DRAIN)
psda = machine.Pin('Y10', machine.Pin.OPEN_DRAIN)
i2c = machine.I2C(scl=pscl, sda=psda)
else:
i2c = machine.I2C(2)
ssd = SSD1306_I2C(WIDTH, HEIGHT, i2c)
Die korrigierte Fassung sieht so aus:
pscl = machine.Pin('Y9', machine.Pin.OPEN_DRAIN)
psda = machine.Pin('Y10', machine.Pin.OPEN_DRAIN)
if soft:
i2c = machine.I2C(scl=pscl, sda=psda)
else:
i2c = machine.I2C(2)
ssd = SSD1306_I2C(WIDTH, HEIGHT, i2c)
und funktioniert.
Parameter dem µC anpassen
Die initialisierung der I2C-Schnittelle erfolgt folgendermaßen:
Raspberry Pi Pico - SoftI2C:
from machine import Pin, SoftI2C
i2c = SoftI2C(scl=Pin(5), sda=Pin(4), freq=100_000)
Raspberry Pi Pico - HardI2C:
from machine import Pin, I2C
i2c = I2C(0) # default assignment: scl=Pin(9), sda=Pin(8)
i2c = I2C(1, scl=Pin(3), sda=Pin(2), freq=400_000)
ESP32 - SoftI2C:
from machine import Pin, SoftI2C
i2c = SoftI2C(scl=Pin(5), sda=Pin(4), freq=100000)
ESP32 - HardI2C:
from machine import Pin, I2C
i2c = I2C(0)
i2c = I2C(1, scl=Pin(5), sda=Pin(4), freq=400000)
ssd1306_setup.py für das Demoboard
Hier wird nur der veränderte Ausschnitt für I2C für das Demoboard gezeigt.
import machine
from ssd1306 import SSD1306_SPI, SSD1306_I2C
...
# Diese beiden Zeilen sind nicht erforderlich
# pscl = machine.Pin('Y9', machine.Pin.OPEN_DRAIN)
# psda = machine.Pin('Y10', machine.Pin.OPEN_DRAIN)
if soft:
i2c = SoftI2C(scl=Pin(21), sda=Pin(20), freq=100_000)
else:
i2c = I2C(0, sda=Pin(20), scl=Pin(21))
ssd = SSD1306_I2C(WIDTH, HEIGHT, i2c)
ssd1306_setup.py benutzen
Natürlich ist die Einrichtung der I2C-Schnittstelle und das Erzeugen der Display-Instanz auch auf herkömmliche Weise möglich.
Wenn die ssd1306_setup.py verwendet werden soll geschieht das wie folgend:
- setup() ist eine Funktion und wird als solche aufgerufen.
- Als Parameter muss ihr use_spi = True/False übergeben werden.
- Der Parameter soft ist optional, da er schon mit True vorbelegt ist.
- Will man die Hardware-Schnittstelle verwenden, so muss auch soft=False übergeben werden.
- Zurückgegeben wird das Display-Objekt.
def setup:
def setup(use_spi=False, soft=True):
from ssd1306_setup import WIDTH, HEIGHT, setup
use_spi=False
ssd = setup(use_spi)
Testen ob setup() funktioniert.
Die Fonts
Diese 4 Fonts sind in dem Dateienpaket enthalten:
- courier20.py
- font10.py
- font6.py
- freesans20.py
Leider enthalten Sie keine Umlaute und manche Sonderzeichen fehlen.
Fonts werden ins Programm durch einen Import eingeführt. Sie belegen dann ggf. viel Speicherplatz:
import courier20
Testen ob andere Fonts von obigen Projekten funktionieren.
Writer-Instanzen erstellen
Wenn ein oder mehrere Fonts importiert sind, können wir Writer-Instanzen erzeugen, die diese Fonts verwenden:
Ein Erster Test
Die Demo-Programme ausprobieren
writer_gui.py'
Die Dauer für das Zeichnen von einem Kreis mit der circle-Funktion aus writer_gui.py im Vergleich zur ellipse-Funktion von Framebuffer:
Schleifen_dauer = 5.1 µS
Zeit_circle = 3813.384 µS
Zeit_ellipse = 162.312 µS
Die Zeit der Schleife wurde herausgerechnet.
Der Radius betrug in beiden Fällen 24 Pixel.
Neue Fonts erzeugen
Links
https://github.com/zuku/font16seg