マイコンArduinoを使って電光掲示板を作る。

 

 

マイコンArduinoを使って電光掲示板を作る。

 

続き

今回は新しいゲームを作って行きます。

 

作るゲームは「シューティングゲーム」です。

 

プログラム自体は前回のテニスと似ている部分が多いので分かり易いかと思います。

 

最初のプログラム

int count = 0;
int x_pos = 0;
int y_pos = 0;
int fort_pos = 7;        // 砲台の位置
boolean shot = false;    // ビーム発射
int velocity = 0;        // 落下速度


void setup() {
  // put your setup code here, to run once:
  pinMode(2,OUTPUT);
  pinMode(3,OUTPUT);
  pinMode(4,OUTPUT);
  pinMode(5,OUTPUT);
  pinMode(6,OUTPUT);
  pinMode(7,INPUT_PULLUP);
  pinMode(8,INPUT_PULLUP);
  pinMode(9,INPUT_PULLUP);
  pinMode(10,INPUT_PULLUP);
  pinMode(11,OUTPUT);
  
  x_pos = random(1, 15); // 爆弾の落ちてくる位置 ランダム
 }

void loop() {
  // put your main code here, to run repeatedly:
  for (int i = 0;i < 16;i++) {
    for (int j = 0;j < 16;j++) {
      digitalWrite(2,LOW);
      // ビームを描く
      if (shot) {
        if (x_pos == j) {
          if (j == fort_pos + 1 && i > y_pos)
            digitalWrite(2,HIGH);
        }
        else {
          if (j == fort_pos + 1)
            digitalWrite(2,HIGH);
        }
      }
      // 爆弾を描く
      if (j == x_pos && i == y_pos)
        digitalWrite(2,HIGH);
      // 砲身
      if (i == 14) {          // 15段目
        if (fort_pos + 1 == j)
        digitalWrite(2,HIGH);
      }
      // 砲台
      if (i == 15) {          // 1番下の16段目
        if (fort_pos <= j && j < fort_pos + 3)
        digitalWrite(2,HIGH);
      }
      digitalWrite(4,HIGH);
      digitalWrite(4,LOW);
    }
    digitalWrite(5,HIGH);
    digitalWrite(5,LOW);
  }
  digitalWrite(6,HIGH);
  digitalWrite(6,LOW);
  
  shot = false;
  count++;
  if (count > 10) {
    count = 0;

    // 爆弾の位置 y軸
    velocity++;
    if (velocity > 5) {   // 落下速度
      velocity = 0;
      y_pos++;
      if (y_pos > 15) {
        y_pos = 0;
        x_pos = random(1, 15);
      }
    }
    
    if (digitalRead(7) == 0) {  // 発射
      shot = true;
    }

    if (digitalRead(8) == 0) {  // NOP
    }

    // 砲台の位置
    if (digitalRead(9) == 0)
      if (fort_pos > 0)
        fort_pos--;         // 左へ移動

    if (digitalRead(10) == 0)
      if (fort_pos < 13)
        fort_pos++;         // 右へ移動
  }
}

ほぼ作りはテニスと同じ。

砲台の位置 = ラケットの位置

爆弾の位置 = ボールの位置

ビームは縦に一筋のラインでこれも最初のころに経験済み

 

テストの様子


www.youtube.com

今のところ単独で動いているだけです。

 

次回、撃破のアクションやサウンド等を作って行きます。

 

では、また。

 

mckeechan.hatenadiary.com

マイコンArduinoを使って電光掲示板を作る。

マイコンArduinoを使って電光掲示板を作る。

 

続き

今回は音が出る様に改造していきます。

 

本体にブザーを取り付けて行きます。

黒線をGNDに、赤線を11番ピンに直接はんだ付けします。

このブザーは電気に繋げるだけで鳴るタイプ

 

本体の改造はこれだけです。

 

次はプログラムです。

まず最初に作ったプログラムが

