Einfaches Arduino-UserInterface mit 16×2-Display

[en]The English translation may be not complete, since I just started to write bilingual, and also not very good.[/en]
[de]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.[/de]

[en]While Text-Output on 16×2 Character-Displays with LiquidCrystal is quite easy, input is a little bit harder. Hence you are often coding the parameters hard and flash the arduino for every value new. To expand the lifetime of my Arduino I wrote a little library for simple Input. You need only a display, compatible with the LiquidCrystal-Library, and 5 Buttons (LEFT, RIGHT, UP, DOWN, SELECT) which you can implement as you like.

The mainfunctions are for example a Menu, Numberinput, Textinput and Percentinput. Also the buttons can be accessed easily and assigned functions.[/en]

[de]Anwendungsbeispiele[/de][en]Examples of user[/en]

Menu:

display16x2-menu [de]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.[/de][en]A simple menu where you can chose between entries. You can navigate through it using the UP and DOWN keys. If you have reached the desired entry you can select it with SELECT or RIGHT. Use LEFT to abort.

[/en]

 

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

[de]Prozent:[/de][en]Percent:[/en]

display16x2-procent[de]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).[/de][en]A function to input percent-values, for example the volume. With LEFT and RIGHT you change in 10% steps, with UP and DOWN in 1% steps. You can set a function, which is called everytime the value changes (to play a sound with the new volume etc.). [/en]

 

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();

 

[de]Konfiguration[/de][en]Configuration[/en]

[de]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.[/de][en]First you have to initalize LiquidCrystal by creating the specific object. The parameter are the pins for controlling the display. You will find them in the manuals or homepage for your display.[/en]

LiquidCrystal lcd(8,9,4,5,6,7);

[de]Als naechstes erstellst du dann analog das SimpleUI16x2-Objekt, dem du das LiquidCrystal-Objekt und eine Funktion zum Abfragen der Buttons gibst.[/de][en]In the next step you create the SimpleUI16x2-object which you give the LiquidCrystal-object and a function to query the buttons.[/en]

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;
}

[de]Nun solltest du in der Lage sein, das Nutzerinterface zu benutzen. Siehe auch das in der Library enthaltene Beispiel.[/de][en]Now you should be able to use the UserInterface. You should take a look at the example in the library.[/en]

 

Download

[de]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.[/de]
[en]You will find the library in git under https://github.com/dserv01/SimpleUI16x2.

To use the library you have to move the folder SimpleUI16x2 into the folder libraries of your Sketchbook-Folder. If this Folder doesn’t exist yet, you can simply create it. Maybe you also need the LiquidCrystal-Libary, if it is not included in your Arduino-Installation by default.[/en]

./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.

13 thoughts on “Einfaches Arduino-UserInterface mit 16×2-Display

  1. 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

    Like

    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.

      Like

      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.

        Like

      2. 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.

        Like

  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

    Like

    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

      Like

    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.

      Like

  3. 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

    Like

    1. Ich glaube ich sollte in der Uni noch ein entsprechendes Display haben. Eventuell finde ich in den nächsten Wochen mal ein wenig Zeit. Sollte nicht viel Arbeit sein.

      Grüße,
      Dominik

      Like

    1. Hallo,
      Wer ist “er” und was heißt “erkennt nicht”?
      getButton musst du selber schreiben und als Funktionspointer (einfach der Name der Funktion) dem Constructor mitgeben.
      Diese Funktion wird dann von der Library in einer Dauerschleife aufgerufen (mit 10ms Pause) bis etwas anderes als BUTTON_NONE zurück kommt.

      Grüße,
      Dominik

      PS: Diese Library stammt noch aus meiner Bachelorzeit und entspricht nicht mehr meinen aktuellen Qualitätsstandards. Habe aber keine Zeit den Code zu überarbeiten.

      Like

    1. Am wichtigsten dürfte “lcd->begin(16,2);” sein. Hier musst du dann vermutlich 20, 4 daraus machen.
      Die Anzeige nutzt dann vermutlich aber trotzdem nur einen kleinen Teil. Ich habe vor die Library noch mal komplett neu zu schreiben, sodass diese deutlich flexibler und einfacher für sowas ist (dann auch in sauberem C++). Leider weiß ich nicht wann/ob ich dazu Zeit finden werde.

      Grüße,
      Dominik

      Like

Comments are closed.