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

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

 

続き

今回はEEPROMに書き込んでデータが記憶できるかに挑戦していきます。

 

前回のプログラムを基に作ったテスト用プログラム

#include <EEPROM.h>
byte address = {5, 4, 3, 2};      // アドレスは扱いやすい様に配列で持つ
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};
int pos = 0;
short inData = 0;
short value = 0;
boolean toggle = false;
boolean eep = false;
boolean completion = false;

void setup() {
  for (int i = 2; i < 13; i++) {
    pinMode(i, OUTPUT);             // 各ピンの設定 全てアウトプット
  }
  pinMode(13,INPUT_PULLUP);
  pinMode(14,INPUT_PULLUP);

  digitalWrite(11,LOW); // SE     L 自動でRAM切り替わり
  digitalWrite(12,LOW); // A/BB   書き込み用RAM選択
  digitalWrite(6,LOW); // GREEN  緑データ
  digitalWrite(7,LOW); // CLK    クロック
  digitalWrite(8,LOW); // WE     書き込み信号 Hで書き込み
  digitalWrite(9,LOW); // RED    赤データ
  digitalWrite(10,LOW);// ALE   アドレスラッチ Hで有効
  Serial.begin(19200);

  if (digitalRead(13) == 0) {
    eep = true;
  }
}

void loop() {
  if (Serial.available() > 0) {
    inData = Serial.read();
    if (!toggle) {
      value = inData * 256;
    }
    else {
      value |= inData;
      data_hex[pos++] = value;
    }
    toggle = !toggle;
  }

  if (pos == 32 && !completion) {
    for (int i = 0;i < pos;i++) {
      EEPROM.put(i * 2, data_hex[i]);
    }
    completion = true;
  }

  if (eep)
    eep_disp();
  else
    disp();
}

void eep_disp(){
  for (int i = 0; i < 16; i++) {                        // アドレス0~15
    for (int j = 0; j < sizeof(address); j++)
      if ((i & 0x1 << j) != 0)                          // address[0]~address[3]にビットをセット
        digitalWrite(address[j], HIGH);
      else
        digitalWrite(address[j], LOW);
        
    for (int k = 0;k < 32;k++) {
      digitalWrite(9,LOW); // RED    赤データ
      if ((EEPROM.read(k * 2) + EEPROM.read(k * 2 + 1) * 256 & 0x1 << i) != 0) {
        digitalWrite(9,HIGH); // RED    赤データ
      }
      shift_clock(); // クロック
    }
    write_ale_we(); // 書き込み操作 関数にまとめて有る
  }
}

void disp() {
  for (int i = 0; i < 16; i++) {                        // アドレス0~15
    for (int j = 0; j < sizeof(address); j++)
      if ((i & 0x1 << j) != 0)                          // address[0]~address[3]にビットをセット
        digitalWrite(address[j], HIGH);
      else
        digitalWrite(address[j], LOW);
        
    for (int k = 0;k < 32;k++) {
      if ((data_hex[k] & 0x8000 >> i) != 0)
        digitalWrite(9,HIGH); // RED    赤データ              // データのセット
      else
        digitalWrite(9,LOW); // RED    赤データ              // データのセット
      shift_clock(); // クロック
    }
    
    write_ale_we(); // 書き込み操作 関数にまとめて有る
  }
}

void shift_clock() {
  digitalWrite(7,HIGH); // クロック
  digitalWrite(7,LOW);  // クロック
}

void write_ale_we() {
  digitalWrite(10,HIGH);// ALE   アドレスラッチ Hで有効
  digitalWrite(8,HIGH); // WE     書き込み信号 Hで書き込み
  digitalWrite(8,LOW);  // WE     書き込み信号 Hで書き込み
  digitalWrite(10,LOW); // ALE   アドレスラッチ Hで有効
}

太字が追加部分

boolean eepはdigitalRead(13)が立ち上げ時に押されてるとeepromモードで表示