int count = 0;
int x_pos = 0;
int y_pos = 0;
boolean x_dir = false;
boolean y_dir = false;
int racket_pos = 5;        // ラケットの位置
int racket_size = 6;        // ラケットのサイズ

void setup() {
  // put your setup code here, to run once:
  pinMode(2,OUTPUT);
  pinMode(3,OUTPUT);
  pinMode(4,OUTPUT);
  pinMode(5,OUTPUT);
  pinMode(6,OUTPUT);
  pinMode(7,INPUT_PULLUP);
  pinMode(8,INPUT_PULLUP);
  pinMode(9,INPUT_PULLUP);
  pinMode(10,INPUT_PULLUP);
  pinMode(11,OUTPUT);
 }

void loop() {
  // put your main code here, to run repeatedly:
  for (int i = 0;i < 16;i++) {
    for (int j = 0;j < 16;j++) {
      digitalWrite(2,LOW);

      // ボールを描く
      if (j == x_pos && i == y_pos)
        digitalWrite(2,HIGH);

      // ラケットを描く
      if (i == 15) {          // 1番下の16段目
        if (racket_pos <= j && j < racket_size + racket_pos)
        digitalWrite(2,HIGH);
      }
      digitalWrite(4,HIGH);
      digitalWrite(4,LOW);
    }
    digitalWrite(5,HIGH);
    digitalWrite(5,LOW);
  }
  digitalWrite(6,HIGH);
  digitalWrite(6,LOW);
  
  count++;
  if (count > 10) {
    count = 0;
    
    // ボールの位置 x軸
    if (!x_dir)
      x_pos++;
    else
      x_pos--;
    if (x_pos > 14) {
      x_dir = true;
    }
    if (x_pos < 1) {
      x_dir = false;
    }

    // ボールの位置 y軸
    if (!y_dir)
      y_pos++;
    else
      y_pos--;
    if (y_pos == 14 && x_pos < racket_size + racket_pos && x_pos >= racket_pos) {
      y_dir = true;
      beep();
    }
    if (y_pos < 1) {
      y_dir = false;
    }
    
    if (y_pos > 15) {
      y_dir = false;
    }

    if (digitalRead(7) == 0) {  // サーブ
      x_pos = 0;
      y_pos = 0;
    }

    if (digitalRead(8) == 0) {  // サーブ
      x_pos = 15;
      y_pos = 0;
      x_dir = true;
    }

    // ラケットの位置
    if (digitalRead(9) == 0)
      if (racket_pos > 0)
        racket_pos--;         // 左へ移動

    if (digitalRead(10) == 0)
      if (racket_pos < 16 - racket_size)
        racket_pos++;         // 右へ移動
  }
}

void beep() {
  digitalWrite(11,HIGH);
  delay(5);
  digitalWrite(11,LOW);
}

失敗例

画面がチラつきます。

 

チラつく様子。動画前半の部分


www.youtube.com

 

次に作ったのが

int count = 0;
int x_pos = 0;
int y_pos = 0;
boolean x_dir = false;
boolean y_dir = false;
int racket_pos = 5;        // ラケットの位置
int racket_size = 6;        // ラケットのサイズ
boolean beep_flag = false;
int beep_count = 0;
boolean game_flag = true;

void setup() {
  // put your setup code here, to run once:
  pinMode(2,OUTPUT);
  pinMode(3,OUTPUT);
  pinMode(4,OUTPUT);
  pinMode(5,OUTPUT);
  pinMode(6,OUTPUT);
  pinMode(7,INPUT_PULLUP);
  pinMode(8,INPUT_PULLUP);
  pinMode(9,INPUT_PULLUP);
  pinMode(10,INPUT_PULLUP);
  pinMode(11,OUTPUT);
 }

