5 Grafikfunktionen in der Matrix
Grafikelemente können sich überlagern und mit Text vermischen. Würde man sie durch verschiedene Funktionen direkt auf das Dot-Modul übertragen, würden beim Bildaufbau diverse Dots doppelt geflipt. Zur Beschleunigung des Bildaufbaus schreibt man daher mit den Grafikfunktionen der aaFlipra-Library zunächst alles in eine Speicher-Matrix des Arduino Nano.
Matrix Grundfunktionen
Durch Aufrufen der Funktion mUpdate()
wird die neue Matrix mit der Vorgängermatrix verglichen, die den aktuellen realen Flip-Dot Zustand enthält. Die Funktion lässt dann nur die Dots flipen, die gegenüber dem alten Zustand geändert werden müssen. Neben dem Einsparen von Flip-Vorgängen kann bei mehreren in Reihe geschalteten KRUEGER Modulen in allen Modulen gleichzeitig ein Dot manipuliert werden.
void mUpdate(); // neue Matrix auf Dot-Modul ausgeben,
// bestromt nur sich unterscheidende Dots
Die 2 Matrizen werden im dynamischen Speicher des Arduino abgelegt. Bei einem 28x19 Dot-Modul sind das (28 Spalten mal 19 Zeilen zu je 3 Byte) x 2 Matrizen = 2x 28x 3 Byte = 168 Byte. Eine Anzeige mit 4 Stück 28x19 Dot-Modulen benötigt 4x 168 Byte = 672 Byte im dynamischen Speicher des Arduino NANO.
Die Speicherreservierung findet automatisch durch die in der Config eingestellen Anzeigendaten statt. Dieser Speicher steht dann nicht mehr für die eigene Projekte zur Verfügung. Achtung: Der Arduino neigt schon zu "Hängern", wenn beim Kompilieren ein Speicherverbrauch von 75-85% angegeben ist. Größere Projekte mit großen Anzeigen sollten daher per serieller Kommunikation von einem anderen Host-System, wie einem ESP32 oder Raspi erzeugt werden.
// --- Matrix Grundfunktionen ---------------------------------
void mReset(); // Löscht alle Dots in der Matrix[DATANEW]
// in die man mit den Funktionen schreibt.
void mResetold(); // Löscht alle Dots in der Matrix[DATAOLD]
// Diese löscht man in der Regel nicht.
// - sonst würde man ja durcheinander kommen...
void mInvert(); // Invertiert alle Pixel der Matrix[DATANEW].
// - danach mUpdate() aufrufen!
void mUpdate(); // Interne Matrix[DATANEW] auf Display übertragen.
// Verändert nur sich unterscheidende Dots.
Dotmanipulation in der Matrix
In der Matrix setzt und löscht man einzelen Dots mit den Funktionen mSetDot
und mResetDot
. Mit dem Befehl mGetDot
kann man den aktuellen Zustand eines Dots in der Matrix abfragen.
// --- Dotmanipulation in der Matrix -------------------------------
// x unx y abhängig von der Orientierung
void mSetDot(uint8_t userPointX, uint8_t userPointY ); // Dot in der Matrix setzen = farbig stellen
void mResetDot(uint8_t userPointX, uint8_t userPointY ); // Dot in der Matrix löschen = schwarz stellen
uint8_t mGetDot(uint8_t userPointX, uint8_t userPointY ); // Stellung des Dot in der Matrix lesen.
//Rückgabewert 1: Dot ist gesetzt, 0: Dot ist nicht gesetzt
Grafische Funktionen
Die grafischen Funktionen der aaFlipra habe ich aus den üblichen OLED Librarys von Adafruit & Co. abgeleitet. Sie vereinfachen das Zeichnen primitiver Formen. Die Namen der Funktionen sind weitgehend selbsterklärend.
Alle Übergabewert dürfen als int16_t vorzeichenbehaftete zwischen -32768 und +32767 liegen. Die Funktionen schneiden nicht darstellbare Dots problemlos ab.
// --- Grafische Funktionen ------------------------------------
void mDrawHorizontalLine(int16_t userPointX, int16_t userPointY, int16_t length);
// horizontale Linie mit vorgegebener Länge zeichnen
void mDrawVerticalLine(int16_t userPointX, int16_t userPointY, int16_t length);
// vertikale Linie mit vorgegebener Länge zeichnen
void mEraseVerticalLine(int16_t userPointX, int16_t userPointY, int16_t length);
// vertikale Linie mit vorgegebener Länge löschen
void mDrawLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1);
// Linie von P0 zu P1 zeichnen - Stufung bei schrägen Linien wird intern errechnet
void mDrawCircle(int16_t userCenterX, int16_t userCenterY, int16_t radius);
// male einen ungefüllten Kreis um Punkt P0 mit vorgegebenem Radius
void mFillCircle(int16_t userCenterX, int16_t userCenterY, int16_t radius);
// male einen gefüllten Kreis um Punkt P0 mit vorgegebenem Radius
void mDrawRect(int16_t topLeftCornerX, int16_t topLeftCornerY, int16_t width, int16_t height);
// male eine ungefülltes Rechteck mit Linienbreite 1
void mFillRect(int16_t topLeftCornerX, int16_t topLeftCornerY, int16_t width, int16_t height);
// male ein gefülltes Rechteck
void mEraseRect(int16_t topLeftCornerX, int16_t topLeftCornerY, int16_t width, int16_t height);
// lösche einen Rechteckausschnitt
Programmbeispiel
Das folgende Programm findet man in der Arduino IDE unter den vielen Beispielen der aaFlipra-Library.
// **************************************************************************
// aaFlipra-02-grafik
//
// c by Rainer Radow, 30171 Hannover, Germany rainer.radow.org
// **************************************************************************
#include "aaFlipra.h"
aaFlipra ww;
// ==========================================================================
void setup(){
ww.begin();
ww.dotPowerOn(); // schaltet die Flipspannung auf die Treiberbausteine
ww.setCoilFlipDuration(1000);
ww.setAll(2); // setze alle Dots mit 2 Millisekunden Verzögerung
delay(100); // warte 0,1 Sekunde
ww.resetAll(0); // lösche alle Dots schnellstmöglich
delay(100); // warte 0,1 Sekunde
ww.mClean(); // lösche die Matrix vor dem Beschreiben
ww.mFillCircle(14, 9, 4); // Ursprung x14/y9, Radius 4
ww.mDrawVerticalLine(14, 1, 19); // Start x14/y1, Länge 19
ww.mDrawHorizontalLine(4,9,21); // Start x4/y9, Länge 21
ww.mDrawLine(7,2,21,16); // Start x7/y2, Ende x21/y16
ww.mDrawLine(6,17,21,2); // Start x6/y17, Endex21/y2
ww.mUpdate(); // Ausgabe auf dem Dot-Modul
ww.dotPowerOff(); // Dot-Strom aus
}
// ==========================================================================
void loop() {
}
// ===========================================================================
// ===========================================================================
Ergebnis des Demoprogramms aaFlipra-02-grafik.
Die Verwendung der "virtuellen" Dot-Matrix erspart diverse reale Flip-Vorgänge.