Einfaches Arduino-UserInterface mit 16×2-Display

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

Examples of user

Menu:

display16x2-menu

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.

 

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

Percent:

display16x2-procent

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

 

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

 

Configuration

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.
LiquidCrystal lcd(8,9,4,5,6,7);
In the next step you create the SimpleUI16x2-object which you give the LiquidCrystal-object and a function to query the buttons.
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;
}
Now you should be able to use the UserInterface. You should take a look at the example in the library.

 

Download

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.

./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 Gedanken zu „Einfaches Arduino-UserInterface mit 16×2-Display“

    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

    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.

  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.

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.