void loop() {
  // put your main code here, to run repeatedly:
  for (int i = 0;i < 16;i++) {
    for (int j = 0;j < 16;j++) {
      digitalWrite(2,LOW);

      // ボールを描く
      if (j == x_pos && i == y_pos)
        digitalWrite(2,HIGH);

      // ラケットを描く
      if (i == 15) {          // 1番下の16段目
        if (racket_pos <= j && j < racket_size + racket_pos)
        digitalWrite(2,HIGH);
      }
      digitalWrite(4,HIGH);
      digitalWrite(4,LOW);
    }
    digitalWrite(5,HIGH);
    digitalWrite(5,LOW);
  }
  digitalWrite(6,HIGH);
  digitalWrite(6,LOW);

  if (beep_flag) {
    beep_count--;
    if (beep_count == 0) { // 0になると音を止める
      beep_flag = false;
      digitalWrite(11,LOW);
    }
  }
  
  count++;
  if (count > 10) {
    count = 0;
    
    // ボールの位置 x軸
    if (!x_dir)
      x_pos++;
    else
      x_pos--;
    if (x_pos > 14) {
      x_dir = true;
    }
    if (x_pos < 1) {
      x_dir = false;
    }

    // ボールの位置 y軸
    if (!y_dir)
      y_pos++;
    else
      y_pos--;
    if (y_pos == 14 && x_pos < racket_size + racket_pos && x_pos >= racket_pos) {
      y_dir = true;
      digitalWrite(11,HIGH); // ラケット音
      beep_count = 7;
      beep_flag = true;
    }
    if (y_pos < 1) {
      y_dir = false;
    }

    if (y_pos > 14 && game_flag) {
      digitalWrite(11,HIGH); // 終了音
      beep_count = 70;
      beep_flag = true;
      game_flag = false;
    }
    
    if (digitalRead(7) == 0) {  // サーブ
      x_pos = 0;
      y_pos = 0;
      game_flag = true;
    }

    if (digitalRead(8) == 0) {  // サーブ
      x_pos = 15;
      y_pos = 0;
      x_dir = true;
      game_flag = true;
    }

    // ラケットの位置
    if (digitalRead(9) == 0)
      if (racket_pos > 0)
        racket_pos--;         // 左へ移動

    if (digitalRead(10) == 0)
      if (racket_pos < 16 - racket_size)
        racket_pos++;         // 右へ移動
  }
}

動画の後半

 

画面のチラつきが無くなりました。

これで完成です。後はボール速度を変える、ラケットを小さくしていく等、改造して行って下さい。

 

次回、新しいゲームを作って行きます。

 

では、また。

 

mckeechan.hatenadiary.com

マイコンArduinoを使って電光掲示板を作る。

マイコンArduinoを使って電光掲示板を作る。

 

続き

今回はゲームのプログラムを作って行きます。

 

最初にまだスイッチの動作確認をしていないので簡単な確認用プログラムを作りました。

 

入力のテスト用プログラム

int x_num = -1;
int y_num = -1;

void setup() {
  // put your setup code here, to run once:
  pinMode(2,OUTPUT);
  pinMode(3,OUTPUT);
  pinMode(4,OUTPUT);
  pinMode(5,OUTPUT);
  pinMode(6,OUTPUT);
  pinMode(7,INPUT_PULLUP);
  pinMode(8,INPUT_PULLUP);
  pinMode(9,INPUT_PULLUP);
  pinMode(10,INPUT_PULLUP);
 }

void loop() {
  // put your main code here, to run repeatedly:
  for (int i = 0;i < 16;i++) {
    for (int j = 0;j < 16;j++) {
      digitalWrite(2,LOW);
      if (i == y_num && j == x_num)
        digitalWrite(2,HIGH);
      digitalWrite(4,HIGH);
      digitalWrite(4,LOW);
    }
    digitalWrite(5,HIGH);
    digitalWrite(5,LOW);
  }
  digitalWrite(6,HIGH);
  digitalWrite(6,LOW);
  
  x_num = -1;
  y_num = -1;
  
  if (digitalRead(7) == 0) { // 左上のボタン
    x_num = 0;
    y_num = 0;
  }
  
  if (digitalRead(8) == 0) { // 右上のボタン
    x_num = 15;
    y_num = 0;
  }
  
  if (digitalRead(9) == 0) { // 左下のボタン
    x_num = 0;
    y_num = 15;
  }
  
  if (digitalRead(10) == 0) { // 右下のボタン
    x_num = 15;
    y_num = 15;
  }
}

