안녕하세요, 기술과 창의력을 결합한 프로젝트를 소개합니다. 이번에는 XIAO ESP32 C6 개발 보드를 활용한 재미있는 게임, "XIAO Hopper"를 제작해 보았습니다. Flappy Bird에서 영감을 얻어 LED 매트릭스를 기반으로 독창적인 게임을 처음부터 디자인했습니다. 이 글에서는 전체 제작 과정과 필요한 구성 요소를 상세히 설명하겠습니다.
프로젝트 개요
"XIAO Hopper"는 XIAO ESP32 C6 마이크로컨트롤러를 기반으로 만든 Flappy Bird 스타일의 픽셀 게임입니다. 이 게임은 사용자 지정 16x8 WS2812B LED 매트릭스를 디스플레이로 사용하며, 간단한 버튼 조작으로 플레이합니다. 플레이어는 단일 픽셀 형태로 표현된 새를 조작해 움직이는 기둥 사이의 틈을 통과하며, 기둥에 부딪히지 않도록 탐색하는 것이 목표입니다.

이 프로젝트를 위해 필요한 구성 요소는 다음과 같습니다:
- XIAO ESP32 C6 개발 보드
- 맞춤형 PCB (Seeed Studio Fusion에서 제공)
- 16x8 WS2812B LED 매트릭스
- 푸시 버튼
- 점퍼 와이어
- 브레드보드
1단계: XIAO ESP32 C6 개발 보드
XIAO ESP32 C6는 ESP32-C6 SoC를 기반으로 한 개발 보드로, 고성능 32비트 RISC-V 코어(160MHz)와 저전력 코어(20MHz)를 갖추고 있어 멀티태스킹 및 에너지 효율성이 뛰어납니다. 또한 Wi-Fi 6, Bluetooth 5.3, Zigbee/Thread와 같은 고급 통신 프로토콜을 지원해 스마트 홈 시스템 및 IoT 장치에 활용할 수 있는 강력한 보드입니다.
자세한 사양은 XIAO ESP32 C6 제품 페이지와 Wiki 페이지를 참조하세요.
2단계: 16X8 WS2812B LED 매트릭스
16x8 WS2812B LED 매트릭스는 이 게임의 디스플레이 역할을 합니다. 128개의 LED가 병렬로 연결되어 하나의 GPIO 핀으로 제어됩니다. 각 LED는 앞뒤로 배선되어 단일 데이터 핀만으로 모든 LED를 쉽게 제어할 수 있습니다.
LED 매트릭스 개발 방법에 대한 자세한 내용은 WS2812B 매트릭스 제작 과정을 참고하시기 바랍니다.
3단계: PCB 제작
Seeed Studio Fusion PCB 서비스는 빠르고 신뢰할 수 있는 프로토타이핑 서비스를 제공하며, 높은 품질의 PCB와 턴키 PCBA 솔루션을 지원합니다. PCB 제작부터 조립 및 테스트까지 원스톱으로 진행하여 효율적으로 작업할 수 있습니다.
더 자세한 정보는 Seeed Studio Fusion 공식 사이트에서 확인해 보세요.
4단계: 브레드보드 조립
마지막으로 브레드보드에 부품들을 연결하며 조립을 시작합니다:
- XIAO ESP32 C6 마이크로컨트롤러를 브레드보드에 배치합니다.
- LED 매트릭스의 VCC를 XIAO의 5V에 연결합니다.
- LED 매트릭스의 GND를 XIAO의 GND에 연결합니다.
- 푸시 버튼의 한 단자는 GND에 연결하고, 다른 단자는 GPIO 1로 배선합니다.
- LED 매트릭스의 데이터 핀은 XIAO의 GPIO0에 연결합니다.
이제 조립이 완료되었습니다. 준비된 코드로 게임을 실행하면 XIAO Hopper의 매력적인 픽셀 게임을 즐길 수 있습니다!
공급
이 빌드에 사용되는 구성 요소는 다음과 같습니다.
- XIAO ESP32 C6 개발 보드
- 맞춤형 PCB(Seeed Fusion 제공)
- WS2812B LED
- 점퍼 와이어
- 브레드보드
- 푸시 버튼
1단계: XIAO ESP32 C6 개발 보드