boolean completionは1回のみ書き込む為

eep_disp()のEEPROM.readで読み込み。バイト単位なので少しややこしい

 

テストの様子


www.youtube.com

上手く行きました。

再起動後にもeepromモードで「かき」と表示されます。

 

次回文字数を増やしてスクロール表示も出来るように改造していきます。

 

では、また。

 

 

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

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

 

続き

今回はandroid端末との接続でデータの書換えが出来るかを試していきます。

 

android端末とUSBケーブルを介してシリアル通信するプログラム

byte address = {5, 4, 3, 2};      // アドレスは扱いやすい様に配列で持つ
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};
int pos = 0;
short inData = 0;
short value = 0;
boolean toggle = false;

void setup() {
  for (int i = 2; i < 13; i++) {
    pinMode(i, OUTPUT);             // 各ピンの設定 全てアウトプット
  }

  digitalWrite(11,LOW); // SE     L 自動でRAM切り替わり
  digitalWrite(12,LOW); // A/BB   書き込み用RAM選択
  digitalWrite(6,LOW); // GREEN  緑データ
  digitalWrite(7,LOW); // CLK    クロック
  digitalWrite(8,LOW); // WE     書き込み信号 Hで書き込み
  digitalWrite(9,LOW); // RED    赤データ
  digitalWrite(10,LOW);// ALE   アドレスラッチ Hで有効
  Serial.begin(19200);
}

void loop() {
  if (Serial.available() > 0) {
    inData = Serial.read();
    if (!toggle) {
      value = inData * 256;
    }
    else {
      value |= inData;
      data_hex[pos++] = value;
    }
    toggle = !toggle;
  }

  disp();
}

void disp() {
  for (int i = 0; i < 16; i++) {                        // アドレス0~15
    for (int j = 0; j < sizeof(address); j++)
      if ((i & 0x1 << j) != 0)                          // address[0]~address[3]にビットをセット
        digitalWrite(address[j], HIGH);
      else
        digitalWrite(address[j], LOW);
        
    for (int k = 0;k < 32;k++) {
      if ((data_hex[k] & 0x8000 >> i) != 0)
        digitalWrite(9,HIGH); // RED    赤データ              // データのセット
      else
        digitalWrite(9,LOW); // RED    赤データ              // データのセット
      shift_clock(); // クロック
    }
    
    write_ale_we(); // 書き込み操作 関数にまとめて有る
  }
}

void shift_clock() {
  digitalWrite(7,HIGH); // クロック
  digitalWrite(7,LOW);  // クロック
}

void write_ale_we() {
  digitalWrite(10,HIGH);// ALE   アドレスラッチ Hで有効
  digitalWrite(8,HIGH); // WE     書き込み信号 Hで書き込み
  digitalWrite(8,LOW);  // WE     書き込み信号 Hで書き込み
  digitalWrite(10,LOW); // ALE   アドレスラッチ Hで有効
}

太字の部分を追加

d0,d1はシリアルで使うのでd11,d12に変更

loop()の中でシリアルデータを受信してデータを受け取ったらdata_hex[]を書き換える

 

実験の様子


www.youtube.com

「かき」と書き替えられました。文字が逆さまなのはご愛敬。

 

Androidのアプリ

アプリはusb-serial-for-android(githubで入手)のライブラリを使って作りました。

 

これで書き替えは出来ました。

ただ、このままでは電源が落ちるとデータが消滅します。

 

そこで次回、Arduino Nanoに搭載せれているEEPROMに書き込んでデータが記憶できる様に改造して行きます。

 

では、また。

 

 

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

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

 

続き

android端末との接続でデータの書換えが出来る電光掲示板を作って行きます。

 

それに向けてプログラムしやすい様に最小構成で電光掲示板を作りました。

 

プログラム

