
Projekt opiera się na dwóch płytkach ESP wyposażonych w wyświetlacze OLED i konsole do gier, które komunikują się bezprzewodowo za pomocą ESP-NOW. Umożliwiają one płynną i interaktywną rozgrywkę w klasyczną grę Pong, wyświetlaną na ekranach OLED. Sterowanie odbywa się za pomocą prostych przycisków, a całość łączy technologię ESP z klasyczną estetyką gier retro.
-Dwie płytki Esp8266
-Dwa wyświetlacze OLED SSD 1306
-Dwa kable micro USB
-Game console z przyciskami
Projekt opiera się na dwóch płytkach ESP, które zostały zaprojektowane do bezprzewodowej współpracy w ramach gry Pong, realizowanej za pomocą protokołu ESP-NOW. Jest to technologia umożliwiająca szybkie i bezpośrednie przesyłanie danych między urządzeniami ESP bez konieczności korzystania z sieci Wi-Fi czy routera. Każda płytka została wyposażona w wyświetlacz OLED, na którym wyświetlana jest gra, oraz prostą konsolę do gier z przyciskami sterującymi, które pozwalają graczom kontrolować ruchy paletek w czasie rzeczywistym.
Gra Pong, będąca klasykiem w świecie gier wideo, została zaprogramowana tak, aby zapewnić płynną i dynamiczną rozgrywkę. Gracze rywalizują ze sobą, sterując paletkami na swoich wyświetlaczach OLED, próbując odbijać piłkę i zdobywać punkty. Rozgrywka odbywa się w pełni synchronicznie dzięki wykorzystaniu ESP-NOW, co eliminuje opóźnienia i zapewnia wrażenie gry w czasie rzeczywistym. Każda z płytek ESP działa jako niezależny węzeł komunikacyjny, wysyłając i odbierając dane na temat pozycji piłki oraz stanu gry.
Wyświetlacze OLED zapewniają minimalistyczną, ale czytelną grafikę gry, przypominającą estetykę klasycznych konsol retro. Każdy gracz widzi na swoim wyświetlaczu te same dane, co sprawia, że rozgrywka jest spójna i angażująca. Dodatkowo, wykorzystanie przycisków w konsolach umożliwia intuicyjne sterowanie, co czyni projekt łatwym w obsłudze dla użytkowników o różnym poziomie doświadczenia.
Projekt ten łączy wiele aspektów elektroniki i programowania, takich jak komunikacja bezprzewodowa, obsługa wyświetlaczy OLED, projektowanie układów sterujących oraz implementacja logiki gry. Dzięki temu jest doskonałym przykładem integracji technologii ESP w aplikacjach interaktywnych. Może służyć zarówno jako edukacyjny projekt DIY, jak i baza do tworzenia bardziej złożonych systemów gier lub aplikacji komunikacyjnych.
Dzięki prostocie i jednocześnie dużej funkcjonalności, projekt może być inspiracją dla innych konstrukcji, pokazując, jak niewielkie i tanie moduły ESP można wykorzystać do tworzenia ciekawych, interaktywnych urządzeń.





