工業製造
産業用モノのインターネット | 工業材料 | 機器のメンテナンスと修理 | 産業プログラミング |
home  MfgRobots >> 工業製造 >  >> Manufacturing Technology >> 製造プロセス

ブレッドボードからPCBへ:Simon Saysゲームの制作 – パート1

部品と用品

部品数量備考
Arduino UNO1
はんだ付け不要ブレッドボード フルサイズ1
LED(汎用)4緑・赤・黄・青 各1
SparkFun プッシュボタンスイッチ 12mm4LEDと対応する色
ブザー1
ジャンパーワイヤー(汎用)12
抵抗 10kΩ4ボタン用プルダウン(内蔵プルアップ使用時は不要)
抵抗 330Ω4LED電流制限用
USB-A - Bケーブル1

アプリとオンラインサービス

このプロジェクトについて

はじめに

誰もが知る「Simon Says」ゲーム:光るボタンのシーケンスを記憶し、同じ順序でボタンを押すアレです。Hackster LiveでPCB設計ツール「Upverter」を紹介するために、この楽しくシンプルなプロジェクトを作り、PCB化しました。以下はハードウェアとコードを含む基本プロジェクトです。

このシリーズは3部構成です。

このシリーズで学べること

ソフトウェア

Arduino IDEをお持ちでない方は、こちらから最新版をダウンロードしてください。

ハードウェアセットアップ

SparkFunのInventor's Kitの例を参考に、少しアレンジしたハードウェア構成です。以下のFritzing図をご覧ください。

ブレッドボードからPCBへ:Simon Saysゲームの制作 – パート1
ブレッドボードからPCBへ:Simon Saysゲームの制作 – パート1

コード

このゲームの面白さはバリエーションが無限に作れることです。ハードウェアはSparkFunの例をベースにし、コードはゼロから書きました。自作コードに興味がない方は、以下のコードを使うか、SparkFunの例題コードを少し修正して使うか、他のSimon Saysコードを探してみてください。

詳細なコメントとデバッグ用シリアル出力を入れているので、ゲーム実行中の動作をシリアルモニターで確認できます。動作動画は以下をご覧ください!

Simon Saysゲーム動画

※動画ではクリア条件を「連続5回正解」に設定しています。この数を変えれば難易度調整可能ですが、動画を短くするため5回にしました。

さて、ブレッドボードをPCBに変える準備が整いました! 次回「Breadboard to PCB パート2 – UpverterでPCB設計」でお会いしましょう。

コード

Simon Says Arduinoコード Arduino

int ledArray[] = {12, 9, 5, 2};  // ledArray[0]=緑, [1]=赤, [2]=黄, [3]=青
int buttonArray[] = {13, 10, 6, 3}; // buttonArray[0]=緑, [1]=赤, [2]=黄, [3]=青
int pinCount = 4;
int buzzer = 8;
int ledState = 0;
int gameState = 0;
#define NUMBERTOWIN 5  // クリアに必要な正解数(変更で難易度調整可)
int gameValues[NUMBERTOWIN];
int roundNum = 0;
unsigned long previousMillis = 0;
unsigned long interval1 = 500;

void setLed(int ledNum);
void displayClue(int roundNum);
boolean waitForInput(int buttonNum);

void setup() {
  Serial.begin(9600);
  Serial.println("setup");
  for (int Pin = 0; Pin < pinCount; Pin++) {
    pinMode(ledArray[Pin], OUTPUT);
  }
  for (int Pin = 0; Pin < pinCount; Pin++) {
    pinMode(buttonArray[Pin], INPUT_PULLUP); // 内蔵プルアップ使用
  }
  randomSeed(analogRead(0));
}

void loop() {
  if (gameState == 0) {
    int button0 = digitalRead(buttonArray[0]);
    int button1 = digitalRead(buttonArray[1]);
    int button2 = digitalRead(buttonArray[2]);
    int button3 = digitalRead(buttonArray[3]);
    if (button0 && button1 && button2 && button3) {
      pre_game();
    } else {
      Serial.println("button Pressed");
      setLed(-1);
      roundNum = 0;
      delay(1000);
      gameState = 1;
    }
  }
  if (gameState == 1) gamePlay();
  if (gameState == 2) {
    delay(500);
    winning_sound();
    winDisplay(); winDisplay(); winDisplay();
    loseDisplay();
    Serial.println("winDisplay");
    delay(1000);
    gameState = 0;
  }
  if (gameState == 3) {
    delay(500);
    losing_sound();
    loseDisplay(); loseDisplay(); loseDisplay();
    Serial.println("loseDisplay");
    delay(1000);
    gameState = 0;
  }
}

void pre_game() {
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis > interval1) {
    if (ledState == 0) { Serial.println("pre green"); setLed(0); ledState = 1; }
    else if (ledState == 1) { Serial.println("pre red"); setLed(1); ledState = 2; }
    else if (ledState == 2) { Serial.println("pre yellow"); setLed(2); ledState = 3; }
    else if (ledState == 3) { Serial.println("pre blue"); setLed(3); ledState = 0; }
    previousMillis = currentMillis;
  }
}

