Adafruit: 2-Axis Thumb Joystick

Revision as of 01:57, 16 October 2012 by Astroricks (Talk | contribs)

Jump to: navigation, search

Overview: 2
Wiring:   2
Code:     2
git/Compiles with make: 2  gcc works
Demo:     2
Total:    10
Comments: Looks good.

2axisthumbstick MED.jpg


The Adafruit: 2-Axis Thumb Joystick uses 2 10 kΩ pots which are adjusted by moving the joystick. The joystick and development board can be purchased from the Adafruit Website. The joystick is simplistic enough that Adafruit does not provide a datasheet.

From the Manufactorer: This mini-kit makes it easy to mount a PSP/Xbox-like thumb joystick to your project. The thumbstick is an analog joystick - more accurate and sensitive than just 'directional' joysticks - with a 'press in to select' button. Since it's analog, you'll need to analog reading pins on your microcontroller to determine X and Y. Having an extra digital input will let you read the switch.

Inputs and Outputs

The Adafruit joystick takes a supply voltage (Vs) of up to 5V. The analog outputs have a direct correlation to the resistance observed by the analog joystick. At the resting position, the resistance in both axis is at its middle resistance or 5k. At either extreme of the range of motion, there is either enough resistance for the analog inputs to register a 0 or so little resistance that the supply line to the analog input looks open.

BeagleBone Usage

The BeagleBone can support up to 8 analog inputs and has the ability to supply an analog 1.8 V voltage and an analog ground. I have connected my beagle as shown after soldering the joystick and some wires to the dev board:

BeagleBone Adafruit 2axis Joystick mmoravec.jpg

The pinout is as shown:

Bone P9 pinout.jpg

Pins 36 and 38 I have wired to the 0-1.8V analog inputs. I have wired VCC to the Beagle's 1.8V analog VCC output(pin 32). The ground wire from the joystick is wired to the analog ground on the beagle(pin 34). The select GPIO signal I have routed to the GPIO_7 pin(pin 42).

I have written a small program which displays the x-Axis and y-Axis positions in the terminal. It can be found in a git repository here.

Using this configuration one can take the analog inputs with the GPIO selector and do about anything that requires two axises of movement and a selection knob. If you need some help interfacing with the analog ports or the GPIO ports, check out Dr. Yoder's succinct exercise at Analog and GPIO Info


Control a 8x8 LED Matrix With The Joystick

Now we have the joystick as an input, and we can do something interesting if there's an output part. This is a mini project about using the joysick to control a 8x8 LED matrix.

The details about the LED matrix can be found here: Mini 8x8 LED Matrix w/I2C - Yellow The LED matrix has an i2c port. Wire up the LED matrix to the Beagle Bone by attaching the Vdd to the 3.3V + bus, the GND to the - bus, SDA to SDA (pin 20), and SCLK to SCLK (pin 19). The joystick can be wired up as described above. Here is a picture of the hardware configuration.

Our main goal is to create a bright dot on the LED matrix and use the joystick to move it.

static __u16 dot_bmp[] = {0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
pos = 0x80;

if(analog_value_x >= 4000 && row < 7) {
	row ++;
	dot_bmp[row] = pos;
	dot_bmp[row - 1] = 0x00;
if(analog_value_x <= 1000 && row > 0) {
	row --;
	dot_bmp[row] = pos;
	dot_bmp[row + 1] = 0x00;
if(analog_value_y >= 4000 && pos < 0x80) {
	pos = pos << 1;			
	dot_bmp[row] = pos;
if(analog_value_y <= 1000 && pos > 0x01) {
	pos = pos >> 1;			
	dot_bmp[row] = pos;

This is how we move the dot around: First, we create a bmp array whose first element is 0x80, which means only the dot on the right-down corner should be bright. 'analog_value_x' and 'analogy_value_y' are the two variables we set up to represent the voltage of x-axis and y-axis analog-in. 'pos' represents the position of the bright dot in the row. If 'analog_value_x' changes significantly and the bright dot does not reach the boundary of the 8x8 matrix, we should light up the dot next to it and turn off the dot itself.

for(i = 0; i < 8; i ++)
	block[i] = (bright_bmp[i] & 0xfe) >>1 | (bright_bmp[i] & 0x01) << 7;

res = i2c_smbus_write_i2c_block_data(file, daddress, 16, (__u8 *)block);

For some reason the display is rotated one column, so after pre-unrotating the data, we can write the block data through the i2c bus. Thus, a dot can be lighten up on the matrix and can be moved as the way we want.

Next, we would like to make use of the button on the joystick. This is our objective: when pushing the button down, an interrupt is triggered and a frown face is presented on the LED matrix. Then if we move the dot across the face, it can be changed to a smile face.

According to the instructions on the joystick, the SEL shorts to ground when pressed. So the first important thing to do is to change gpio0_7 to pull-up mode. So that the interrupt can work correctly.

int gpio_pullup(void)
	FILE *fp;
	char pullup[] = "0x37";
	fp = fopen("/sys/kernel/debug/omap_mux/ecap0_in_pwm0_out", "w+");
	fprintf(fp, "%s", pullup);

Instructions about setting the interrupt can be found here: [1]