Kod płytki master
import network
import espnow
from machine import I2C, Pin
from ssd1306 import SSD1306_I2C
import time
# Debug flag
DEBUG = True
# I2C setup
i2c = I2C(scl=Pin(5), sda=Pin(4))
oled = SSD1306_I2C(128, 64, i2c)
# ESP-NOW setup
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
esp = espnow.ESPNow()
esp.active(True)
slave_mac = b'\x08:\x8d\xcc\xfc\xca' # Replace with slave MAC address
esp.add_peer(slave_mac)
# Game variables
ball_x, ball_y = 64, 32
ball_dx, ball_dy = 1, 1
ball_speed = 2
paddle1_y, paddle2_y = 28, 28
score1, score2 = 0, 0
game_active = False
# Button setup
up_button = Pin(12, Pin.IN, Pin.PULL_UP)
down_button = Pin(13, Pin.IN, Pin.PULL_UP)
select_button = Pin(14, Pin.IN, Pin.PULL_UP)
def log(message):
if DEBUG:
print(message)
def update_paddle():
global paddle1_y
if not up_button.value():
paddle1_y = max(0, paddle1_y - 2)
if not down_button.value():
paddle1_y = min(48, paddle1_y + 2)
def update_ball():
global ball_x, ball_y, ball_dx, ball_dy, score1, score2
ball_x += ball_dx * ball_speed
ball_y += ball_dy * ball_speed
if ball_y <= 0 or ball_y >= 63:
ball_dy = -ball_dy
if ball_x <= 4 and paddle1_y <= ball_y <= paddle1_y + 16:
ball_dx = -ball_dx
elif ball_x >= 124 and paddle2_y <= ball_y <= paddle2_y + 16:
ball_dx = -ball_dx
if ball_x < 0:
score2 += 1
reset_ball()
elif ball_x > 127:
score1 += 1
reset_ball()
def reset_ball():
global ball_x, ball_y, ball_dx, ball_dy
ball_x, ball_y = 64, 32
ball_dx, ball_dy = 1, 1
def show_menu():
oled.fill(0)
oled.text("Pong Game", 20, 10)
oled.text("Press SELECT", 10, 30)
oled.text("to Start", 30, 40)
oled.show()
def start_game():
global game_active
game_active = True
reset_ball()
def draw_screen():
oled.fill(0)
oled.text(f"P1: {score1}", 0, 0)
oled.text(f"P2: {score2}", 64, 0)
oled.fill_rect(2, paddle1_y, 2, 16, 1)
oled.fill_rect(124, paddle2_y, 2, 16, 1)
oled.pixel(ball_x, ball_y, 1)
oled.show()
def send_game_state():
data = f"{ball_x},{ball_y},{paddle1_y},{score1},{score2}"
esp.send(slave_mac, data)
def receive_paddle_position():
global paddle2_y
if esp.any():
_, msg = esp.recv()
try:
paddle2_y = int(msg.decode())
except Exception as e:
log(f"Error parsing paddle position: {e}")
log("Starting game on Master...")
show_menu()
while True:
if not select_button.value():
start_game()
if game_active:
update_paddle()
update_ball()
send_game_state()
receive_paddle_position()
draw_screen()
time.sleep(0.02)
Kod do płytki slave
import network
import espnow
from machine import I2C, Pin
from ssd1306 import SSD1306_I2C
import time
# Debug flag
DEBUG = True
# I2C setup
i2c = I2C(scl=Pin(5), sda=Pin(4))
oled = SSD1306_I2C(128, 64, i2c)
# ESP-NOW setup
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
esp = espnow.ESPNow()
esp.active(True)
master_mac = b'\x08:\x8d\xcc\xea\xa5' # Replace with master MAC address
esp.add_peer(master_mac)
# Game variables
ball_x, ball_y = 64, 32
paddle1_y, paddle2_y = 28, 28
score1, score2 = 0, 0
# Button setup
up_button = Pin(12, Pin.IN, Pin.PULL_UP)
down_button = Pin(13, Pin.IN, Pin.PULL_UP)
def log(message):
if DEBUG:
print(message)
def update_paddle():
global paddle2_y
if not up_button.value():
paddle2_y = max(0, paddle2_y - 2)
if not down_button.value():
paddle2_y = min(48, paddle2_y + 2)
def draw_screen():
oled.fill(0)
oled.text(f"P1: {score1}", 0, 0)
oled.text(f"P2: {score2}", 64, 0)
oled.fill_rect(2, paddle1_y, 2, 16, 1)
oled.fill_rect(124, paddle2_y, 2, 16, 1)
oled.pixel(ball_x, ball_y, 1)
oled.show()
def send_paddle_position():
data = str(paddle2_y)
esp.send(master_mac, data)
def receive_game_state():
global ball_x, ball_y, paddle1_y, score1, score2
if esp.any():
_, msg = esp.recv()
try:
ball_x, ball_y, paddle1_y, score1, score2 = map(int, msg.decode().split(","))
except Exception as e:
log(f"Error parsing game state: {e}")
log("Starting game on Slave...")
while True:
update_paddle()
send_paddle_position()
receive_game_state()
draw_screen()
time.sleep(0.02)