Portable devices often require the use of a linear, two-axis position sensor or joystick, and the demand for such sensing capability is increasing as portable devices proliferate. The task for designers is to meet key performance requirements such as sensitivity, accuracy, low power, and smoother operation, while also lowering cost, reducing size, and adding features such as haptic feedback.
This article will describe how joysticks function before introducing the parts and code necessary to design a low-cost, sensitive joystick for mobile devices.
How joysticks function
The common joystick used in video games is comprised of two orthogonal potentiometers for X and Y movement through a mechanism that rotates the shafts (Figure 1). These work well and are inexpensive, but are rather large and have noticeable lash around the center position. Further, potentiometer contacts are susceptible to environmental factors which can introduce noise and reduce reliability.
Figure 1: The 27800 from Parallax is a good example of a joystick that uses two rotational potentiometers mounted at right angles to each other. (Image source: Parallax)
The once ubiquitous “pointing sticks” embedded in PC laptop keyboards used force sensitive or strain gauge resistors as the sensing element (Figure 2). These resistors are placed on four sides of the stick. Moving the stick compresses one or more of the resistors changing their value. They are very small, reliable, and provide haptic force feedback that is proportional to displacement. Pressing down on the stick changes the value on all four resistors allowing for measurement of Z-axis displacement. The problem is that these pointing sticks are no longer manufactured in high volume. What is currently available is very expensive and can cost tens and even hundreds of dollars.
Figure 2: Typical “nub” pointing stick embedded in a PC laptop keyboard. This found popularity as a replacement for a mouse or touch pad. (Image source: Wikipedia)
Using magnets to detect movement
An alternative joystick solution is the AS5013 Hall effect IC from ams which uses a tiny moving magnet to determine X-Y position. The AS5013 is a complete solution that contains five sensors and a processing engine, making integration with a host processor quite easy. It has the advantages of being small (3.7 mm2), accurate, low power, reliable, and easy to implement. It requires a 2.7 volt to 3.6 volt supply and consumes less than 3 microamps in idle mode. It will detect motion of the magnet within a nominal ±1 mm range.
Figure 3: Typical arrangement of AS5013 and axial magnet (Image source: ams)
The movement of the magnet over the Hall elements causes a response that is geometrically distributed like a bell-shaped curve (Figure 4). The maximum magnet travel is a circle of 2 mm radius around the center of the AS5013. Hall elements C1 through C4 are placed on a circle centered on the middle of the package. Hall element C5, placed exactly in the middle, is used for better linearity response with magnet displacement larger than ±1.0 mm.
Figure 4: Hall element placement and magnetic field with the magnet centered over each Hall element. (Image source: ams)
Only four wires are needed for a simple application using a single power supply: two for power and two for the I2C communication. Additionally, a fifth connection can be added in order to send an interrupt to the host CPU, and a sixth connection can be added as a reset.
Figure 5: Block diagram and electrical connections of AS5013 with a host microcontroller. All six wires are shown connected, but only VDD, GND, and the two I2C signals are required (SDA and SCL). The ADDR pin selects between one of two I2C addresses. (Image source: ams)
To ease development with the AS5013, ams provides the AS5013-QF_EK_AB evaluation kit (Figure 6) that can be easily connected to an Arduino or NXP Freedom board.
Figure 6: The AS5013-QF_EK_AB evaluation kit simplifies development with the AMS5013 and contains the two major components: the AS5013 Hall sensor circuit board and the magnet assembly (bottom left). The magnet assembly mounts on the backside of the circuit board. (Image source: ams)
The IC is mounted on the front side of the pc board, while the magnet assembly is mounted on the backside directly underneath the center of the AMS5013 IC. The kit requires some careful soldering to complete the assembly. It is very important that the magnet assembly be positioned correctly or there will be an offset in the readings, which will be discussed later.
The mounting method used in the kit is only one suggestion. The magnet assembly module could also be mounted on top of the IC with suitable mounting hardware. This might be preferable for circuit boards with components that need to be mounted on only one side.
The magnetic assembly module also has an internal dome switch. Pressing down on the stick, a normally-open (N.O.) switch is activated, serving as a button click. The pads for the switch are located on the backside and do require soldering to the pc board.
On the schematic for the evaluation kit, note the button signal (labeled BUTn) for the internal dome switch (Figure 7). This will short to ground when the stick is depressed.
Figure 7: On the AS5013 evaluation board schematic, note that the button signal (BUTn) for the internal dome switch will short to ground when the stick is depressed. (Image source: ams)
Evaluation setup
In order to evaluate the ams joystick, it can be connected to the FRDM-KL05Z board from NXP which uses a very small and low cost 32-bit ARM® Cortex® M0+. Only 4 wires are needed: 3.3 volts, Ground, I2C SLK and I2C SDA.
Figure 8: The FRDM-KL05Z and AS5013 evaluation kit using only 4 wires for connection. (Image source: Digi-Key)
The embedded code was written using the mbed development system (mbed.org). It's a free web-based integrated development environment (IDE). The programming language is similar to an Arduino sketch but is actually C++ with library classes. The code is open source and the entire project can be obtained here.
The embedded code is rather simple, acting as a bridge between the kit and a host PC. Communication between the FRDM-KL05Z and the AS5013 is via 2-wire I2C. The main section of code runs in a continuous while-loop (Listing 1). Every 100 ms, the data from the AS5013 is read and is then printed over the virtual USB UART COM device at 115200 baud 8N1.
#include "mbed.h"
#if defined (TARGET_KL05Z)
#else
#error TARGET NOT DEFINED
#endif
PinName const SDA = PTB4;
PinName const SCL = PTB3;
I2C i2c(SDA, SCL); //construct I2c object
const int addr = 0x40<<1; //i2c address of AS5013
Serial pc(USBTX, USBRX); //optional, but needed to set faster baud
char data[7];
int main() {
int8_t x,y; //x y values to be printed to terminal
uint8_t statusF; //status flag
pc.baud (115200);
init_AS5013(); //reset and initialize the AS5013
while (1) { //endless loop
wait(0.1); //wait 100 ms
statusF =0;
data[0] = 0x0f;
i2c.write(addr, data, 1); //set to read address 0x0f
i2c.read(addr, data, 3); //read data at register 0x0f,0x10,0x11
statusF = data[0]; //get status byte
if(statusF & 0x01){
x=data[1]; //get x
y=data[2]; //get y
printf(" %d %d", x,y); //output result
printf("\n");
}
else{
pc.printf("error 0x%x\n",statusF); //should not get here
}
}
} //end of main
Listing 1: Source code of main() using the “mbed” IDE. This is the code that runs on the FRDM-KL05Z board. It consists of an endless loop that reads the X and Y values from the I2C interface. (Code source: mbed)
On the host PC side, you have a number of options. The simplest is to use a terminal program such as Tera Term for Windows or MiniCom for Linux. The terminal output lists the values for both X and Y (Figure 9). The AS5013 provides 8-bit signed values for X and Y from +128 to -127 relative to the center position at Y=X=0 (after calibration).
Figure 9: Tera Term output that continuously displays AS5013 X and Y 8-bit values. (Image source: Digi-Key)
PC graphic display
A program written in Python 3.6 provides a nice visualization of the data. The code can be obtained here on GitHub.
This program was written and tested with Windows 7, but the same code will run on Linux or a Mac. Python can be downloaded from python.org.
Figure 10 shows the output of the X and Y data in an “oscilloscope” display. X is shown in the blue trace, and Y is in red.
Figure 10: Display for X (blue) and Y (red) joystick movement. The joystick is moved left-right, up-down. (Image source: Digi-Key)
The second option moves a small circle around the screen in synchronization with movement of the stick (Figure 11). The red circle at the center of the screen corresponds to the default stick position where both X and Y are zero. When not touched, the joystick returns to this position.
Figure 11: Position of red circle (representing the joystick) in neutral or center position. (Image source: Digi-Key)
Figure 12: Position of the red circle in the upper-left quadrant when the stick is pushed to the upper left. (Image source: Digi-Key)
Offset effects and calibration
As mentioned earlier, it is important that the magnetic assembly module be correctly positioned so it is directly centered above (or below) the AS5013. Failure to do so will create an offset. In this case, the center position X and Y values will be non-zero. To overcome this problem, an offset is calculated for each axis and added to the final result. Figures 13 and 14 show the effects of offset before calibration.
Figure 13: X-Y values with offset. Note that the zero position is below the centerline. (Image source: Digi-Key)
Figure 14: Joystick position off-center due to offset. (Image Source: Digi-Key)
Calibration is straightforward. When the program first starts, take several readings of the X and Y values with the stick in the center position, average and add or subtract an offset so the result is zero.
Scaling
The distance between the magnet and the AS5013 can vary due to design, affecting the ability to obtain full scale readings of +/- 127. For example, the board thickness will have an effect on the sensitivity. Fortunately, this can be controlled by a “scaling factor” set in register 0x2D of the AS5013. If the magnet is too close in proximity, it should be lowered from the default value of 100%. Conversely, if the magnet is too far away, it should be increased. The movement sensitivity can also be adjusted by changing the scaling factor.
Low-power mode
The AS5013 can be placed into an ultra-low-power mode, and can be woken up by movement of the stick at a user-configurable threshold. Upon awakening, it can generate an interrupt to the host MCU and then proceed with normal operation.
Advanced sensor data
There are a total of five Hall sensors. The raw data can be read from each sensor and used for custom configurations. One interesting application is to sense when the magnet moves in the Z direction, emulating a pushbutton. The center Hall element value increases as the magnet gets closer to the AS5013. This can be compared to a fixed threshold value to determine a push state. The remaining four Hall sensors will also be affected by a smaller amount. However, in the case of external parasitic magnetic fields, these four sensors can be used to improve detection. There is a good example of this in ams’ Application Note AN5013-20.
However, when using the magnetic assembly module, the dome switch is a simpler and more robust solution for a button press.
Conclusion
The AS5013 and magnetic assembly module make for a good choice for a small and accurate joystick interface. It is very sensitive and can respond to very small movements. In many cases, it's an ideal replacement for bulky potentiometer or expensive strain gauge joysticks. The evaluation kit provides an easy development platform.