void gamePlay() {
  Serial.println("gamePlay");
  for (int i = 0; i < NUMBERTOWIN; i++) {
    gameValues[i] = floor(random(0, 4));
    Serial.println(gameValues[i], DEC);
  }
  Serial.print("Starting Round "); Serial.println(roundNum, DEC);
  for (int r = 0; r < NUMBERTOWIN; r++) {
    displayClue(roundNum);
    for (int i = 0; i <= roundNum; i++) {
      Serial.print("Waiting for input "); Serial.print(i+1, DEC);
      Serial.print(" of "); Serial.print(roundNum+1, DEC); Serial.println();
      if (waitForInput(gameValues[i])) {
        if (i == roundNum) {
          Serial.println("Correct");
          if (roundNum == NUMBERTOWIN - 1) {
            Serial.println("You Win!");
            gameState = 2;
            return;
          } else {
            Serial.println("Continue");
          }
        }
      } else {
        Serial.println("You Lose!");
        gameState = 3;
        return;
      }
    }
    roundNum++;
    delay(1000);
  }
}

void setLed(int ledNum) {
  if (ledNum < 0) {
    for (int i = 0; i < pinCount; i++) digitalWrite(ledArray[i], LOW);
  } else {
    for (int i = 0; i < pinCount; i++) {
      digitalWrite(ledArray[i], (i == ledNum) ? HIGH : LOW);
    }
  }
}

void displayClue(int roundNum) {
  setLed(-1);
  for (int i = 0; i <= roundNum; i++) {
    setLed(gameValues[i]);
    delay(750);
    setLed(-1);
    delay(250);
  }
}

boolean waitForInput(int buttonNum) {
  while (true) {
    int button0 = digitalRead(buttonArray[0]);
    int button1 = digitalRead(buttonArray[1]);
    int button2 = digitalRead(buttonArray[2]);
    int button3 = digitalRead(buttonArray[3]);
    if (!button0 || !button1 || !button2 || !button3) {
      delay(250);
      if (buttonNum == 0) { digitalWrite(ledArray[0], HIGH); delay(250); digitalWrite(ledArray[0], LOW); }
      else if (buttonNum == 1) { digitalWrite(ledArray[1], HIGH); delay(250); digitalWrite(ledArray[1], LOW); }
      else if (buttonNum == 2) { digitalWrite(ledArray[2], HIGH); delay(250); digitalWrite(ledArray[2], LOW); }
      else if (buttonNum == 3) { digitalWrite(ledArray[3], HIGH); delay(250); digitalWrite(ledArray[3], LOW); }
      if (buttonNum == 0 && button0 == 0) { Serial.println("0 Pressed"); return true; }
      else if (buttonNum == 1 && button1 == 0) { Serial.println("1 Pressed"); return true; }
      else if (buttonNum == 2 && button2 == 0) { Serial.println("2 Pressed"); return true; }
      else if (buttonNum == 3 && button3 == 0) { Serial.println("3 Pressed"); return true; }
      else return false;
    }
  }
}

void winDisplay() {
  for (int i = 0; i < 4; i++) { digitalWrite(ledArray[i], HIGH); delay(75); digitalWrite(ledArray[i], LOW); delay(75); }
  for (int i = 2; i >= 0; i--) { digitalWrite(ledArray[i], HIGH); delay(75); digitalWrite(ledArray[i], LOW); delay(75); }
}

void winning_sound() {
  Serial.println("buzzer1");
  tone(buzzer, 294, 250); delay(200);
  tone(buzzer, 294, 250); delay(200);
  tone(buzzer, 294, 250); delay(200);
  tone(buzzer, 392, 500); delay(500);
  tone(buzzer, 392, 250); delay(200);
  tone(buzzer, 440, 250); delay(200);
  tone(buzzer, 392, 250); delay(200);
  tone(buzzer, 440, 250); delay(200);
  tone(buzzer, 494, 500);
}

void loseDisplay() {
  for (int i = 0; i < 4; i++) digitalWrite(ledArray[i], HIGH);
  delay(200);
  for (int i = 0; i < 4; i++) digitalWrite(ledArray[i], LOW);
  delay(200);
}

void losing_sound() {
  Serial.println("losing_sound");
  tone(buzzer, 98, 250); delay(250);
  tone(buzzer, 93, 250); delay(250);
  tone(buzzer, 87, 250); delay(250);
}

回路図

simon_says_fritzing_Yb8EdKPqD4.fzz

製造プロセス

  1. Arduino NanoとMPU-6050で作るリアルタイムジャイロスコープゲーム
  2. Arduinoデジタルダイス: LCD表示の乱数ジェネレーター自作
  3. Arduino Nanoで37LEDルーレットゲームを自作:ヨーロピアンスタイル完全再現
  4. DIY Arduino USBゲームコントローラー - 高性能ゲームパッドを自作
  5. Arduinoとジョイスティックでインタラクティブゲーム – LEDフィードバック付き
  6. ポータブル距離検出器:Arduino Nano自作キット(HC-SR04、18650電源、3Dプリントケース付き)
  7. Pixel Chaser: Arduino Nanoで作るワンタップLEDゲーム
  8. 銅メッキプロジェクト:Arduino UNOで作るスマート電気メッキシステム
  9. Arduino Nanoで作るNeoPixelマトリックス版Pongゲーム
  10. 中小ショップのための航空宇宙製造参入ガイド:実践的アプローチ
  11. 4層PCB製造完全ガイド:ステップバイステッププロセス(後編)