How to use an analog joystick (KY-023) with an Arduino Uno

KY-023 Analog Joystick.

The KY-023 (or KY-23) is an easy-to-use analog joysticks for the Arduino microcontroller. The joysticks features two dimensions (x and y axis) as well as a state that is set when the joystick is pressed. In this tutorial, it is shown how to connect the KY-023 joystick with the Arduino and how to use it.

List of materials:
– Arduino Uno [buy at AliExpress]
– Jumper wires (female/male) [buy at AliExpress]
– KY-023 analog joystick [buy at AliExpress]

Typically, the KY-023 comes as a module with 5 male pins:

  • GND (Ground Pin)
  • +5V (5V Pin)
  • VRX (voltage proportional to x-axis)
  • VRY (voltage proportional to y-axis)
  • SW (joystick pressed PIN)

How to connect the KY-023 to the Arduino?
Connecting the KY-023 to the Arduino is very straight forward. The module’s “GND” has to be connected to the Arduino’s “GND”. As the KY-023 work also 5 Volt, the module’s “+5V” has to be connected to one of the Arduino’s “5V” pins.
The joystick is basically a combination of two potentiometers. This means, when the joystick is moved along the x-axis the resistance changes resulting also in a change of voltage. The voltage can be used to detect the x-position of the joystick by connecting the VRX Pin to an analog input of the Arduino. The same applies for the y-axis. The y-axis’ position can be read by connecting VRY to an analog input. In this tutorial, VRX is connected to “A0” and VRY is connected to “A1”. Lastly, SW is connected to the Arduino’s digital pin “2”.

Picture of how to connect KY-023 to Arduino Uno.

Scheme of how to connect KY-023 to Arduino Uno.

How to program the KY-023 with the Arduino IDE?
The source code is fairly simple. First, we will setup the two analog pins A0 and A1 and the digital pin “2” to detect whether the joystick is pressed. Next, we setup the serial connection which is utilize to print out the current state of the analog joystick on the console.

Then, we read the analog data of the x- and y-axis. Thereby, the analog voltage of the potentiometers is mapped to a digital value between 0 and 1023. If the button is set up as shown in the upper picture/scheme, then moving the joystick to the left will result in an x value of 0. If the button is moved to the right, the x value will be 1023. If the joystick is moved to the top/north, then the y value will be 0. If the joystick is moved down, the y value will be 1023.

The pin mode of the button (for detecting whether the joystick is pressed) uses a pull-up resistor. The result is that the value of the pin will be 0 if the button is pressed. Therefore, the variable name “notPressed” is used in the source code.

// (c) Michael Schoeffler 2017,

const int inX = A0; // analog input for x-axis
const int inY = A1; // analog input for y-axis
const int inPressed = 2; // input for detecting whether the joystick/button is pressed

int xValue = 0; // variable to store x value
int yValue = 0; // variable to store y value
int notPressed = 0; // variable to store the button's state => 1 if not pressed

