LoginSignup
6
4

More than 5 years have passed since last update.

Arduino開発入門-動かなければ勝ちゲームを作ってみた

Last updated at Posted at 2017-08-23

はじめに

Arduino開発の入門として、簡単なゲームを作成してみました。

概要

動かなければ勝ちゲームを作成します。
1分間、センサーに感知されないように動きを止めて監視をくぐり抜けるゲームです。

仕様

・電源が入ったらゲームスタート。
・ゲームをスタートしてから1分間、人感センサーに動きを感知されなければゲームクリア。
・動きを感知されたらゲームオーバー。
・ゲームクリア、ゲームオーバー時にLEDを点灯。
・再度ゲームを始めるにはArduinoのリセットボタンを押し、リセットする。

構成

・Arduino Uno R3
・LCDディスプレイ(I2Cモジュール付)
・人感センサー

フロー

フロー.png

詰まった所

・LCD液晶に文字が表示されなかった。
 原因:I2C アドレスが間違っていた。
 解決:下記のURLを参考にアドレスを調べて設定しました。
URL:http://ht-deko.com/arduino/lcd_i2c.html

 原因:ディスプレイの輝度が明る過ぎて文字が見えていなかった。
 解決:下記のURLを参考にI2CモジュールのLCD Constractの設定を変更したら表示できました。
URL:http://ht-deko.com/arduino/lcd_i2c.html

回路図

Arduino_Uno_i2C_LCD_ブレッドボード.png

完成イメージ

IMG_2306.jpg

ソースコード

#include <Wire.h> 
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x3F, 16, 2);

//----------------------------
// 人感センサー
#define SWITCH_SOCKET 2

//----------------------------
// LED制御
#define LED_SOCKET 10

//----------------------------
// Geme 制御
#define STATE_START 0 // ゲームスタート
#define STATE_RUN 1 // ゲーム実行中
#define STATE_GEME_OVER 9 // ゲームオーバー
#define STATE_GEME_CLEAR 8 // ゲームクリア

#define START_START_TIME 2000

int m_state = STATE_START;

void setup() {
  Serial.begin(9600);

  //-------------------------
  // PIN MODE 設定
  pinMode(LED_SOCKET,OUTPUT);
  pinMode(SWITCH_SOCKET, INPUT);

  //-------------------------
  // LED設定
  digitalWrite(LED_SOCKET,LOW);

  //-------------------------
  // LCD設定
  lcd.init();
  lcd.backlight();
}

void loop() {
  //--------------------------
  // 経過時間を取得
  unsigned long time_m = millis() - START_START_TIME;

  if(m_state == STATE_RUN)
  {
    //----------------------------
    // 人感センサー
    // 動きを感知したらゲームオーバー
    int val = digitalRead(SWITCH_SOCKET);
    if(val == 1){
      m_state = STATE_GEME_OVER;
      lcd.clear();
    }

    // 経過時間を監視
    // 1分過ぎたらゲームクリア
    int m = (time_m / 1000) / 60;
    m = m % 60;
    if(m >= 1){
      m_state = STATE_GEME_CLEAR;
      lcd.clear();
    }
  }

  // 状態に応じて表示を切り替え
  switch (m_state) {
  case STATE_START:
    lcd.setCursor(0, 0);
    lcd.print("Game Start !!");
    lcd.setCursor(0, 1);
    lcd.print("Don't move!");

    m_state = STATE_RUN;
    delay(START_START_TIME);
    lcd.clear();
    break;

  case STATE_RUN:
    // 現在時刻を表示
    DispCountTimer(time_m);
    break;

  case STATE_GEME_OVER:

    lcd.setCursor(0, 0);
    lcd.print("Game Over,,");

    analogWrite(LED_SOCKET, 124);
    digitalWrite(LED_SOCKET,HIGH);

    break;

  case STATE_GEME_CLEAR:
    lcd.setCursor(0, 0);
    lcd.print("Game Clear!!");

    analogWrite(LED_SOCKET, 124);
    digitalWrite(LED_SOCKET,HIGH);

    break;
  }

  delay(500);

}

/**
 * 現在時刻を表示
 */
void DispCountTimer(unsigned long time_m)
{
  int s = (time_m / 1000) % 60;
  int m = (time_m / 1000) / 60;
  m = m % 60;
  int h = (time_m / 1000) / 60 / 60;

  lcd.setCursor(0, 0);
  lcd.print(StringTwoZero(String(h)) + ":" + StringTwoZero(String(m))  + ":" + StringTwoZero(String(s)) );

}

/**
 * 2桁の前ゼロ変換
 */
String StringTwoZero(String val)
{
  val = "00" + val;
  return val.substring(val.length() - 2);
}

参考にしたサイト

LCDディスプレイに文字を表示:
http://ht-deko.com/arduino/lcd_i2c.html

最後に

LCDディスプレイの表示が思うようにされず時間がかかりましたが、ブログで技術展開してくれている皆様のおかげで、なんとか完成できました。ありがとうございました。

人感センサーの感度を高く設定していると呼吸をしただけでゲームオーバーとなるので、感度は下げるのがいいかと思います。

また、ゲームとしてだけでなく仕事の集中力が切れた時などにこのゲームを行うと、集中力を回復することが出来るので、ぜひご利用ください。

6
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
4