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

 

 

NO YOUTUBE


NOSSO PODCAST