テストの様子


www.youtube.com

 

次はもう3回目になりますがテニスを作って行きます。

 

今回のプログラム

int count = 0;
int x_pos = 0;
int y_pos = 0;
boolean x_dir = false;
boolean y_dir = false;
int racket_pos = 5;        // ラケットの位置
int racket_size = 6;        // ラケットのサイズ

void setup() {
  // put your setup code here, to run once:
  pinMode(2,OUTPUT);
  pinMode(3,OUTPUT);
  pinMode(4,OUTPUT);
  pinMode(5,OUTPUT);
  pinMode(6,OUTPUT);
  pinMode(7,INPUT_PULLUP);
  pinMode(8,INPUT_PULLUP);
  pinMode(9,INPUT_PULLUP);
  pinMode(10,INPUT_PULLUP);
 }

void loop() {
  // put your main code here, to run repeatedly:
  for (int i = 0;i < 16;i++) {
    for (int j = 0;j < 16;j++) {
      digitalWrite(2,LOW);

      // ボールを描く
      if (j == x_pos && i == y_pos)
        digitalWrite(2,HIGH);

      // ラケットを描く
      if (i == 15) {          // 1番下の16段目
        if (racket_pos <= j && j < racket_size + racket_pos)
        digitalWrite(2,HIGH);
      }
      digitalWrite(4,HIGH);
      digitalWrite(4,LOW);
    }
    digitalWrite(5,HIGH);
    digitalWrite(5,LOW);
  }
  digitalWrite(6,HIGH);
  digitalWrite(6,LOW);
  
  count++;
  if (count > 10) {
    count = 0;
    
    // ボールの位置 x軸
    if (!x_dir)
      x_pos++;
    else
      x_pos--;
    if (x_pos > 14) {
      x_dir = true;
    }
    if (x_pos < 1) {
      x_dir = false;
    }

    // ボールの位置 y軸
    if (!y_dir)
      y_pos++;
    else
      y_pos--;
    if (y_pos == 14 && x_pos < racket_size + racket_pos && x_pos >= racket_pos) {
      y_dir = true;
    }
    if (y_pos < 1) {
      y_dir = false;
    }

    if (digitalRead(7) == 0) {  // サーブ
      x_pos = 0;
      y_pos = 0;
    }

    if (digitalRead(8) == 0) {  // サーブ
      x_pos = 15;
      y_pos = 0;
      x_dir = true;
    }

    // ラケットの位置
    if (digitalRead(9) == 0)
      if (racket_pos > 0)
        racket_pos--;         // 左へ移動

    if (digitalRead(10) == 0)
      if (racket_pos < 16 - racket_size)
        racket_pos++;         // 右へ移動
  }
}

前回のテニスをベースに少し書き替えて


www.youtube.com

あっさりと動いてしまいました。

 

今回はゲーム機と言うことなので音は必須だと思います。

 

そこで次回は音が出る様に改造していきます。

 

では、また。

 

mckeechan.hatenadiary.com

マイコンArduinoを使って電光掲示板を作る。

 

 

マイコンArduinoを使って電光掲示板を作る。

 

続き

今回はゲーム機を仕上げて行きます。

 

Arduino nanoに直接半田付けしていきます。

 

USBケーブルもコネクターは利用せずに直接半田付け

ここが一番苦労した所(こて先が太い)

 

タクトスイッチからの配線

入力スイッチはGNDを共通に接続して信号線をD7~D10に接続

 

蓋をして完成

かっこいい!

試しに前回の文字表示プログラムを実行



次回はゲームのプログラムを作って行きます。

 

では、また。

 

mckeechan.hatenadiary.com

マイコンArduinoを使って電光掲示板を作る。

マイコンArduinoを使って電光掲示板を作る。

 

続き

