Einfaches Arduino-UserInterface mit 16×2-Display

Waehrend die Text-Ausgabe auf einem kleinen 16×2-Zeichen-Display mit LiquidCrystal noch relativ einfach ist, erfordert die Eingabe doch gewoehnlich ein wenig Programmieraufwand, zu dem man oft keine Lust hat und dann doch lieber alles hardcodiert und fuer jeden Wert den Code neu uebertraegt. Um die Lebensspanne meines Arduinos ein wenig zu erhoehen habe ich daher eine kleine Library entwickelt ueber der sich diverse Werte schnell und einfache eingeben lassen. Benoetigt wird lediglich ein Display, welches sich ueber die LiquidCrystal-Library ansprechen laesst, und 5 Buttons (LEFT, RIGHT, UP, DOWN, SELECT) die beliebig selbst implementiert werden duerfen.

Kernfunktionen sind unter anderem ein Menu, Nummerneingabe, Texteingabe und Prozenteingabe. Auch die Buttons lassen sich bequem ansprechen und z.B. Funktionen zuweisen.

Anwendungsbeispiele

Menu:

display16x2-menu

Ein einfaches Menu bei dem ein Eintrag gewaehlt werden kann. Navigiert wird mit den UP und DOWN Tasten. Wenn der gewuenschte Eintrag erreicht wurde, kann er mit SELECT oder RIGHT ausgewaehlt werden. Mit LEFT wird abgebrochen.

 