이 프로젝트에서는 ESP32-C6 SoC를 기반으로 하고 트윈 32비트 RISC-V 프로세서를 특징으로 하는 XIAO ESP32 C6 개발 보드를 활용하고 있으며, 하나는 160MHz에서 작동하는 고성능 코어가 있고 다른 하나는 20MHz에서 실행되는 저전력 코어가 있어 효율적인 멀티태스킹 및 에너지 절약을 가능하게 합니다.
512KB SRAM 및 4MB 플래시는 프로그램 실행 및 저장을 위한 충분한 공간을 제공하므로 속도와 메모리 효율성이 모두 요구되는 프로젝트에 탁월한 선택입니다.
XIAO ESP32 C6는 Wi-Fi 6, Bluetooth 5.3 및 Zigbee/Thread와 같은 고급 프로토콜을 지원하여 스마트 홈 시스템 및 IoT 장치와 원활하게 통합할 수 있는 연결성이 특징입니다. 이 보드에는 11개의 GPIO 핀과 UART, SPI, I2C 및 ADC와 같은 다양한 인터페이스가 있어 센서 및 주변 장치에 쉽게 연결할 수 있습니다. 작은 설치 공간(21mm x 17.8mm)과 USB Type-C 전원 입력으로 LED 매트릭스 게임 콘솔과 같이 공간 제약이 있고 휴대가 간편한 프로젝트에 적합합니다.
원하는 경우 제품 페이지를 방문하거나 wiki 페이지를 방문하여 개발 보드에 대해 자세히 알아보세요.
https://www.seeedstudio.com/Seeed-Studio-XIAO-ESP32C6-p-5884.html
2단계: 16X8 WS2812B LED 매트릭스