今回はゲーム機を作って行きます。

 

プログラムだけでは無くケースも作りゲーム機として単体で遊べる様に作って行きます。

 

3dプリンターでケースを作って行きます。

 

Fusion 360でデザインしました。

作りやすい様に角型にしています。

 

下面

 

上面

 

押しボタン

4個作ります。

 

Curaを使って印刷しました。延べ時間は20時間位

印刷した部品はケース上面、ケース下面、押しボタン4個です。

 

造形した部品

木片はタクトスイッチのブレ止め

 

タクトスイッチ4個搭載

タクトスイッチをユニバーサル基板に半田付け

基板自体はケースにホットボンドで固定

 

仮組した所

押しボタンは前面に2個、上面に2個

 

合わせてねじ止め

LEDモジュールを4本のネジでねじ止め。

 

次回、マイコンを収め配線をして行きます。

 

では、また。

 

mckeechan.hatenadiary.com

マイコンArduinoを使って電光掲示板を作る。

マイコンArduinoを使って電光掲示板を作る。

 

続き

今回は、文字の表示に挑戦していきます。

 

が、その前に

ネクター5番ピン(pinMode(6,OUTPUT);)の制御信号が分かりました。

前回、自動で点灯ラインが順次変化していると書きましたが稀に段ずれが起こりズレたまま表示が続きます。試しに下記プログラムに書き換えたところ全くズレが起こらなくなりました。5番ピンが順送りのリセットをしている様です。

不明ピンは残り1つとなりました。

 

太字を追加

int num = 0;
void setup() {
  // put your setup code here, to run once:
  pinMode(2,OUTPUT);
  pinMode(3,OUTPUT);
  pinMode(4,OUTPUT);
  pinMode(5,OUTPUT);
  pinMode(6,OUTPUT);

  digitalWrite(2,LOW);
  digitalWrite(3,LOW);
  digitalWrite(4,LOW);
  digitalWrite(5,LOW);
  digitalWrite(6,LOW);
 }

void loop() {
  // put your main code here, to run repeatedly:
   for (int i = 0;i < 16;i++) {
    digitalWrite(2,LOW);
    if (num == 5 && i == 5)
      digitalWrite(2,HIGH);
    digitalWrite(4,HIGH);
    digitalWrite(4,LOW);
  }
  digitalWrite(5,HIGH);
  digitalWrite(5,LOW);
  num++;
  if (num > 15) {
    num = 0;
    digitalWrite(6,HIGH);
    digitalWrite(6,LOW);
  }
}

これで完璧に動作しています。

 

続いてメインの文字の表示に挑戦していきます。

と言っても何度も作っているので少し手を加えるだけでOKです。

 

横向き反転で良いならこんな感じ

short data_hex[] = {0x0000, 0x0200, 0x0200, 0x3ff8, 0x0200, 0x0220, 0x03f0, 0x0628,
                    0x1a44, 0x1244, 0x2284, 0x2304, 0x260c, 0x3d18, 0x0070, 0x0000,
                    0x0000, 0x0000, 0x0000, 0x2010, 0x2018, 0x2008, 0x200c, 0x2004,
                    0x3004, 0x3004, 0x1186, 0x1106, 0x1b00, 0x0e00, 0x0400, 0x0000};

void setup() {
  // put your setup code here, to run once:
  pinMode(2,OUTPUT);
  pinMode(3,OUTPUT);
  pinMode(4,OUTPUT);
  pinMode(5,OUTPUT);
  pinMode(6,OUTPUT);
 }

void loop() {
  // put your main code here, to run repeatedly:
  for (int i = 0;i < 16;i++) {
    for (int j = 0;j < 16;j++) {
      digitalWrite(2,LOW);
      if ((data_hex[j] & 0x8000 >> i) != 0)
        digitalWrite(2,HIGH);
      digitalWrite(4,HIGH);
      digitalWrite(4,LOW);
    }
    digitalWrite(5,HIGH);
    digitalWrite(5,LOW);
  }
  digitalWrite(6,HIGH);
  digitalWrite(6,LOW);
}

 

