名刺サイズPCBで作る4×4三目並べゲーム - 設計・製作・プログラミングガイド
概要
このチュートリアルでは、名刺サイズのカスタムPCBを作成し、それを4×4の三目並べゲームとしても使えるようにする手順を解説します。表面にはEDISON SCIENCE CORNERのロゴ、SNSアイコン、YouTubeチャンネルへのQRコードを配置。裏面をめくると、ATmega328、NeoPixel LED、タクトスイッチで構成された完全に機能するゲーム回路が現れます。
必要な部品と材料
| 部品 | 数量 |
|---|---|
| Microchip ATmega328P‑AU | 1 |
| NeoPixel RGB LEDストリップ (WS2812B) | 16個 (4×4) |
| タクトスイッチ (上面操作タイプ) | 16個 |
| カスタムPCB (JLCPCB製) | 1枚 |
| Arduino UNO (書き込み用) | 1台 |
| USB Micro‑Bコネクタ (メス) | 1個 |
| コンデンサ 22pF (0805) | 2個 |
| コンデンサ 100nF (0805) | 2個 |
| 抵抗 1kΩ (0805) | 3個 |
| 抵抗 10kΩ (0805) | 1個 |
| 16MHz 水晶発振子 | 1個 |
| LED (SMD 0805) | 2個 |
必要な工具と機器
- はんだごて (汎用)
- 鉛フリーはんだ
- フラックス
- ジャンパーワイヤキット (5cm、10本)
使用するアプリとオンラインサービス
- Arduino IDE
- EasyEDA - PCB設計プラットフォーム
- JLCPCB - 低コストPCB製造 (5枚で$2から)
ステップ1: PCBの設計と発注
EasyEDAを使用して、標準的な名刺サイズである89mm × 50mmの基板を設計し、4×4の三目並べマトリックスを配線しました。回路図ではATmega328をメインマイコンとし、16個のWS2812B LEDと16個のタクトスイッチを統合しています。レイアウトを確定後、ガーバーファイルを出力しJLCPCBにアップロード。板厚0.8mmの黒基板で発注し、2週間で品質の良い基板が届きました。
ステップ2: 部品の調達
上記の部品リストを参照してください。すべて一般的で安価な部品であり、Digi-Key、Mouser、AliExpressなどの電子部品通販で入手可能です。
ステップ3: はんだ付け
最初にUSB Micro-Bコネクタをはんだ付けし、次にATmega328と周辺の受動部品を実装します。その後、NeoPixel LEDストリップを配置し、各LEDに対応するタクトスイッチを位置合わせしながらはんだ付けします。全16個のスイッチを向きに注意して慎重に実装してください。熟練したホビイストなら約1時間で組み立てられます。
ステップ4: プログラミング
基板をUSBでPCに接続し、Arduino IDEで以下のスケッチを書き込みます:
このスケッチは16個のLEDアレイを初期化し、4×4キーパッドマトリックスからのキー入力を処理、シンプルな勝利判定を実装しています。プレイヤー1は緑色LED、プレイヤー2は青色LEDを使用。勝利時は勝者の色で点滅、引き分け時は赤色で点滅します。
ステップ5: 遊んで楽しむ
カードを裏返せばゲーム面が現れます。ボタンを押すと対応するLEDが点灯。クラシックな三目並べのルールですが、4×4グリッドと色表示で楽しめます。会議やネットワーキングイベントでの会話のきっかけになる、ユニークな携帯型ゲームの完成です。
ソースコード
プロジェクトで使用したArduinoスケッチ (C/C++) を全文掲載します。キーパッド処理、LED制御、勝利判定ロジックを含みます。
#include <Keypad.h>
#include <FastLED.h>
#define LED_PIN 5
#define NUM_LEDS 16
#define LED_TYPE WS2812B
#define COLOR_ORDER GBR
#define BRIGHTNESS 30
CRGB leds[NUM_LEDS];
int player = 1;
char board[16] = {'1','2','3','4','5','6','7','8','9','10','11','12','13','14','15','16'};
char key;
int moveCount = 0;
const byte ROWS = 4;
const byte COLS = 4;
char hexaKeys[ROWS][COLS] = {{'1','2','3','A'},{'4','5','6','B'},{'7','8','9','C'},{'*','0','#','D'}};
byte rowPins[ROWS] = {A0,A1,A2,A3};
byte colPins[COLS] = {A4,A5,2,3};
Keypad customKeypad = Keypad(makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS);
void setup(){
Serial.begin(9600);
LEDS.addLeds<LED_TYPE, LED_PIN, COLOR_ORDER>(leds, NUM_LEDS);
FastLED.setBrightness(BRIGHTNESS);
// 起動時: 全LEDを緑→青と点灯させて動作確認
for(int i=0;i<3;i++){
for(int j=0;j<NUM_LEDS;j++) leds[j] = (i%2==0) ? CRGB::Green : CRGB::Blue;
FastLED.show();
delay(500);
}
FastLED.clear();
}
void loop(){
key = customKeypad.getKey();
if(key && player==1){
int idx = keyToIndex(key);
leds[idx] = CRGB::Green;
FastLED.show();
board[idx] = 'X';
if(checkWinner('X')){ announceWinner(1); }
player = 2;
delay(1000);
}
if(key && player==2){
int idx = keyToIndex(key);
leds[idx] = CRGB::Blue;
FastLED.show();
board[idx] = 'O';
if(checkWinner('O')){ announceWinner(2); }
player = 1;
moveCount++;
delay(1000);
}
if(moveCount==8){ announceDraw(); }
}
int keyToIndex(char k){
switch(k){
case '1': return 0; case '2': return 1; case '3': return 2; case 'A': return 3;
case '4': return 4; case '5': return 5; case '6': return 6; case 'B': return 7;
case '7': return 8; case '8': return 9; case '9': return 10; case 'C': return 11;
case '*': return 12; case '0': return 13; case '#': return 14; case 'D': return 15;
}
return -1;
}
bool checkWinner(char mark){
const int lines[10][4] = {
{0,1,2,3},{4,5,6,7},{8,9,10,11},{12,13,14,15}, // 行
{0,4,8,12},{1,5,9,13},{2,6,10,14},{3,7,11,15}, // 列
{0,5,10,15},{3,6,9,12} // 斜め
};
for(auto &line: lines){
if(board[line[0]]==mark && board[line[1]]==mark && board[line[2]]==mark && board[line[3]]==mark){
return true;
}
}
return false;
}
void announceWinner(int p){
CRGB color = (p==1) ? CRGB::Green : CRGB::Blue;
while(true){
for(int i=0;i<NUM_LEDS;i++) leds[i] = color;
FastLED.show(); delay(500);
FastLED.clear(); FastLED.show(); delay(500);
}
}
void announceDraw(){
while(true){
for(int i=0;i<NUM_LEDS;i++) leds[i] = CRGB::Red;
FastLED.show(); delay(1000);
FastLED.clear(); FastLED.show(); delay(500);
}
}
回路図
設計ファイル、BOM、コードはすべてダウンロード可能です。
製造プロセス
- Arduino NanoとMPU-6050で作るリアルタイムジャイロスコープゲーム
- スマートホーム連携向けマルチポジション温度センサーシステム
- Arduino Nanoで37LEDルーレットゲームを自作:ヨーロピアンスタイル完全再現
- DIY Arduino USBゲームコントローラー - 高性能ゲームパッドを自作
- Arduino Dueで作るタッチスクリーン三目並べゲーム
- MotionSense: ArduinoとESP8266で作るスマート侵入検知システム
- 3Dプリンター火災予防:スマートセンサーセーフティシステム
- Pixel Chaser: Arduino Nanoで作るワンタップLEDゲーム
- Arduinoで作る斥力式磁気浮上装置: シンプル回路とDIYガイド
- 高度なリモートコントロールグリッパーロボット: 精密ハンドリング向け
- CoroFenceサーマルディテクター:Grid-EYE & PIRセンサー搭載IoT体温監視