Das Smart-I2C Graphic Display kommt bei verschiedenen Projekten zum Einsatz. Neulich begegneten uns zwei Probleme, die zu kleinen Erweiterungen der Funktionalität führten.
Rechts-bündige Texte ausgeben
Manchmal ist es hilfreich, Texte rechtsbündig auszugeben. Das ist zum Beispiel nützlich, wenn man mehrere Zahlenwerte untereinander positionieren möchte.
Also wurde die Firmware für das Display noch einmal geöffnet und um die Funktion draw_radj_str() erweitert. Der zugehörige Command-Token ist 37. Damit gibt es jetzt drei Funktionen zur Text-Ausgabe, wie in Smart I2C GLCD Instruction Set_v1-1 erläutert:
Das folgende Beispiel zeigt einen Arduino-Sketch, der die drei Text-Funktionen verwendet und die Ausgabe produziert, die hier als Beitrags-Bild zu sehen ist.
In der setup()-Funktion werden die drei Texte ausgegeben. In der loop()-Funktion wird dann gezeigt, wie man z.B. eine Zahl in die untere, rechte Ecke des Displays setzt. Dazu wird die Zahl mit itoa() in einen String konvertiert, der dann mit draw_radj_str() ausgegeben wird.
Die neue Firmware für das I2C GLCD und das Instructions-Dokument stehen auf der Ressourcen-Seite bereit. Auch die Arduino-Bibliothek wurde angepasst.
Texte aus dem Programm-Speicher ausgeben
Ein notorisches Problem der 8-Bit AVR-Prozessoren ist der sehr limitierte RAM-Speicherplatz. Zum Beispiel hat der ATmega328 nur 2 kByte RAM an Board. Die üblichen Funktionen zur Textausgabe, z.B. draw_str(„Dieses ist Text“); haben den Nachteil, dass der Text erst in das RAM kopiert wird, bevor er zur Ausgabe gelangt. Das ist für konstante Texte, wie sie z.B. als Titel-Texte, Menü-Items oder Beschriftungen häufig zum Einsatz kommen, nicht sinnvoll und führt schnell zu Engpässen im RAM-Speicher.
Zum Glück gibt es die Möglichkeit, Texte direkt aus dem Flash-Programm-Speicher auszugeben. Davon hat der ATmega eine ganze Menge zu bieten. Wenn man mit dem Atmel-Studio in C arbeitet, sieht das etwa so aus:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
#include <avr/pgmspace.h> #include "i2cmaster.h" #define GLCD_DRAW_STR 33 /* glcd_draw_pgm_string ------------------------------------------ * Funktion to plot a zero-terminated string from program memory */ void glcd_draw_pgm_str(const char *my_str) { char my_char; i2c_start_wait(GLCD_ADDR + I2C_WRITE); i2c_write(GLCD_DRAW_STR); do { my_char = pgm_read_byte(my_str); i2c_write(my_char); ++my_str; } while (my_char > 0); i2c_stop(); }; ... const char str_title[] PROGMEM = "Dieses ist ein Titel-Text"; glcd_draw_pgm_str(str_title); ... |
Dieses Beispiel geht davon aus, dass die I2C-Funktionen bereit stehen. Ich verwende üblicherweise die I2C-Master-Bibliothek von Peter Fleury (siehe http://jump.to/fleury).
Natürlich klappt das auch mit dem Arduino. Die entsprechenden Funktionen zur Textausgabe aus dem Programm-Speicher wurden in die GLCD-Bibliothek arduino_glcd_functions aufgenommen und heißen draw_pgm_str(), draw_center_pgm_str() und draw_radj_pgm_str(). Die Anwendung ist damit sehr einfach, wie das folgende Beispiel zeigt:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
#include <Wire.h> #include <glcd_functions.h> #include <avr/pgmspace.h> const char str_title[] PROGMEM = "Dieses ist ein Titel-Text"; glcd gd(0x20); // creates an instance of the Graphic LCD ... gd.draw_pgm_str(str_title); // plots a string from program memory ... |
Die Arduino-Bibliothek mit den neuen Funktionen zur Textausgabe ist – wie immer – auf der Ressourcen-Seite verfügbar.
Bleibt noch zu erwähnen, dass diese Methode natürlich nur für Texte und Strings klappt, die als Konstante definiert werden können und sich im Laufe des Programms nicht ändern. Und dass das Problem des limitierten RAM-Speichers eine AVR-8-Bit-Eigenart ist. Sobald man mit grösseren Prozessoren, z.B. den STM32-Prozessoren oder gar dem Raspberry Pi unterwegs ist, sind solche Klimmzüge zur Text-Ausgabe nicht mehr notwendig.
Ich hoffe, die neuen Funktionen sind hilfreiche. Kommentare und Rückmeldungen sind sehr willkommen.