void setup() {

  pinMode(inX, INPUT); // setup x input
  pinMode(inY, INPUT); // setup y input
  pinMode(inPressed, INPUT_PULLUP); // we use a pullup-resistor for the button functionality
  Serial.begin(9600); // Setup serial connection for print out to console

void loop() {
  xValue = analogRead(inX); // reading x value [range 0 -> 1023]
  yValue = analogRead(inY); // reading y value [range 0 -> 1023]
  notPressed = digitalRead(inPressed); // reading button state: 1 = not pressed, 0 = pressed

  // print out values
  Serial.print("X: ");
  Serial.print("Y: ");
  Serial.print("Not pressed: ");

  // The following delay of 1000ms is only for debugging reasons (it's easier to follow the values on the console)
  delay(1000); // Probably not needed for most applications

If the code has been successfully uploaded to the Arduino, the output on the Serial Monitor (Tools->Serial Monitor, Ctrl+Shift+M) should look like this:

Serial monitor output of the Arduino IDE when uploading the example (button not pressed, joystick at the center).

On the validity of virtual reality-based auditory experiments: a case study about ratings of the overall listening experience

It has been a little more than a year that my former colleagues and I published a paper in Springer’s Virtual Reality journal. Unfortunately, the paper is not accessible for free. Fortunately,  Springer allows to publish the submitted manuscript after a 12-month embargo (“self-archiving policy”). Therefore, I decided to publish the paper also on my private website.

The paper is about an experiment in which virtual reality environments are compared to “real-world” environments. For the graphics in the VR environment, we used OGRE as graphics engine and the Oculus Rift (Development Kit – second revision) as output device. A lot of effort was put in the auditory part of the virtual reality environments.

Title: On the validity of virtual reality-based auditory experiments: a case study about ratings of the overall listening experience
Authors: Michael Schoeffler, Jan Lukas Gernert, Maximilian Neumayer, Susanne Westphal and Jürgen Herre
Abstract: In recent years, new developments have led to an increasing number of virtual reality (VR)-based experiments, but little is known about their validity compared to real-world experiments. To this end, an experiment was carried out which compares responses given in a real-world environment to responses given in a VR environment. In the experiment, thirty participants rated the overall listening experience of music excerpts while sitting in a cinema and a listening booth being in a real-world environment and in a VR environment. In addition, the VR system that was used to carry out the sessions in the VR environment is presented in detail. Results indicate that there are only minor statistically significant differences between the two environments when the overall listening experience is rated. Furthermore, in the real-world environment, the ratings given in the listening booth were slightly higher than in the cinema.
PDF Download Link

Slides: “On the validity of virtual reality-based auditory experiments: a case study about ratings of the overall listening experience”, LRZ Munich

A few months ago, I gave a general talk about creating Virtual Reality (VR) environments at the Leibniz-Rechenzentrum in Munich. I just uploaded the slides in case someone else is interested in this topic. A lot of slides focus on how to create auditory stimuli for VR environments. Furthermore, I presented also some results about a study which has been carried out to investigate the differences between “real world” experiments and VR experiments in the context of auditory experiments.
Link to slides: schoeffler_lrz_munich_2015 (AudioLabs Mirror)

In addition to the slides, my students, my supervisor, and I published a Journal Paper that describes the study in more detail (Link to Springer VR).

Web Development with Java in 2015 – A Review

Some months ago, I started to completely redesign one of my web applications. My personal goal was to refresh my knowledge of designing and programming web applications with Java. The web application I started to redesign is (German version: which is a search engine for books. To put it simple: visitors can lookup information about a book by entering an ISBN (International Standard Book Number).

I finished the first major release version more than seven years ago. It was written in PHP and used a MySQL database which contained all the book data.
About two years ago, I finished the second major release version which was written in Java. The design and user interface stayed more or less the same. The purpose of the second version was to heavily simplify the architecture and source code as I wrote the first release version when I just started my studies in Computer Science and had not that much experience in designing perfect software architectures (In my defense, the first revision needed almost no maintenance and produced a very nice monthly income). 😉

Therefore, it was time for a third major revision as the majority of the visitors has started to use mobile devices to access the web application. So I started to improve the second revision of the web application. I had two (non-personal) goals: First, to further improve the architecture of the web application in order to add new features in almost no time. Second, to have a web application that looks always good even if accessed by smartphones with small displays. Furthermore, I wanted only one version of the website that supports both, mobile and desktop devices.

Based on my requirement analysis, I came up with these technologies:

The Eclipse Modeling Framework comes with a nice editor allowing to graphically design meta models. EMF uses Ecore as standard format for the meta models. Ecore is very similar to OMG’s MOF (sometimes one reads that Ecore is a subset of MOF, and sometimes one read Ecore is a de-facto reference implementation of MOF etc.).

EMF Editor

Meta-model editor of Eclipse Modeling Framework.

Designing meta-models with EMF is very easy when you have learned the ropes. The first hours with EMF might be a bit frustrating as EMF is a very comprehensive framework and one might not know where to start. However, in my opinion, the frustration is worth the gain in productivity.

Once you have the graphic representation of your meta-model, the next step is to us them to generate some source code. In EMF the source code generation is more or less just pressing a button. There are tons of options, e. g. you can choose whether you want adapter classes, interface classes etc.

For persisting the model data, I used Hibernate. Hibernate is a well known and widely used object-relational mapping framework that maps an object-oriented domain model (like Ecore models) to a traditional relational database. If you are familiar with Hibernate, you know that you have to write annotations or mapping files in order to map your classes to tables etc. Luckily, there exists already a solution that does all the work for you: Teneo. Teneo is a so-called model-relational mapping and runtime database persistence solution that integrates EMF with Hibernate. Once Teneo is configured, it stores all your model data into a database. A big advantage of Teneo is that it is highly configurable. For example, you can decide how to solve the inheritance mapping problem.

Database Connection Handling
The more visitors a website has, the more queries are sent to its database (if it has one). If in addition some computationally intensive queries are sent, the database might be overloaded. Especially in such a scenario, a more advanced handling of the database connections is very helpful. I chose c3p0 as it allows me to perfectly configure the connection handling. For example, you can select the minimum and maximum number of connections, the maximum idle time of connections, the maximum number of statements per connection and so on. Once you are done with the configuration, you need not to care about idling database connections etc. anymore.

Java Servlets and JSF
My code contains some business logic which is implemented as Java servlets. There is nothing special to tell, the servlets get requests and send responses.
The User Interface was implemented with Java Server Faces (JSF). I did not write all the code in plain JSF, I made as much use as possible of PrimeFaces framework.

Screenshot of the website

A screenshot showing the responsive design of the website

PrimeFaces is a component library for JSF-based web-applications. PrimeFaces features more than hundred components ranging from simple buttons to very powerful data tables. All components are mobile-friendly, which made PrimeFaces the perfect choice for my ISBN search application. The framework does not only feature components, it comes with a nice theme-roller and ajax functionality to let the user interface smoothly interact with all the objects that live in the backend (servlets, JAVA beans etc.).
Although PrimeFaces is a very comprehensive and powerful framework, getting started is not that hard. Once you know the ropes, you can easily design and implement your website.
The major disadvantage of PrimeFaces is that it is not “100% open source”. Major versions are released as “Community Downloads” free for everyone. If you rely on bugfixes or features of minor versions, you must subscribe to the so-called ELITE or PRO support options. In my case, the latest community version had all the features I needed to implement my website.

Last but not least, my project needed some SEO-friendly URLs. I chose PrettyFaces as it worked well with the other technologies I used. Using PrettyFaces is rather simple, you configure URLs by mapping files. External (SEO-friendly) URLs are mapped to the project’s internal URLs. Since I have only eight or nine different “types” of URLs, my config file has only a few lines.

In summary, it was a lot of fun the implement the website by using many “state of the art” frameworks. It is good to know that the Java ecosystem offers many options to architect, develop and deploy a website for mobile and desktop devices. Certainly, I have to admit, that not everything worked directly out of the box. Most effort went into setting up and configuring all the different libraries and integrate them into the web application. However, once this is done, the development is rather fast.

Next, I want to start a new web project using a completely different ecosystem. I’m thinking of using Python+Django since it got a lot of attention lately and becomes more and more popular among web developers.

Retrieving the previous and the next record of a selected record (SQL)

Let’s assume we have selected a record (record_id = 7) and we want to select its previous and next record.

A very naive approach would be to add “1” (and to subtract “1”) to the record_id:
SELECT * FROM table WHERE record_id = (7-1) # selects previous record
SELECT * FROM table WHERE record_id = (7+1) # selects next record

However, this does not work in many scenarios, e.g., if record_id is not a number or if numbers are “missing” (…,4,5,7,8,…). Therefore, a more sophisticated query is needed.

One possibility is to explicitly sort the records according to the record_id, add a condition which selects only records that have a record_id that is greater (or less) than the record_id of the selected record, and finally select only one record:
SELECT * FROM table WHERE record_id < 7 ORDER BY record_id DESC LIMIT 1 # selects previous record
SELECT * FROM table WHERE record_id > 7 ORDER BY record_id ASC LIMIT 1 # selects next record

Fixing the NULL Pointer of the OculusWorldDemo [Oculus Rift SDK 0.4.3, Windows] when running in OpenGL mode

The OculusWorldDemo is little demo application which is shipped with the Oculus Rift SDK and demonstrates some features of the Rift. Recently, I (and some more people) came across a nasty exception while trying out the OculusWorldDemo in OpenGL mode.

When starting the demo, the demo breaks when trying to retrieve the OpenGL version of my system (Line 1901 in Render_GL_Device.cpp):
const char* version = (const char*)glGetString(GL_VERSION);

The function returns NULL and a few lines later an assert checks for the version and throws an exception. For retrieving a valid OpenGL version, one must create a valid OpenGL context before calling the glGetString function. In OculusWorldDemo this happens in Render_GL_Win32_Device.cpp at line 145 (HGLRC context = wglCreateContextAttribsARB(dc, 0, attribs);).
On my system (Windows 7, GeForce GTX 560 Ti), wglCreateContextAttribsARB fails to create a context and returns a NULL pointer. There are more than one reason for getting a NULL pointer here. Long story short, you can replace the function call by calling wglCreateContext instead. The function has only one argument (the handle to the device context) which is why we do not have to add some additional code.
Changing line 145 to HGLRC context = wglCreateContext(dc); does the trick. However, a proper solution would be to call wglCreateContext only if wglCreateContextAttribsARB fails to create a context. 😉

How to map String to TEXT instead of String to VARCHAR(255) (Teneo/Hibernate)

Teneo/Hibernate maps String to VARCHAR(255) per default. If values with sizes of more than 255 characters are expected, this mapping strategy might result in a lot of exceptions. A simple solution  for this is to change the mapping from VARCHAR to TEXT of the EAttribute. Teneo supports such a mapping by looking for a specific annotation value (“@Lob” in “teneo.jpa” annotation).

1. Add an EAnnotation to the EAttribute
2. Set source of the EAnnotation to “teneo.jpa”
3. Add a Details Entry to the EAnnotation
4. Set the key of the Details Entry to “value”
5. Set the value of the Details Entry to “@Lob”
6. Regenerate your model
7. Recreate the database (Teneo will not update the table per default)