byte address = {5, 4, 3, 2};      // アドレスは扱いやすい様に配列で持つ
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() {
  for (int i = 0; i < 11; i++) {
    pinMode(i, OUTPUT);             // 各ピンの設定 全てアウトプット
  }

  digitalWrite(0,LOW); // SE     L 自動でRAM切り替わり
  digitalWrite(1,LOW); // A/BB   書き込み用RAM選択
  digitalWrite(6,LOW); // GREEN  緑データ
  digitalWrite(7,LOW); // CLK    クロック
  digitalWrite(8,LOW); // WE     書き込み信号 Hで書き込み
  digitalWrite(9,LOW); // RED    赤データ
  digitalWrite(10,LOW);// ALE   アドレスラッチ Hで有効
}

void loop() {
  disp();
}

void disp() {
  for (int i = 0; i < 16; i++) {                        // アドレス0~15
    for (int j = 0; j < sizeof(address); j++)
      if ((i & 0x1 << j) != 0)                          // address[0]~address[3]にビットをセット
        digitalWrite(address[j], HIGH);
      else
        digitalWrite(address[j], LOW);
        
    for (int k = 0;k < 32;k++) {
      if ((data_hex[k] & 0x8000 >> i) != 0)
        digitalWrite(9,HIGH); // RED    赤データ              // データのセット
      else
        digitalWrite(9,LOW); // RED    赤データ              // データのセット
      shift_clock(); // クロック
    }
    
    write_ale_we(); // 書き込み操作 関数にまとめて有る
  }
}

void shift_clock() {
  digitalWrite(7,HIGH); // クロック
  digitalWrite(7,LOW);  // クロック
}

void write_ale_we() {
  digitalWrite(10,HIGH);// ALE   アドレスラッチ Hで有効
  digitalWrite(8,HIGH); // WE     書き込み信号 Hで書き込み
  digitalWrite(8,LOW);  // WE     書き込み信号 Hで書き込み
  digitalWrite(10,LOW); // ALE   アドレスラッチ Hで有効
}

 

単色のスクロール無しで2文字のみの表示

 

このプログラムを基にandroid端末との接続機能を構築していきます。

 

今回利用を予定しているOTGケーブル

 

王道で行くならフォントデータをROMに持ってアクセスする所ですがすでにいくつかのサイトで紹介されているので文字データそのものを書き込むプログラムを作ります。

 

次回、USBケーブルでのやり取りのプログラムを作って行きます。

 

では、また。

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

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

 

続き

ネクターが届くのを待っているのですが来る気配なしです。

待ちきれずに直接コードを半田付けして実験に臨む事にしました。

 

コードを半田付けした様子

狭い隙間に端子が有ったので半田ごてがコネクターに当たりまくり!

半田付け自体も怪しい(一応テスターでショート無しは確認)

 

ピンアサインは前回言っていた通りSLX-5024と同じでプログラムもそのまま動きました。

 

slx_5024用プログラム
byte address = {5, 4, 3, 2};      // アドレスは扱いやすい様に配列で持つ
int pos = 0;
int count = 0;
int scroll = 0;
int scroll_speed = 5;
                    // 2文字では寂しいので5文字に変更 "あいうえお"
short data_hex
= {0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
                    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
                    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
                    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
                    0x0000, 0x0200, 0x0200, 0x3ffc, 0x0200, 0x03e0, 0x0e38, 0x1a2c,
                    0x3244, 0x22c4, 0x2384, 0x2304, 0x3e0c, 0x1878, 0x00e0, 0x0000,
                    0x0000, 0x0000, 0x2000, 0x2018, 0x2008, 0x200c, 0x2004, 0x2006,
                    0x2006, 0x3006, 0x3102, 0x3300, 0x1e00, 0x0e00, 0x0000, 0x0000,
                    0x0000, 0x0fc0, 0x00f0, 0x0000, 0x0000, 0x1ff0, 0x3818, 0x0018,
                    0x0008, 0x0018, 0x0018, 0x0030, 0x0070, 0x03c0, 0x0700, 0x0000,
                    0x0000, 0x0fe0, 0x00e0, 0x0000, 0x1fe0, 0x1ff0, 0x00c0, 0x0180,
                    0x03c0, 0x07c0, 0x0c40, 0x1840, 0x3040, 0x207e, 0x0000, 0x0000,
                    0x0000, 0x0200, 0x0218, 0x7fec, 0x0206, 0x0200, 0x0200, 0x0ff8,
                    0x1a0c, 0x2204, 0x6204, 0x6204, 0x220c, 0x3ef8, 0x0c00, 0x0000,
                    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
                    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
                    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
                    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000};
