The Raspberry Pi Pico is a cost effective component to play and tinker with if you intend to dive into the world of IoT and electronics. It is also a great device and often considered the heart of robotics as it is reliable and easy to program. Further, this dual core arm cortex m0+ processor is quite compact in size, around 21x51mm. One can directly solder to carrier board as it is a castellated module. However, we would advise you to use jumper wires to connect your sensors and device to Raspberry Pi Pico instead of directly soldering them to the board. Using Raspberry Pi Pico, one can develop several projects like controlling a robot, building a stop motion camera, retro gaming machine, etc. In this blog we will discuss another fun project- How to interface an analog joystick with Raspberry pi Pico.
The Pico board has 26 GPIO pins which include 3 Analog pins. Regular RPI boards do not possess analog inputs, therefore Pico is different and a better choice for this particular project. Hence, this can be an individual project in itself or can be a part of a larger project. The modules are quite similar to the thumb sticks found on video game consoles and are inexpensive and easy to set-up.
The following given below is a comprehensive list of hardware you would require to complete this project ‘How to interface an analog JoyStick with Raspberry Pi Pico’. Further, their amazon links given enable a quick purchase.
- 5 pin analog joystick
- Raspberry Pi Pico
- Jumper wires: female to female and female to male
The use of breadboard in this project is optional. If you wish to connect the joystick directly to Raspberry Pi Pico, you can do so too. We have provided you with a circuit diagram.
PIN DIAGRAM OF RPI PICO
Pico can be programmed with C/C++ SDK or MicroPython. We will work on your project using MicroPython.
Pico board specifications
- Dual core ARM Cortex M0+ processor, flexible clock running up to 133 MHz.
- Pico has the RP2040 chip
- 2 Mb of flash memory
- Temperature sensor
- Fast software floating point libraries
- Castellated module that allows one to solder directly onto the carrier boards.
- USB 1.1 Host and Device support.
- 26 functional GPIO pins (It does not have any analog input)
- Mass storage over USB through drag and drop programming.
- Low power sleep
- Dormant modes
- 2 x SPI, 2 x I2C, 2 x UART, 3 x 12 bit ADC, 16 x controllable PWM channels
- 8 x Programmable IO (PIO) state machines for custom peripheral support
- Accurate clock
- Operates at 3.3 volts.
- 12 bit ADC
Raspberry Pi Pico has input pins that can work with analog signals. Therefore, it can read values besides 0 and 1. But the RPI Single Board Computers does not contain pins to take readings from an analog device (very often an ADC device is required). This complicates the project. In sleep mode, the Pico consumes approximately 6 milliwatts which is lesser than even Pi Zero that consumes around 100 milliwatts in its low power mode.
Recommended operating conditions
- The maximum operating temperature is 85C, this includes self heating too.
- The minimum operating temperature is -20C.
- VBUS- 5V +/1 10%
- VSYS Min- 1.8V
- VSYS Max- 5.5V
It is important to note that the VBUS and VSYS current depends on the situation. The maximum recommended ambient temperature of operation is 70C. But if you would like to learn more about Raspberry Pi Pico, please refer to its datasheet
In order to power your raspberry pi pico without attaching it to a computer, we can use a USB power supply.
MicroPython vs C: Which Programming Language to use?
You can program Raspberry Pi Pico in both C and MicroPython. C is a low to middle level Programming language while Python Provides Higher level of abstraction.
|It has complex data structures(Lists, Dictionary)||Complex data structures can be supported but it leans more towards pointers.|
|Doesn’t need to be compiled||Needs to be compiled|
|Easy to code and understand||Coding can be a little complicated|
|Memory leak can be avoided( due to absence of memory management – malloc)||Prone to memory leak. If you are not good with user-defined memory management.|
|In contrast to C language, Python uses more ROM.||C Programs are complied, Program it is highly optimized in Size, Hence Program Size is small & utilizes less ROM as compared to Python.|
|More portable (can be used on different |
OS/HW Platforms) with less to none changes in the code. Hence it is preferred by developers.
|Less portable especially on embedded platforms.|
We advise you to not rely too heavily on C, when you work on something as heavy or complicated. In contrast, Python is a simple language and a better choice. It adds functionality and has a complete inline assembler.
What is MicroPython?
Python 3 programming language has a lean version called MicroPython. This was developed to run efficiently on microcontrollers. It is a simple, yet extremely powerful language that has gained massive popularity over the last few years. MicroPython is not very different from the traditional Python. It has almost all the features as Python 3 and interacts with the hardware in a smooth and efficient manner. Further, if you want to learn more about MicroPython, we suggest you to refer the official guide book – “Get started with MicroPython on Raspberry Pi Pico”. This will assist you to understand the basics of MicroPython and also strengthen your foundation. Hence, it allows you to tinker with more projects like connecting the Pico to displays, sensors, building alarms, reaction games, etc. (Refer to this article “Easy Setup and Program Raspberry Pi Pico”
Working of the joystick:
The Emerging Techs joystick is equipped with two potentiometers, for each axis. You can measure the movement of stick in 2D using potentiometers. This variable resistor is used to tinker with the values of the resistance that will in turn give us the values along X and Y axis. Its voltage varies from 0 to 5volts. So the values sent by the joystick helps determine its position. When untouched, in the middle, the values are 511, 511. When we move it in the left or right direction, the values change accordingly. We are using ADC pins to read the values of x and y axis. Pin 16 will be used to create a button variable.
- It is compatible with Pico and Arduino interface.
- It has five pins.
- Its dimensions are: 1.57 inches x 1.02 inches x 1.26 inches (4.0 cm x 2.6 cm x 3.2 cm)
- Two potentiometers present in it are each responsible for an axis.
JoyStick Schematic Diagram:
The 5 pin analog joystick is quite similar in design to the joysticks on PS2 (PlayStation 2). The self-centering spring present in it brings the joystick back to the center position when released. Then on the sides of the joystick, you will notice blue boxes which are the potentiometers. Observe the center shaft of the potentiometer while moving the joystick to understand its movement. Another important component of the joystick is the switch present in the tiny box at the back of the thumbstick. The switch activates through the action of a lever, when you push the joystick down. The potentiometers are connected between +VCC and ground. It acts like a Voltage Divider Network.
The joystick module has 5 pins
|Power supply||Signal pins|
|VRX – Signal pin for X direction|
VRY – Signal pin for Y -direction
SW – Signal pin for switch button
Note: a 5V joystick will work with 3V3 Out.
Learn to code the joystick using MicroPython
The analog stick constitutes of three devices:
- Potentiometer for the X axis
- Potentiometer for the Y axis
- Digital momentary button
To learn the direction at which the joystick points, we will enter a few lines of code. Then to learn how to install the IDE on host laptop/ desktop please refer to the article: “Easy setup and program raspberry pi.”
Step 1: Once you log into the Pico, select your MicroPython IDE (for example Thonny) and create a blank program.
Step 2: Import the important modules – Pin, ADC and Utime
from machine import Pin, ADC import utime
- In Pico, the ADC pins work with 12 bits. Therefore, their values can range from 0 to 4095. However, when you use MicroPython, the ADC values gets scaled to a 16 bit range thereby changing the range – 0 to 65535.
- The machine module provides the ADC ()
- The utime.sleep function is used later on in the code to instill a delay into a loop. This is necessary as we need to read the button state.
Step 3: Create x and yAxis variables. Then, assign them to the GPIO pins. xAxis will be assigned to pin 27 and yAxis will be assigned to pin 26.
Pico has 12 bit ADC (analog to digital sensor) which generally means that it returns that many bits. Its discreet level is 4096( 2^12).
xAxis = ADC(Pin(27)) yAxis = ADC(Pin(26))
Step 4: Create a button variable. This helps in toggling the joystick and sending signals.
button = Pin (16, Pin.IN, Pin.PULL_UP)
- The button variable created is then assigned to a Pin object. So this Pin object has three arguments.
- The format is: pin = machine.Pin(0, machine.Pin.IN, machine.Pin.PULL_UP). Here, 0 indicated the pin that will be accessed.
- Therefore, in our code, pin 16 will be configured. The second argument specifies whether we need a pull up or pull down resistor.
- You use PULL_UP to pull the pin to the high logic level with an internal resistor
- You use PULL_DOWN to pull the pin towards the low logic level with an internal resistor.
- So for our project, we will be using input mode and pull up. When you use pull up, it means that they are high. This happens when the button is not pushed down.
Step 5: Check and print the value of x, y and button through a continuous loop.
while True: xValue = xAxis.read_u16() yValue = yAxis.read_u16() buttonValue= button.value() print(str(xValue) +", " + str(yValue) + " -- " + str(buttonValue)) utime.sleep(0.1) //validate the values of the joystick after every 100ms.
Step 6: Then observe the results by running the code in the MicroPython shell. Since no external screen is attached to the Pico, we can validate and check the operation using a Python IDE on a laptop or desktop
- When the joystick is in a stationary position, no movement at all, you will observe that the value of X and Y will be around 32,000 to 33,000. The button value will be 1.
- When you move the joystick in the upward direction, you will observe that the values are between 300 to 500.
- When you move the joystick in the downward direction, you will observe the value to be approximately 65,000.
- Moving the joystick to the left will give us a value of X between 300 to 500.
- But if you move the joystick to the right, it will display a value of approximately 65,000.
- When you press the button down, you will get a value of 0.
Step 7: Stop the execution of the program
Step 8: Then, create variable for the status of X, Y and button. But make sure you place them within the loop and provide them with default values.
xStatus = "middle" yStatus = "middle" buttonStatus = "not pressed"
Step 9: label the joystick and button status within the loop using if/then statements.
if xValue <= 600: xStatus = "left" elif xValue >= 60000: xStatus = "right" if yValue <= 600: yStatus = "up" elif yValue >= 60000: yStatus = "down" if buttonValue == 0: buttonStatus = "pressed"
Step 10: above the sleep command, write a print statement to display the variables.
print ("X: " + xStatus + ", Y: " + yStatus + " -- button " + buttonStatus)
Your final code
from machine import Pin, ADC import utime xAxis = ADC (Pin (27)) yAxis = ADC (Pin (26)) button = Pin (16,Pin.IN, Pin.PULL_UP) while True: xValue = xAxis.read_u16() yValue = yAxis.read_u16() buttonValue = button.value () xStatus = "middle" yStatus = "middle" buttonStatus = "not pressed" if xValue <= 600: xStatus = "left" elif xValue >= 60000: xStatus = "right" if yValue <= 600: yStatus = "up" elif yValue >= 60000: yStatus = "down" if buttonValue == 0: buttonStatus = "pressed" print ("X: " + xStatus + ", Y: " + yStatus + " -- button " + buttonStatus) utime.sleep(0.1)
Drawbacks of analog joysticks
While the joysticks are not inherently a bad choice for the project, they do have a few disadvantages that are important to acknowledge.
- Due to the manufacturing tolerances of the resistor, the joystick might make a mistake and not read exactly half the value of VCC while at rest. Hence we advise you to note down the zero reading and include it in the program.
- Being a low power device, the analog and switch outputs should be carefully connected with high impedance outputs. But please do not connect them directly to LED’s or motors. Refrain from high current devices (devices that are more than 1mA) as well because that could severely damage the controller.
You can program the Pico microcontroller, similar to Raspberry Pi 4, to run C/C++ and MicroPython. So it harnesses a multitude of peripherals like I2C, SPI, PWN and UART. In addition, it also supports analog to digital conversion and therefore can be used in a variety of projects. Connecting an analog joystick with Pico is fairly easy and efficient as compared to other RPI boards. The circuit diagram is clear. Hence the process of coding becomes easy once you set and define the GPIO pins.