はじめに
Arduino開発の入門として、簡単なゲームを作成してみました。
概要
動かなければ勝ちゲームを作成します。
1分間、センサーに感知されないように動きを止めて監視をくぐり抜けるゲームです。
仕様
・電源が入ったらゲームスタート。
・ゲームをスタートしてから1分間、人感センサーに動きを感知されなければゲームクリア。
・動きを感知されたらゲームオーバー。
・ゲームクリア、ゲームオーバー時にLEDを点灯。
・再度ゲームを始めるにはArduinoのリセットボタンを押し、リセットする。
構成
・Arduino Uno R3
・LCDディスプレイ(I2Cモジュール付)
・人感センサー
フロー
詰まった所
・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
回路図
完成イメージ
ソースコード
# 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ディスプレイの表示が思うようにされず時間がかかりましたが、ブログで技術展開してくれている皆様のおかげで、なんとか完成できました。ありがとうございました。
人感センサーの感度を高く設定していると呼吸をしただけでゲームオーバーとなるので、感度は下げるのがいいかと思います。
また、ゲームとしてだけでなく仕事の集中力が切れた時などにこのゲームを行うと、集中力を回復することが出来るので、ぜひご利用ください。