// カラーを配列で持つ                    
byte color[] = {1, 2, 3, 2, 1}; // 1,赤 2,緑 3,橙

void setup() {
  for (int i = 0; i < 11; i++) {
    pinMode(i, OUTPUT);             // 各ピンの設定 全てアウトプット
  }
  pinMode(11, INPUT_PULLUP);
  pinMode(12, INPUT_PULLUP);
  
  digitalWrite(0,LOW); // SE     L 自動でRAM切り替わり
  digitalWrite(1,LOW); // A/BB   書き込み用RAM選択
  digitalWrite(6,LOW); // GREEN  緑データ
  digitalWrite(7,LOW); // CLK    クロック
  digitalWrite(8,LOW); // WE     書き込み信号 Hで書き込み
  digitalWrite(9,LOW); // RED    赤データ
  digitalWrite(10,LOW); // ALE   アドレスラッチ Hで有効
  change();
}

void loop() {
  for (int i = 0; i < 16; i++) {                        // アドレス0~15
    for (int j = 0; j < sizeof(address); j++)
      if ((i & 0x1 << j) != 0)                          // address[0]~address[3]にビットをセット
        digitalWrite(address[j], HIGH);
      else
        digitalWrite(address[j], LOW);
        
    for (int k = 0;k < 32;k++) {
      digitalWrite(6,LOW); // GREEN  緑データ
      digitalWrite(9,LOW); // RED    赤データ
      if ((data_hex[k + scroll] & 0x8000 >> i) != 0) {
        int color_pos = (k + scroll - 32) / 16;
        if (color_pos < 0) color_pos = 0;
        byte c = color[color_pos];
        if (c & 1)
          digitalWrite(9,HIGH); // RED    赤データ
        if (c & 2)
          digitalWrite(6,HIGH); // GREEN  緑データ
      }
      clock(); // クロック
    }
    
    write_ale_we(); // 書き込み操作 関数にまとめて有る
  }

  count++;
  if (count > scroll_speed) {
    count = 0;
    scroll ++;
    if (scroll > sizeof(data_hex) / 2 - 32)
      scroll = 0;
    pos++;
    if (pos > 15) {
      pos = 0;
    }

    // スピード可変
    if (digitalRead(11) == 0)
      if (scroll_speed > 0)
        scroll_speed--;

    if (digitalRead(12) == 0)
       if (scroll_speed < 10) 
        scroll_speed++;
  }
}

void write_ale_we() {
  digitalWrite(10,HIGH); // ALE   アドレスラッチ Hで有効
  digitalWrite(8,HIGH); // WE     書き込み信号 Hで書き込み
  digitalWrite(8,LOW); // WE     書き込み信号 Hで書き込み
  digitalWrite(10,LOW); // ALE   アドレスラッチ Hで有効
}

void clock() {
  digitalWrite(7,HIGH); // クロック
  digitalWrite(7,LOW);  // クロック
}

void clock_n(int n) {
  for (int i = 0;i < n;i++)
    clock();
}