char *menu[] = {"Entry A", "Entry B", "Entry C", 0}
switch(simpleui.showMenu("Titel", menu)){
   case 0: //Entry A
      ...
   case -1: //Abbruch (en: abort)
...

Prozent:

display16x2-procent

Eine Funktion zur Eingabe von Prozentzahlen, z.B. fuer die Lautstaerke. Mit LEFT und RIGHT macht man 10% Schritte und mit UP und DOWN 1%. Es kann eine Funktion gesetzt werden, die jedes mal aufgerufen wird, wenn der Wert sich aendert (um z.B. einen Probeton abzuspielen).

 

int p = simpleui.getPercent("Titel", 63, onVolumeChange);
...
void onVolumeChange(uint8_t p){
   //Spiele Beispielton
}

Texteingabe:

display16x2-textEine sehr primitive Texteingabe wie sie von Spielekonsolen(„Please enter your name“) bekannt ist.  Mit LEFT/RIGHT wird die Position geaendert und mit UP/DOWN das Symbol veraendert. Mit SELECT wird die Eingabe abgeschlossen. Es koennen klein und Grossbuchstaben sowie Zahlen und Leerzeichen eingegeben werden. Ein Erweiterung um die erlaubten Symbole selber zu setzen ist geplant.

char buffer[20];
simpleui.getString(buffer, 20);

Nummerneingabe:

display16x2-numberEine relativ schnelle Eingabemethode von Nummern. Ueber LEFT/RIGHT wird der Summand veraendert (Zehnerpotenz 1,10,100,…) und mit UP/DOWN der Summand addiert oder subtrahiert. Mit SELECT  wird die Eingabe abgeschlossen.

 

int i = simpleui.getUInt();

 

Konfiguration

Zu erst musst du LiquidCrystal initalisieren in dem du ein entsprechendes Objekt erzeugst. Die Parameter entsprechen den verwendeten Pins zu Ansteuerung des Displays. Du findest sie in der Anleitung oder Homepage deines Displays.
LiquidCrystal lcd(8,9,4,5,6,7);
Als naechstes erstellst du dann analog das SimpleUI16x2-Objekt, dem du das LiquidCrystal-Objekt und eine Funktion zum Abfragen der Buttons gibst.
LiquidCrystal lcd(8,9,4,5,6,7);
SimpleUI16x2 simpleui(&lcd,getButton);

//The Button function you have to define by yourself
uint8_t getButton(){
	int adc_key_in = analogRead(0);
	if (adc_key_in > 790) return BUTTON_NONE;
	if (adc_key_in < 50) {
		return BUTTON_RIGHT;
	}
	if (adc_key_in < 195) {
		return BUTTON_UP;
	}
	if (adc_key_in < 380) {
		return BUTTON_DOWN;
	}
	if (adc_key_in < 555) {
		return BUTTON_LEFT; 
	}
	if (adc_key_in < 790) {
		return BUTTON_SELECT;  
	} 
	return BUTTON_NONE;
}
Nun solltest du in der Lage sein, das Nutzerinterface zu benutzen. Siehe auch das in der Library enthaltene Beispiel.

 

Download

Du findeste die Library in Git unter https://github.com/dserv01/SimpleUI16x2.

Um die Library zu benutzen musst du den Ordner SimpleUI16x2 in den Ordner libraries in deinem Sketchbook-Verzeichnis verschieben. Sollte dieser Ordner nicht existieren, so kannst du ihn einfach anlegen. Unter Umstaenden musst du dir auch noch die LiquidCrystal-Library besorgen, sollte sie in deiner Arduino-Installation nicht standardmaessig enthalten sein.

./sketchbook/libraries/SimpleUI16x2/SimpleUI16x2.h
./sketchbook/libraries/SimpleUI16x2/SimpleUI16x2.cpp 
./sketchbook/libraries/SimpleUI16x2/examples/MenuExample/MenuExample.ino

Die Library befindet sich noch im Aufbau und wird in der naechsten Zeit, ebenso wie dieser Artikel fertiggestellt.

9 Gedanken zu „Einfaches Arduino-UserInterface mit 16×2-Display“

  1. Hallo Dominik,
    meine C++-/OOP – Kenntnisse sind eher bescheiden. Aus dem Grund war ich begeistert Deine Library zu finden, die auf einem LCD-Display so einfach Interaktion möglich macht. Im ganzen Netz habe ich nichts vergleichbares gefunden.
    Leider habe ich das gleiche Problem wie andere User in diesem Thread. Ich benötige die Anbindung an ein I2C-Display und bin mit den Fehlermeldungen des Compilers überfordert.
    Vielleicht motiviert Dich das ja Dir die Lib noch mal anzuschauen.

    Gruß, Miss Franken

  2. Danke für die schnelle Antwort.

    Die klassische Variante läuft auch nicht, auch nicht das
    MenuExample der „SimpleUI16x2“

    Habe das auch schon auf Verschiedenen Rechnern, Win XP / 7
    probiert, und immer das gleiche.

    ###### Fehlermeldung ############

    In file included from MenuExample.ino:2:

    D:\mm\Eigene Dateien\Arduino\arduino-1.0.5-r2\libraries\SimpleUI16x2/SimpleUI16x2.h:75: error: ISO C++ forbids initialization of member ‚brightness_‘

    D:\mm\Eigene Dateien\Arduino\arduino-1.0.5-r2\libraries\SimpleUI16x2/SimpleUI16x2.h:75: error: making ‚brightness_‘ static

    D:\mm\Eigene Dateien\Arduino\arduino-1.0.5-r2\libraries\SimpleUI16x2/SimpleUI16x2.h:75: error: ISO C++ forbids in-class initialization of non-const static member ‚brightness_‘

    ###### Fehlermeldung Ende############

    Unter welcher Arduino IDE ist das ganze mal gelaufen?
    Kann ja sonst auch mal eine alte Version installieren.

    Gruß
    Manu

    1. Tatsächlich scheint die Library mit der aktuellen Version nicht zu kompilieren. Ich werde versuchen das heute oder morgen zu korrigieren. Scheinbar gab es Änderungen im benutzten C++ Standard, die der Code nicht erfüllt.

      Grüße,
      Dominik

    2. Ok, ich schätze dass das Problem lustigerweise nicht eine zu neue Version, sondern ein zu alter C++-Compiler war. Der aktuelle GCC sollte keine Probleme haben. Ich habe mal den Code geändert, sodass er nun auch mit anderen Compilern zurecht kommen sollte. Ich habe den Commit jedoch direkt auf Github gemacht und nicht getestet, weil meine lokale Version zu viele undokumentierte Änderungen hat.
      Ich hoffe das Problem ist nun behoben.

  3. Hallo,
    toller Beitrag, endlich eine einfache Erklärung.

    Leider funktioniert die Librarie „SimpleUI16x2.h“
    unter der aktuellen „Arduino IDE 1.0.5“ nicht mehr.

    Der Compiler meldet mehrere Fehler :-( :-(

    Habe folgendes Display an einem Arduino Uno.

    http://www.geeetech.com/wiki/index.php/Serial_I2C_1602_16%C3%972_Character_LCD_Module

    Die Beispiele der librarie für mein Display „Arduino 1602 I2C – library for Arduino IDE 1.0“
    funktionieren.

    Würde mich freuen wenn du irgendwann die Zeit findest und das überarbeiten könntest.

    Gruß
    Manu

    1. Das Problem liegt (vermutlich) darin, dass du die I2C-Version verwendest, während die Library für die klassische Variante geschrieben worden ist.
      Da das Interface aber (scheinbar) gleich ist, sollte es ausreichen einfach überall (Arduino und Libray (SimpleUI16x2.cpp und SimpleUI16x2.h)) LiquidCrystal durch LiquidCrystal_I2C zu ersetzen. Ich werde aber die Tage mal versuchen, die Library generischer zu machen damit dies einfacher wird.

      1. Hallo, ich habe deine Library erfolgreich testen und einsetzten können. Nur habe ich ein Display mit I2C BUS und konnte es nicht zum leben erwecken. Ich habe alles soweit abgeändert wie du es geschrieben hast, jedoch wenn der Befehl [SimpleUI16x2 simpleui(&lcd,getButton);] aufgerufen wird, verliert das Display jegliche Funktion. Wie ich vermute, liegt es daran, dass [Wire.begin(); lcd.init(); lcd.backlight();] nicht ausgeführt werden. An welcher stelle muss ich die denn aufrufen? Ich stehe gerade auf dem Schlauch.

        1. Also vermutlich müssen diese Funktionen vor der Erzeugung des SimpleUI16x2 aufgerufen werden, weil der Constructor bereits auf das LCD zugreift (Die Displaygröße festlegt und das Display löscht). Wenn dies gemacht wird, bevor das Display korrekt initialisiert wurde, kann es natürlich zu Fehlern kommen.
          Du kannst
          A) Die Befehle im Setup ausführen und anschliessend das SimpleUI16x2 erzeugen (muss dann natürlich als Pointer gemacht werden)
          B) Die Befehle im Constructor(bevor lcd verwendet wird) der SimpleUI16x2 ergänzen. Die Abhängigkeiten (für Wire) müssen vermutlich sowohl in der .ino als auch in der .h ergänzt werden.
          Eventuell könntest du dem Constructor auch einen Funktionspointer übergeben der die Initialisierung macht, was relativ häßlich ist, aber vermutlich sehr einfach.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

Time limit is exhausted. Please reload CAPTCHA.