이 프로젝트에서는 이전에 만든 매트릭스 프로젝트 중 하나를 사용하는데, 16x8 매트릭스 레이아웃에 배치된 128개의 WS2812B LED와 16개의 LED가 16개의 행과 8개의 열에 배치되는 프로젝트입니다.
각 WS2812B LED는 서로 병렬로 배선됩니다. 128개의 LED를 모두 제어하려면 각 LED가 첫 번째 LED Dout가 두 번째 LED Din 포트에 연결되고, 두 번째 LED Dout가 세 번째 LED의 Din에 연결되는 방식으로 마지막 128번째 LED까지 연결되는 고유한 구성으로 연결되기 때문에 하나의 GPIO만 필요합니다.
이 디스플레이의 개발 프로세스에 대한 자세한 내용은 간략하게 설명한 이전 기사를 참조하십시오.
https://www.instructables.com/Custom-16x8-Ws2812-Matrix-Project/
3단계: Seeed Studio Fusion
Seeed 퓨전 PCB서비스는 PCB 제조 및 PCB 조립을 위한 원스톱 프로토타이핑을 제공하며, 그 결과 영업일 기준 7일 이내에 우수한 품질의 PCB와 빠른 턴키 PCBA를 생산합니다.
Seeed Studio Fusion PCB 조립 서비스는 Seeed Studio Fusion Agile 제조 및 하드웨어 맞춤화에서 부품 소싱, 조립 및 테스트 서비스에 이르기까지 전체 제조 프로세스를 처리하므로 고품질 제품을 얻고 있음을 확신할 수 있습니다.
시장 관심을 측정하고 작동 중인 프로토타입을 검증한 후 Seeed Propagate 서비스는 전문적인 안내와 강력한 연결 네트워크를 통해 제품을 시장에 출시하는 데 도움을 줄 수 있습니다.
4단계: 브레드보드 어셈블리
- 조립을 시작하기 위해 XIAO ESP32 C6 마이크로 컨트롤러를 브레드 보드에 놓습니다. 그런 다음 옆에 푸시 버튼을 추가합니다.
- 매트릭스의 VCC를 XIAO의 5V에 연결하여 배선 프로세스를 시작합니다.
- 그런 다음 매트릭스의 GND는 XIAO의 GND에 연결됩니다.
- 푸시 버튼의 한 단자는 GND에 연결하고 다른 단자는 GPIO 1에 배선했습니다.
- 매트릭스 데이터 와이어는 XIAO의 GPIO0에 연결됩니다.
이제 배선 프로세스가 완료되었습니다.
5단계: 코드
이것은 이 프로젝트에서 사용된 코드이며 간단한 코드입니다.
#include <Adafruit_NeoMatrix.h>
#define MATRIX_PIN 0
#define MATRIX_WIDTH 16
#define MATRIX_HEIGHT 8
Adafruit_NeoMatrix matrix = Adafruit_NeoMatrix(MATRIX_WIDTH, MATRIX_HEIGHT, MATRIX_PIN,
NEO_MATRIX_TOP + NEO_MATRIX_LEFT + NEO_MATRIX_ROWS, NEO_GRB + NEO_KHZ800);
#define BUTTON_PIN 1
int birdY = MATRIX_HEIGHT / 2;
struct Pillar {
int x;
int gapStart;
int gapHeight;
};
Pillar pillars[5];
int gameSpeed = 200; // Initial game speed
int difficultyCounter = 0; // Difficulty tracking
void setup() {
matrix.begin();
matrix.setBrightness(50);
matrix.fillScreen(0);
matrix.show();
pinMode(BUTTON_PIN, INPUT_PULLUP);
for (int i = 0; i < 5; i++) {
pillars[i].x = MATRIX_WIDTH + i * 8;
pillars[i].gapStart = random(2, MATRIX_HEIGHT - 2);
pillars[i].gapHeight = 3;
}
Serial.begin(115200);
}
void loop() {
matrix.fillScreen(0);
// Bird movement based on button hold
if (digitalRead(BUTTON_PIN) == LOW) {
birdY -= 1; // Bird moves upward while button is held
} else {
birdY += 1; // Gravity pulls bird downward when button is released
}
// Clamp bird position to stay within matrix bounds
if (birdY < 0) birdY = 0;
if (birdY >= MATRIX_HEIGHT) birdY = MATRIX_HEIGHT - 1;
// Draw bird
matrix.drawPixel(3, birdY, matrix.Color(255, 255, 0)); // Yellow bird
// Move and draw pillars
uint32_t pillarColor = matrix.Color(128, 0, 128); // Purple for initial difficulty
if (difficultyCounter > 50) {
pillarColor = matrix.Color(255, 0, 0); // Transition to red for higher difficulty
}
for (int i = 0; i < 5; i++) {
pillars[i].x--;
if (pillars[i].x < 0) {
pillars[i].x = MATRIX_WIDTH;
pillars[i].gapStart = random(2, MATRIX_HEIGHT - 2);
difficultyCounter++;
}
for (int y = 0; y < MATRIX_HEIGHT; y++) {
if (y < pillars[i].gapStart || y > pillars[i].gapStart + pillars[i].gapHeight) {
matrix.drawPixel(pillars[i].x, y, pillarColor);
}
}
}
// Collision detection
for (int i = 0; i < 5; i++) {
if (pillars[i].x == 3 && (birdY < pillars[i].gapStart || birdY > pillars[i].gapStart + pillars[i].gapHeight)) {
matrix.fillScreen(matrix.Color(255, 0, 0)); // Game over
matrix.show();
delay(2000);
setup(); // Restart game
return;
}
}
matrix.show();
if (difficultyCounter % 10 == 0 && gameSpeed > 150) {
gameSpeed -= 5;
}
delay(gameSpeed);
}
Let's have a brief breakdown of our code.
We use the Adafruit_NeoMatrix.h library to control the 16x8 WS2812B LED matrix. This library helps us draw pixels, shapes, and animations.
#define MATRIX_PIN 0
#define MATRIX_WIDTH 16
#define MATRIX_HEIGHT 8
Adafruit_NeoMatrix matrix = Adafruit_NeoMatrix(MATRIX_WIDTH, MATRIX_HEIGHT, MATRIX_PIN, NEO_MATRIX_TOP + NEO_MATRIX_LEFT + NEO_MATRIX_ROWS, NEO_GRB + NEO_KHZ800);
#define BUTTON_PIN 1
The matrix is initialized to match its physical layout and color format.
BUTTON_PIN connects to a button, which controls the bird's movement.
int birdY = MATRIX_HEIGHT / 2; // Bird starts in the middle vertically
struct Pillar {
int x; // Horizontal position
int gapStart; // Starting position of the gap
int gapHeight; // Gap height
};
Pillar pillars[5];
The bird's vertical position (birdY) is tracked.
Pillars are defined with x (horizontal position), gapStart (gap's position), and gapHeight (size).
void setup() {
matrix.begin();
matrix.setBrightness(50); // Set LED brightness
matrix.fillScreen(0); // Clear the matrix
matrix.show();
pinMode(BUTTON_PIN, INPUT_PULLUP); // Button setup
for (int i = 0; i < 5; i++) {
pillars[i].x = MATRIX_WIDTH + i * 8; // Spacing pillars evenly
pillars[i].gapStart = random(2, MATRIX_HEIGHT - 2); // Random gaps
pillars[i].gapHeight = 3; // Fixed gap height
}
Serial.begin(115200); // Serial for debugging
}
This Section prepares the LED matrix, sets the button pin as input, and initializes the pillars.
if (digitalRead(BUTTON_PIN) == LOW) {
birdY -= 1; // Button pressed, bird goes up
} else {
birdY += 1; // Button released, gravity pulls bird down
}
if (birdY < 0) birdY = 0; // Prevent bird going off-screen
if (birdY >= MATRIX_HEIGHT) birdY = MATRIX_HEIGHT - 1;
matrix.drawPixel(3, birdY, matrix.Color(255, 255, 0)); // Draw yellow bird
The button controls the bird's movement, simulating gravity when released.
The bird's position is clamped within screen bounds and drawn at x=3 .
pillars[i].x--;
if (pillars[i].x < 0) {
pillars[i].x = MATRIX_WIDTH; // Reset pillar position
pillars[i].gapStart = random(2, MATRIX_HEIGHT - 2); // New random gap
}
for (int y = 0; y < MATRIX_HEIGHT; y++) {
if (y < pillars[i].gapStart || y > pillars[i].gapStart + pillars[i].gapHeight) {
matrix.drawPixel(pillars[i].x, y, matrix.Color(128, 0, 128)); // Draw purple pillars
}
}
Pillars move left and reset with new gap positions when they leave the screen.
if (pillars[i].x == 3 && (birdY < pillars[i].gapStart || birdY > pillars[i].gapStart + pillars[i].gapHeight)) {
matrix.fillScreen(matrix.Color(255, 0, 0)); // Red screen for Game Over
matrix.show();
delay(2000);
setup(); // Restart game
return;
}
This Checks if the bird hits a pillar (outside the gap) and Displays "Game Over" in red, then restarts the game.
if (difficultyCounter % 10 == 0 && gameSpeed > 150) {
gameSpeed -= 5; // Gradually increase game speed
}
delay(gameSpeed);
결론
이 프로젝트는 간단하면서도 창의적인 디자인으로, 기술과 엔터테인먼트의 훌륭한 결합을 보여줍니다. Flappy Bird 스타일의 게임을 LED 매트릭스와 XIAO ESP32 C6 마이크로컨트롤러를 활용해 만들어 보는 것은 도전과 재미를 동시에 제공합니다.
추가 질문이나 도움이 필요하면 언제든 말씀해주세요! 🎮✨
이 블로그 형식은 프로젝트를 소개하고 사람들이 따라 할 수 있도록 만드는 데 유용할 것입니다. 의견 있으시면 공유해주세요! 😊
'게임기 만들기' 카테고리의 다른 글
8x8 RGB 픽셀 매트릭스를 이용한 복고풍 포켓 게이머 제작 (0) | 2025.04.11 |
---|---|
전자 핸드헬드 크리켓 게임 V2 제작 (1) | 2025.04.07 |