void change() {
  short local_hex[sizeof(data_hex) / 2];          // sizeofの戻り値がバイト数なので2で割る

  // データをクリア
  for (int n = 0;n < sizeof(data_hex) / 2;n++) {  // sizeofの戻り値がバイト数なので2で割る
    local_hex[n] = 0;               // ビット数は不要 0で16ビット全て0
  }

  for (int i = 0;i < sizeof(data_hex) / 32;i++) {       // 32バイトで1文字
    for (int j = 0;j < 16;j++) {    // 16はデーター数
      for (int k = 0;k < 16;k++) {  // 16はビット数
        if ((data_hex[j + i * 16] & 0x8000 >> k) != 0)  // 横データを
          local_hex[k + i * 16] |= 0x8000 >> j;         // 縦データに
      }
    }
  }
  
  for (int n = 0;n < sizeof(data_hex) / 2;n++) {  // sizeofの戻り値がバイト数なので2で割る
    data_hex[n] = local_hex[n];     // 元に戻す
  }
}

SLX-5024用のプログラムを実行した様子


www.youtube.com

何の問題もなく表示されました。

 

今回はプログラムが完成してると言うことで違った方向に進めていきます。

 

android端末との接続でデータの書換えが出来る電光掲示板を作って行きます。

接続方法はUSB OTGケーブルを考えています。

 

では、また。

 

 

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

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

 

第4弾

今回から新しいLEDモジュールで進めていきます。

 

SLX-5040-71 と言う型番のモジュールです。

以前、扱ったSLX-5024とサイズ以外ほぼ同じではないかと思われます。

 

ドット数 16 × 32

サイズ 40mm × 80mm

 

表側

 

裏側

サイズは小さいがずっしりと重たい

ネクターピンの数も同じで恐らくピイアサインも同じかなぁ

 

ネクターを流用したい所ですがサイズが二回りほど小さいです。

そのまま使えたら言う事なしだったのに残念

 

と、言う事で配線類を作って行きます。

 

その前にコネクターを手に入れなければなりませんが近くの電子パーツ屋さんでは置いて無く(10ピンまでしか置いていないとの事)

型番zh12ピンをネットで調べて注文しました。

 

届いたらブレッドボード用に配線類を作って何時ものように実験して行きます。

 

では、また。

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

 

Arduinoをはじめようキット

Arduinoをはじめようキット

  • スイッチサイエンス
Amazon

 

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

 

続き

テトリスに挑戦の10回目は再スタート出来る様にプログラムを作って行きます。

 

上部で詰まると終了して再スタート出来るプログラム

おまけ機能 ボタンを押して強制的に落とすプログラムも追加

 

int x_pos = 6;
int y_pos = 0;
int select = 0;
int muki = 0;
int fall_speed_count = 0;
boolean rotate_flag = false;
boolean fixed_flag = false;
boolean start_flag = false;
int move_count_l = 0;
int move_count_r = 0;
int fixed_count = 0;
int fall_count = 0;
int left_count = 0;
int right_count = 0;
int rotate_count = 0;
short base_hex = {0x2004, 0x2004, 0x2004, 0x2004, 0x2004, 0x2004, 0x2004, 0x2004,
                    0x2004, 0x2004, 0x2004, 0x2004, 0x2004, 0x2004, 0x2004, 0x3ffc};
short data_hex = {0x2004, 0x2004, 0x2004, 0x2004, 0x2004, 0x2004, 0x2004, 0x2004,
                    0x2004, 0x2004, 0x2004, 0x2004, 0x2004, 0x2004, 0x2004, 0x3ffc};
short block[7][4] = {{0x0660, 0x0660, 0x0660, 0x0660},
                    {0x4444, 0x00f0, 0x2222, 0x0f00},
                    {0x2640, 0x0c60, 0x0264, 0x0630},
                    {0x4620, 0x06c0, 0x0462, 0x0360},
                    {0x0644, 0x0470, 0x2260, 0x0e20},
                    {0x0622, 0x0740, 0x4460, 0x02e0},
                    {0x04e0, 0x0262, 0x0720, 0x4640}};
