Neste artigo teremos 3 passos, onde veremos como capturamos os dados e exibimos no display, os valores de X e Y e mais o clique. No segundo código movimentaremos um cursor na tela e finalmente montaremos o jogo do Pong.
O Joystick KY-023
Este módulo é muito usado na comunidade maker, seja para aulas como para o desenvolvimento de controles de videogames.
Na figura abaixo temos uma foto dele junto com o diagrama elétrico, nele podemos ver que o módulo possui dois potenciômetros e um botão, a engenhosidade está na forma como estes componentes estão montados.

O display SSD1306
O display também faz parte dos componentes ou módulos mais utilizados no mercado maker e temos um vídeo e um artigo o( Display SSD1306 com a Raspberry Pi Pico ), onde abordamos o seu uso e funcionamento.
O Código
Agora vamos aos códigos , sendo que o primeiro (logo abaixo) , temos um jeito simples de exibir no display os valores obtidos pelo movimento da alavanca do joystick.
from machine import Pin, SoftI2C, ADC
import ssd1306
import time
# --- OLED ---
i2c = SoftI2C(scl=Pin(5), sda=Pin(4))
oled = ssd1306.SSD1306_I2C(128, 64, i2c)
# --- Joystick ---
x = ADC(26) # VRx → GP26 (ADC0)
y = ADC(27) # VRy → GP27 (ADC1)
sw = Pin(16, Pin.IN, Pin.PULL_UP) # Botão
def ler_joystick():
return x.read_u16(), y.read_u16(), sw.value()
while True:
x_val, y_val, sw_val = ler_joystick()
oled.fill(0) # limpa a tela
oled.text('Joystick:', 0, 0)
oled.text('X: {}'.format(x_val), 0, 15)
oled.text('Y: {}'.format(y_val), 0, 30)
oled.text('BTN: {}'.format('OK' if sw_val == 0 else 'Solto'), 0, 45)
oled.show()
time.sleep(0.1)
Vale lembrar que é possível usar a função print() para exibir no terminal os valores obtidos.
Agora no próximo código vamos movimentar um cursor pelo display conforme movimentamos a alavanca do joystick.
from machine import Pin, SoftI2C, ADC
import ssd1306
import time
# --- OLED ---
i2c = SoftI2C(scl=Pin(5), sda=Pin(4))
oled = ssd1306.SSD1306_I2C(128, 64, i2c)
# --- Joystick ---
x_adc = ADC(26) # VRx
y_adc = ADC(27) # VRy
sw = Pin(16, Pin.IN, Pin.PULL_UP)
# --- Cursor inicial ---
cursor_x = 64
cursor_y = 32
def map_range(value, in_min, in_max, out_min, out_max):
return int((value - in_min) * (out_max - out_min) / (in_max - in_min) + out_min)
while True:
# Leitura do joystick
x_val = x_adc.read_u16()
y_val = y_adc.read_u16()
# Converte valores para velocidade (-3 a +3)
dx = map_range(x_val, 0, 65535, -3, 3)
dy = map_range(y_val, 0, 65535, -3, 3)
# Atualiza posição do cursor
cursor_x += dx
cursor_y += dy
# Limites da tela
cursor_x = max(0, min(cursor_x, 127))
cursor_y = max(0, min(cursor_y, 63))
# Desenha
oled.fill(0)
oled.text("Cursor:", 0, 0)
oled.pixel(cursor_x, cursor_y, 1) # desenha o cursor
oled.show()
time.sleep(0.05)
No código a seguir temos o jogo Pong (paredão) onde utilizamos o display, o joystick e o processamento da Pi Pico.
from machine import Pin, SoftI2C, ADC
import ssd1306
import time
import random
# --- OLED ---
i2c = SoftI2C(scl=Pin(5), sda=Pin(4))
oled = ssd1306.SSD1306_I2C(128, 64, i2c)
# --- Joystick ---
joy_y = ADC(27) # eixo Y controla a raquete
# --- Raquete ---
paddle_y = 32
paddle_height = 15
paddle_x = 5
# --- Bola ---
ball_x = 64
ball_y = 32
ball_dx = 2
ball_dy = 2
score = 0
def map_range(value, in_min, in_max, out_min, out_max):
return int((value - in_min) * (out_max - out_min) / (in_max - in_min) + out_min)
while True:
# --- Leitura do joystick ---
y_val = joy_y.read_u16()
dy = map_range(y_val, 0, 65535, -3, 3)
paddle_y += dy
# Limites da raquete
paddle_y = max(0, min(paddle_y, 64 - paddle_height))
# --- Movimento da bola ---
ball_x += ball_dx
ball_y += ball_dy
# Colisão com bordas superior/inferior
if ball_y <= 0 or ball_y >= 63:
ball_dy = -ball_dy
# Colisão com a raquete
if paddle_x < ball_x < paddle_x + 3:
if paddle_y <= ball_y <= paddle_y + paddle_height:
ball_dx = -ball_dx
score += 1
# Se a bola sair da tela → reinicia
if ball_x <= 0:
ball_x = 64
ball_y = 32
ball_dx = 2
ball_dy = random.choice([-2, 2])
score = 0
# Colisão com borda direita
if ball_x >= 127:
ball_dx = -ball_dx
# --- Desenho ---
oled.fill(0)
# Raquete
oled.fill_rect(paddle_x, paddle_y, 3, paddle_height, 1)
# Bola
oled.pixel(ball_x, ball_y, 1)
# Pontuação
oled.text("Score: {}".format(score), 40, 0)
oled.show()
time.sleep(0.02)
Neste link temos o vídeo explicativo deste artigo - https://www.youtube.com/watch?v=aqQ7lcC7zkE