制御ピンが少ないので解ってしまえば楽勝かな。

今までで1番簡単に表示出来てしまう。

 

文字数1文字なので電光掲示板としては物足りない。

(OUTコネクターが有るのでモジュールが有れば繋ぐことは可能だと思います。)

 

そこで次回からはゲーム機を作って行きます。

 

では、また。

 

mckeechan.hatenadiary.com

マイコンArduinoを使って電光掲示板を作る。

 

 

マイコンArduinoを使って電光掲示板を作る。

 

続き

前回のプログラムを少しずつ変更して変化を見て行きます。

 

前回のプログラム

void setup() {
  // put your setup code here, to run once:
  pinMode(2,OUTPUT);
  pinMode(3,OUTPUT);
  pinMode(4,OUTPUT);
  pinMode(5,OUTPUT);
  pinMode(6,OUTPUT);

  digitalWrite(2,LOW);
  digitalWrite(3,LOW);
  digitalWrite(4,LOW);
  digitalWrite(5,LOW);
  digitalWrite(6,LOW);
 }

void loop() {
  // put your main code here, to run repeatedly:

   digitalWrite(2,HIGH); // データをセット
   for (int i = 0;i < 16;i++) {
    digitalWrite(4,HIGH); // クロック
    digitalWrite(4,LOW);  // クロック
  }
  digitalWrite(5,HIGH);   // ラッチ
  digitalWrite(5,LOW);    // ラッチ
}

これで全点灯しました。

 

この中のvoid loop()に手を加えてみます。

  digitalWrite(2,HIGH); // データをセット
  for (int i = 0;i < 16;i++) {
    digitalWrite(4,HIGH); // クロック
    digitalWrite(4,LOW);  // クロック
  }

  から

  for (int i = 0;i < 16;i++) {
    digitalWrite(2,LOW); // データをセット
    if (i == 5)
      digitalWrite(2,HIGH); // データをセット
    digitalWrite(4,HIGH); // クロック
    digitalWrite(4,LOW);  // クロック
  }

iが5の時だけHIGHをセット

すると6列目のみ点灯します。5を他の数字に変えてみると数字に応じて列が変わります。列の制御は出来てるみたいです。

 

次は段の方を見て行きます。

int num = 0;

void setup() {
  // put your setup code here, to run once:
  pinMode(2,OUTPUT);
  pinMode(3,OUTPUT);
  pinMode(4,OUTPUT);
  pinMode(5,OUTPUT);
  pinMode(6,OUTPUT);

  digitalWrite(2,LOW);
  digitalWrite(3,LOW);
  digitalWrite(4,LOW);
  digitalWrite(5,LOW);
  digitalWrite(6,LOW);
 }

void loop() {
  // put your main code here, to run repeatedly:

   for (int i = 0;i < 16;i++) {
    digitalWrite(2,LOW); // データをセット
    if (num == 5)
      digitalWrite(2,HIGH); // データをセット

    digitalWrite(4,HIGH); // クロック
    digitalWrite(4,LOW);  // クロック
  }
  digitalWrite(5,HIGH);   // ラッチ
  digitalWrite(5,LOW);    // ラッチ

  num++;

  if (num > 15)

    num = 0;
}

numが5の時だけHIGHをセット

今度は6段目のみ点灯します。5を他の数字に変えてみると数字に応じて段が変わります。段の制御は出来てるみたいです。

 

更に手を加えて

 if (num == 5) → if (num == 5 && i == 5)

で任意の1点のみ点灯出来ます。

 

推測ですが、ここから見えてくるのは16回クロック信号を受け取ると自動で点灯ラインが順次変化するのではないでしょうか。

 

縦横が制御できていると言う事はこのまま文字の表示も可能な様な

ただ、一つ疑問に思うのは他の2本は何に使われているのかな?

 

次回は文字の表示に挑戦していきます。

 

では、また。

 

mckeechan.hatenadiary.com