short disp_hex[16];
short fall_hex[16];
short left_hex[16];
short right_hex[16];
short rotate_hex[16];
              
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);
  Serial.begin(9600);
}

void loop() {
  // put your main code here, to run repeatedly:
  if (start_flag)
    restart();
  else
    move_down();
  move_block();
  rotate();
  fall();
  data_make();
  disp();
 }

void restart(){
  if (digitalRead(8) == 0){
    for (int i = 0;i < 16;i++)
      rotate_hex[i] = right_hex[i] = left_hex[i] = fall_hex[i] = disp_hex[i] = data_hex[i] = base_hex[i];
    x_pos = 6;
    y_pos = 0;
    select = 0;
    muki = 0;
    fall_speed_count = 0;
    rotate_flag = false;
    move_count_l = 0;
    move_count_r = 0;

    fixed_flag = false;
    start_flag = false;
    fixed_count = 0;
    fall_count = 0;
    left_count = 0;
    right_count = 0;
    rotate_count = 0;
    start_flag = false;
  }
}

void move_down(){
  if (digitalRead(8) == 0){
    fall();
    fall();
    fall();
  }
}

boolean full_line_check(){
  for (int i = 0;i < 15;i++){
    if (disp_hex[i] == 0x3ffc){
      disp_hex[0] = 0x2004;
      for (int j = i;j > 0;j--)
        disp_hex[j] = disp_hex[j - 1];
      fixed_count = fixed_count - 10;
    }
  }
}

boolean fall_check(){
  if (fall_count == 46 + fixed_count)
    return true;
  return false;
}

boolean left_check(){
  if (left_count == 46 + fixed_count)
    return true;
  return false;
}

boolean right_check(){
  if (right_count == 46 + fixed_count)
    return true;
  return false;
}

boolean rotate_check(){
  if (rotate_count == 46 + fixed_count)
    return true;
  return false;
}

void move_block(){
  if (digitalRead(9) == 0){
    move_count_l++;
    if (move_count_l > 30){
      move_count_l = 0;
      if (left_check())
        x_pos++;
    }
  }
  else
    move_count_l = 30;
    
  if (digitalRead(10) == 0){
    move_count_r++;
    if (move_count_r > 30){
      move_count_r = 0;
      if (right_check())
        x_pos--;
    }
  }
  else
    move_count_r = 30;
}

void rotate(){
  if (digitalRead(7) == 0){
    if(!rotate_flag){
      rotate_flag = true;
      if(rotate_check())
        muki++;
      if (muki > 3)
        muki = 0;
    }
  }
  else {
    rotate_flag = false;
  }
}

void fall(){
  fall_speed_count++;
  if (fall_speed_count > 100){
    fall_speed_count = 0;
    if(fall_check())
      y_pos++;
    else
      fixed_flag = true;
  }
}

void data_make(){
  if (fixed_flag){
    if (y_pos < 1){
      start_flag = true;
      return;
    }
    full_line_check();
    for (int i = 0;i < 16;i++)
      data_hex[i] = disp_hex[i];
    fixed_count = fixed_count + 4;
    x_pos = 6;
    y_pos = 0;
    select++;
    if (select > 6)
      select = 0;
  }
  fixed_flag = false;
  
  for (int i = 0;i < 16;i++)
    rotate_hex[i] = right_hex[i] = left_hex[i] = fall_hex[i] = disp_hex[i] = data_hex[i];
  int d = muki + 1;
  if (d > 3)
    d = 0;
  for (int i = 0;i < 4;i++){
    disp_hex[i + y_pos] |= ((block[select][muki] >> 4 * i) & 0xf) << x_pos;
    fall_hex[i + y_pos + 1] |= ((block[select][muki] >> 4 * i) & 0xf) << x_pos;
    left_hex[i + y_pos] |= ((block[select][muki] >> 4 * i) & 0xf) << x_pos + 1;
    right_hex[i + y_pos] |= ((block[select][muki] >> 4 * i) & 0xf) << x_pos - 1;
    rotate_hex[i + y_pos] |= ((block[select][d] >> 4 * i) & 0xf) << x_pos;
  }
}

