Use a Joystick on the Raspberry Pi (with MCP3008)

For some applications, such as games, a joystick can be useful or be even necessary. Since these usually work purely analogously, the signal has to be converted, which we do with the MCP3008 chip. Connecting and reading a joystick is shown in this tutorial.


These analogue joysticks have two axes, which allow a certain voltage to pass through two potentiometers (adjustable resistance). So that the position can also be read out digitally on the Raspberry, the MCP3008 is needed. The scheme of this module is as follows:


On the left side are 8 analogue inputs, of which we only need 3.

On the right side are the digital outputs, where the transmission takes place via DIN and DOUT.

The MCP3008 device is a 10-bit analogue-to-digital converter. This means that it can reach a maximum of 2 ^ 10, i.e. 1024 bit combinations (the values from 0 to 1023). With an input voltage of 3.3V, the approx. 3.2mV are steps that can be mapped (3.3V).




Although the joystick has a 5V input voltage, it works without problems using 3.3V, which is even more important when using the MCP3008. The term SW is for the button that is activated when you press the joystick. For this to be either 0 or 1023 (pressed or not pressed) a 10kΩ resistor is attached to VCC. Without this resistance, invalid numbers are output that can not be clearly assigned.



The pin assignment of the Raspberry looks like this:

Raspberry Pi MCP3008
Pin 1 (3.3V) Pin 16 (VDD)
Pin 1 (3.3V) Pin 15 (VREF)
Pin 6 (GND) Pin 14 (AGND)
Pin 23 (SCLK) Pin 13 (CLK)
Pin 21 (MISO) Pin 12 (DOUT)
Pin 19 (MOSI) Pin 11 (DIN)
Pin 24 (CE0) Pin 10 (CS/SHDN)
Pin 6 (GND) Pin 9 (DGND)

Following the connection to the joystick:

RPi / MCP3008 Joystick
 Raspberry Pin 6 (GND)  GND
 Raspberry Pin 1 (3.3V)  +5V
 Pin 1 (CH0)  SW
 Pin 2 (CH1)  VRx
 Pin 3 (CH2)  VRy



In my script, I use the SpiDev library. If you have not already installed it, you should do that before testing the joystick.

As mentioned earlier, the MCP3008 returns a value between 0 and 1023. If the joystick is in the “idle state”, ie in the middle, around 512 will be returned. 0 is returned at one end of one axis and 1023 at the other end (at which end it depends how you look at the joystick).

You can download the test file


or create it yourself:

Then you can start the script  by

sudo python

and move the joystick. You’ll find that 1024 steps are most likely too much, as finger accuracy on a small joystick can hardly be achieved. Therefore, I would recommend setting areas in an application rather than testing for individual values (apart from 0/1023).

5 Responses

  1. Doesn’t work for me. Values are not what I expect. F.i. Switch value is 0 and 254 when pushed.

  2. when I followed these instructions and run the python code it prints out 0 for all the values(x,y,button). I don tknow if that means its a problem with the code or the hardwire. If it is a problem with the hard wire then how do I check if a connection has been made from the joystick to the rasberrypi because when i run ls /dev/spidev it gave me /dev/spidev0.0 /dev/spidev0.1, so I assumed a connection was made.

    • Hello, I am running into the same problem and I was wondering if you ever figured out what the problem was?


Leave a Comment

Your email address will not be published.

Subscribe to Raspberry Pi Tutorials and don't miss any new Tutorial!