Meguru2238 が 2021年02月28日23時02分01秒 に編集
コメント無し
本文の変更
# 概要 M5StackシリーズのATOM Matrixを用いて起動する度にパターンの異なるライフゲームシミュレーションを表示するデバイスを作成する。 実現する機能は以下のとおりとする。 - 起動時にWiFiに接続し、現在日時を取得する。 - 起動後の一定時間(今回は5秒)は現在日時のうち月日時分秒を表示する。 - 現在日時表示後は毎秒ライフゲームのステップを進める。 - 盤面の全てのビットが消滅したことを判定可能とする。
# 余談:ライフゲームとは? 詳細はWikipedia[https://ja.wikipedia.org/wiki/%E3%83%A9%E3%82%A4%E3%83%95%E3%82%B2%E3%83%BC%E3%83%A0]を参照。 簡単に説明すると周囲の状態によって生命がどのような変化をするかをシミュレーションするセル・オートマトンの一種。
# 部品 - ATOM Matrix ( https://m5stack.com/collections/m5-atom/products/atom-matrix-esp32-development-kit ) - 任意でON/OFF可能なUSB Type-C電源 - 今回はATOM TailBat( https://m5stack.com/collections/m5-atom/products/atom-tailbat )を使用 # 接続 中核となるWiFi機能およびLED Matrix制御はATOM Matrixにて行うため、 電源のみATOM MatrixのUSB Type-Cコネクタに接続する # LED表示について 現在時刻を表示するにあたり、ATOM MatrixのUSB Type-Cコネクタを左側になるように置いた時に以下のように各値を配置した。 - 1行目:月 - 2行目:日 - 3行目:時 - 4行目:分 - 5行目:秒 なお、分および秒については1行あたりLEDが5個しかないため、そのまま表示すると0~31までしか表示できないため、 苦肉の策として1bit右シフトを行うことで範囲内に収めている。 # プログラム ```arduino:Atom_LifeGame #include <M5Atom.h> #include <WiFi.h> // Settings const char* ssid = "Your SSID"; const char* password = "Your Pass"; // Global bool map_now[5][5] = {0}; bool map_next[5][5] = {0}; void connectWiFi() { WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); } } void setTime() { struct tm timeInfo; char s[32]; configTime(9 * 3600L, 0, "ntp.nict.jp", "time.google.com", "ntp.jst.mfeed.ad.jp"); getLocalTime(&timeInfo); sprintf(s, "%02d/%02d %02d:%02d:%02d", timeInfo.tm_mon + 1, timeInfo.tm_mday, timeInfo.tm_hour, timeInfo.tm_min, timeInfo.tm_sec); setnextline(0, timeInfo.tm_mon + 1); setnextline(1, timeInfo.tm_mday); setnextline(2, timeInfo.tm_hour); setnextline(3, (timeInfo.tm_min / 2)); setnextline(4, (timeInfo.tm_sec / 2)); drawLED(map_next); Serial.println(s); delay(5000); } void setup() { M5.begin(true, false, true); Serial.begin(115200); delay(10); connectWiFi(); setTime(); } bool moveMap(bool src[5][5], bool dest[5][5]) { int i, j; bool ret = false; for(i = 0; i < 5; i++) { for(j = 0; j < 5; j++) { dest[i][j] = src[i][j]; src[i][j] = 0; if(dest[i][j] == true) { ret = true; } } } return ret; } void drawLED(bool ledmap[5][5]) { int i, j; M5.dis.clear(); for(i = 0; i < 5; i++) { for(j = 0; j < 5; j++) { if(ledmap[i][j] == true) { M5.dis.drawpix(i, j, CRGB::White); } } } } void drawRed() { int i, j; M5.dis.clear(); for(i = 0; i < 5; i++) { for(j = 0; j < 5; j++) { M5.dis.drawpix(i, j, CRGB::Red); } } } void setnextline(int line, int num) { Serial.println(num); if( (num & 0x01) != 0x00) { map_next[line][0] = true; } else { map_next[line][0] = false; } if( (num & 0x02) != 0x00) { map_next[line][1] = true; } else { map_next[line][1] = false; } if( (num & 0x04) != 0x00) { map_next[line][2] = true; } else { map_next[line][2] = false; } if( (num & 0x08) != 0x00) { map_next[line][3] = true; } else { map_next[line][3] = false; } if( (num & 0x10) != 0x00) { map_next[line][4] = true; } else { map_next[line][4] = false; } } int countDot(int i, int j) { int ret = 0; if((i != 0) && (j != 0)) { if(map_now[i-1][j-1] == true) ret++; } if((i != 0)) { if(map_now[i-1][j] == true) ret++; } if((i != 0) && (j != 4)) { if(map_now[i-1][j+1] == true) ret++; } if((j != 0)) { if(map_now[i][j-1] == true) ret++; } if((j != 4)) { if(map_now[i][j+1] == true) ret++; } if((i != 4) && (j != 0)) { if(map_now[i+1][j-1] == true) ret++; } if((i != 4) && (j != 0)) { if(map_now[i+1][j] == true) ret++; } if((i != 4) && (j != 4)) { if(map_now[i+1][j+1] == true) ret++; } return ret; } void loop() { int i, j; int ret; if(moveMap(map_next, map_now) == true) { for(i = 0; i < 5; i++) { for(j = 0; j < 5; j++) { ret = countDot(i, j); if(map_now[i][j] == false) { switch(ret) { case 3: map_next[i][j] = true; break; } } else { switch(ret) { case 2: case 3: map_next[i][j] = true; break; } } } } drawLED(map_next); } else { drawRed(); } delay(1000); M5.update(); } ``` # 動作 以下のTwitterページを参照 https://twitter.com/i/status/1366024248909647880 # 改善点 - 左上の1dot分については、1行目の値が月であるため取りうる値(1~12)において絶対に点灯しない状態になっている。 対して分および秒で1bitシフトで情報が欠落しているため、初期パターン配置を工夫することで全bitを使用することが できるようになる。 - 現在はWiFi接続情報埋め込みのため屋外で使用することができない。幸いにもATOM Matrixの外部接続ポートは 未使用であるため時刻取得をGPS等を用いることでWiFi環境に依存しなくなる。