void disp(){
  fall_count = 0;
  left_count = 0;
  right_count = 0;
  rotate_count = 0;
  for (int i = 0;i < 16;i++) {
    for (int j = 0;j < 16;j++) {
      digitalWrite(2,LOW);
      if ((disp_hex[i] & 0x8000 >> j) != 0){
        digitalWrite(2,HIGH);
      }
      if ((fall_hex[i] & 0x8000 >> j) != 0){
        fall_count++;
      }
      if ((left_hex[i] & 0x8000 >> j) != 0){
        left_count++;
      }
      if ((right_hex[i] & 0x8000 >> j) != 0){
        right_count++;
      }
      if ((rotate_hex[i] & 0x8000 >> j) != 0){
        rotate_count++;
      }
      digitalWrite(4,HIGH);
      digitalWrite(4,LOW);
    }
    digitalWrite(5,HIGH);
    digitalWrite(5,LOW);
  }
  digitalWrite(6,HIGH);
  digitalWrite(6,LOW);
}

太字が追加部分

 

完成したテトリスで遊んでいる様子


www.youtube.com

 

入力ボタンを1個追加して再スタート機能の追加

base_hex[]を使ってデータの初期化

ゲーム中は再スタートボタンをブロックの強制落下に利用しています。

 

今回の10回で終了となりました。

如何だったでしょうか。

ゆっくり進めたので分かり易かったのでは無いかと思います。

 

次のシリーズをお楽しみに!

 

では、また。

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

 

 

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

 

続き

テトリスに挑戦の9回目は横1列揃うと1段落とすプログラムを作って行きます。

 

横1列揃うと1段落とすプログラム

 

int x_pos = 6;
int y_pos = 0;
int select = 6;
int muki = 0;
int fall_speed_count = 0;
boolean rotate_flag = false;
boolean fixed_flag = false;
int move_count_l = 0;
int move_count_r = 0;
int fixed_count = 0;
int fall_count = 0;
int left_count = 0;
int right_count = 0;
int rotate_count = 0;
short data_hex[] = {0x2004, 0x2004, 0x2004, 0x2004, 0x2004, 0x2004, 0x2004, 0x2004,
                    0x2004, 0x2004, 0x2004, 0x2004, 0x2004, 0x2004, 0x2004, 0x3ffc};
short block[7][4] = {{0x0660, 0x0660, 0x0660, 0x0660},
                    {0x4444, 0x00f0, 0x2222, 0x0f00},
                    {0x2640, 0x0c60, 0x0264, 0x0630},
                    {0x4620, 0x0630, 0x0462, 0x0360},
                    {0x0644, 0x0470, 0x2260, 0x0e20},
                    {0x0622, 0x0740, 0x4460, 0x02e0},
                    {0x04e0, 0x0262, 0x0720, 0x4640}};
short disp_hex[16];
short fall_hex[16];
short left_hex[16];
short right_hex[16];
short rotate_hex[16];
              
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(9,INPUT_PULLUP);
  pinMode(10,INPUT_PULLUP);
}

void loop() {
  // put your main code here, to run repeatedly:
  move_block();
  rotate();
  fall();
  data_make();
  disp();
 }

boolean full_line_check(){
  for (int i = 0;i < 15;i++){
    if (disp_hex[i] == 0x3ffc){
      disp_hex[0] = 0x2004;
      for (int j = i;j > 0;j--)
        disp_hex[j] = disp_hex[j - 1];
      fixed_count = fixed_count - 10;
    }
  }
}

boolean left_check(){
  if (left_count == 46 + fixed_count)
    return true;
  return false;
}

boolean right_check(){
  if (right_count == 46 + fixed_count)
    return true;
  return false;
}

void move_block(){
  if (digitalRead(9) == 0){
    move_count_l++;
    if (move_count_l > 30){
      move_count_l = 0;
      if (left_check())
        x_pos++;
    }
  }
  else
    move_count_l = 30;
  if (digitalRead(10) == 0){
    move_count_r++;
    if (move_count_r > 30){
      move_count_r = 0;
      if (right_check())
        x_pos--;
    }
  }
  else
    move_count_r = 30;
}

boolean rotate_check(){
  if (rotate_count == 46 + fixed_count)
    return true;
  return false;
}

void rotate(){
  if (digitalRead(7) == 0){
    if(!rotate_flag){
      rotate_flag = true;
      if(rotate_check())
        muki++;
      if (muki > 3)
        muki = 0;
    }
  }
  else {
    rotate_flag = false;
  }
}

boolean fall_check(){
  if (fall_count == 46 + fixed_count)
    return true;
  return false;
}

void fall(){
  fall_speed_count++;
  if (fall_speed_count > 100){
    fall_speed_count = 0;
    if(fall_check())
      y_pos++;
    else
      fixed_flag = true;
  }
}

void data_make(){
  if (fixed_flag){
    full_line_check();
    for (int i = 0;i < 16;i++)
      data_hex[i] = disp_hex[i];
    fixed_count = fixed_count + 4;
    x_pos = 6;
    y_pos = 0;
    select++;
    if (select > 6)
      select = 0;
  }
  fixed_flag = false;
  for (int i = 0;i < 16;i++)
    rotate_hex[i] = right_hex[i] = left_hex[i] = fall_hex[i] = disp_hex[i] = data_hex[i];
  int d = muki + 1;
  if (d > 3)
    d = 0;
  for (int i = 0;i < 4;i++){
    disp_hex[i + y_pos] |= ((block[select][muki] >> 4 * i) & 0xf) << x_pos;
    fall_hex[i + y_pos + 1] |= ((block[select][muki] >> 4 * i) & 0xf) << x_pos;
    left_hex[i + y_pos] |= ((block[select][muki] >> 4 * i) & 0xf) << x_pos + 1;
    right_hex[i + y_pos] |= ((block[select][muki] >> 4 * i) & 0xf) << x_pos - 1;
    rotate_hex[i + y_pos] |= ((block[select][d] >> 4 * i) & 0xf) << x_pos;
  }
}

void disp(){
  fall_count = 0;
  left_count = 0;
  right_count = 0;
  rotate_count = 0;
  for (int i = 0;i < 16;i++) {
    for (int j = 0;j < 16;j++) {
      digitalWrite(2,LOW);
      if ((disp_hex[i] & 0x8000 >> j) != 0)
        digitalWrite(2,HIGH);
      if ((fall_hex[i] & 0x8000 >> j) != 0)
        fall_count++;
      if ((left_hex[i] & 0x8000 >> j) != 0)
        left_count++;
      if ((right_hex[i] & 0x8000 >> j) != 0)
        right_count++;
      if ((rotate_hex[i] & 0x8000 >> j) != 0)
        rotate_count++;
      digitalWrite(4,HIGH);
      digitalWrite(4,LOW);
    }
    digitalWrite(5,HIGH);
    digitalWrite(5,LOW);
  }
  digitalWrite(6,HIGH);
  digitalWrite(6,LOW);
}

太字が追加部分

 

一段落ちている様子


www.youtube.com

 

data_make()の中からfull_line_check()へチェックに行きます。

上から順に揃っているかをチェックして揃っていればクリアします。

fixed_countも-10して1列分減らします。

 

次回は上まで詰まると再スタート出来る様にプログラムを作って行きます。

 

では、また。

 

mckeechan.hatenadiary.com