// 132LEDクリスマスツリーイルミネーション 20221124_132LED_XmasTreeDeverop // バッファサイズを32ビットに拡張 /*最大30720バイトのフラッシュメモリのうち、スケッチが30418バイト(99%)を使っています。 最大2048バイトのRAMのうち、グローバル変数が465バイト(22%)を使っていて、ローカル変数で1583バイト使うことができます。 */ // 2022/11/24 ラジオペンチ #define OFF_TIMER 28800 // オフタイマー設定値(停止までの時間を秒で設定。28800=8Hr) #define BRIGHT 50 // LEDの明るさを0-100の値で指定。手動調光しない場合(A4=HIGH)に有効) #define BRIGHT_MODE_PIN 18 // 明るさ設定モード切替ピン(A4) LOWなら可変抵抗設定、Highならプログラムの設定値を使用 #define BRIGHTNESS_PIN 5 // 明るさ設定の可変抵抗(A5) volatile uint32_t Ly[11]; // 表示パターンメモリー 11段 volatile byte bSet = 0; // 明るさ設定値(割込みタイマーにセットする値で 0-240、0なら消灯) volatile long timeElapsed; // 経過時間 uint32_t Ly_a[11], Ly_b[11], Ly_c[11]; // 表示パターン操作メモリー int L10count[22]; // 流れ星末端の点灯回数メモリ unsigned long bitMapH[5]; // ビットマップ表示バッファ上位 unsigned long bitMapL[5]; //             下位 float bMag = 1.0; // プログラム内調光時の明るさ補正倍率 α (最終明るさ = αx + β) float bOffset = 0.0; // プログラム内調光時の明るさ補正オフセット β void setup() { Serial.begin(115200); pinMode(BRIGHT_MODE_PIN, INPUT_PULLUP); // 可変抵抗による明るさ設定の有無(HIGH:無し、LOW:有り) pinMode(A5, INPUT_PULLUP); pinMode(13, OUTPUT); timeElapsed = 0; // 経過時間タイマー tc2Setup(); // タイマー2の設定(1ms周期で割り込み) show(10); // 初期化(明るさ設定)のため1回ダミー実行 // ledTest(); // コメントアウトを外すと、LEDの接続テスト(下から一つづつ点灯) } void loop() { // 表示のデモ 引数で実行回数などを指定 starSpiralUp(1); // 下から上にスパイラルに点灯 topExplosion(1); dimming(1); // 調光 randomStar(2); // ランダム点灯 引数1で3秒間 messageBoard(2); // Merry CHRISTMAS! をスクロール表示 fallingRing(3); // 落下するリング rotateAndClimb(2); // 回転しながら登る propeller(1); // プロペラ stackUpDown(2); // UP/DOWN swing(1); // スイング verticalSlice(2); verticalCut(1); // 縦切り parallelCut(1); fallingSnow(2); // 降雪、積雪 (バグ有り、デバッグ中) dimming(1); // 調光 // 以下はテスト用 // allOn(); show(5000); // lampTest(); // ランプテスト show(1000); Serial.println(timeElapsed); if (timeElapsed > OFF_TIMER) { // 表示時間が設定値を超えていたら while (1) { // 無限ループで停止(リセットで抜け出す) } } } void ledTest() { // LED接続テスト(下から順にLEDを一つづつ点灯) for (;;) { // 無限ループで、(中身はstarSpiralUpと同じ) Ly[10] = 0x00000020; // 種を仕込んで show(300); // 点灯 for (int j = 0; j <= 132; j++) { // 一番上まで spiralUp(); // スパイラル上昇 show(200); // 点灯 } clearArray(); delay(200); } } void lampTest() { // ランプテスト uint32_t p; p = 0xFFFFFFFF; // 初期点灯パターン for (int i = 0; i <= 32; i++) { for (int j = 0; j <= 10; j++) { // 点灯パターンをメモリーへコピー Ly[j] = p; } show(50); p = p >> 1; // 点灯パターンを右に1ビットシフト } } void messageBoard(int n) { // 電光掲示板(文字をスクロール表示) // 表示文字の定義 5x64 のビットマップで指定 // M---- E-- R-- R-- Y-- C-- H-- R bitMapH[0] = 0b10001011101100110010100011010101; // MERRYCHR bitMapH[1] = 0b11011010001010101010100100010101; bitMapH[2] = 0b10101011101100110001000100011101; bitMapH[3] = 0b10001010001100101001000100010101; bitMapH[4] = 0b10001011101010101001000011010101; // R- I S-- T-- M---- A-- S-- (hart) bitMapL[0] = 0b10010111011101000100100111001010; // RISTMAS bitMapL[1] = 0b01010100001001101101010100011111; bitMapL[2] = 0b10010010001001010101110010011111; bitMapL[3] = 0b01010001001001000101010001001110; bitMapL[4] = 0b01010111001001000101010111000100; for (int i = 0; i < n; i++) { // 引数で指定された回数を繰り返す clearArray(); // 表示バッファクリア Ly[0] = 0x00018000; // 先端の2段は点灯 Ly[1] = 0x0003c000; Ly[2] = 0x0007E000; Ly[3] = 0x000FF000; Ly[4] = 0x001FF800; for (int j = 31; j >= 0; j--) { // bitMapHを表示 Ly[6] = Ly[6] | ((bitMapH[0] >> j) & 0x001); // 対象ビットをLSBに移動して表示メモリへコピー Ly[7] = Ly[7] | ((bitMapH[1] >> j) & 0x001); Ly[8] = Ly[8] | ((bitMapH[2] >> j) & 0x001); Ly[9] = Ly[9] | ((bitMapH[3] >> j) & 0x001); Ly[10] = Ly[10] | ((bitMapH[4] >> j) & 0x001); show(120); // 表示 Ly[6] = Ly[6] << 1; // 次回表示のために左スクロール Ly[7] = Ly[7] << 1; Ly[8] = Ly[8] << 1; Ly[9] = Ly[9] << 1; Ly[10] = Ly[10] << 1; } for (int j = 31; j >= 0; j--) { // bitMapLを表示 Ly[6] = Ly[6] | ((bitMapL[0] >> j) & 0x001); // 対象ビットをLSBに移動して表示メモリへコピー Ly[7] = Ly[7] | ((bitMapL[1] >> j) & 0x001); Ly[8] = Ly[8] | ((bitMapL[2] >> j) & 0x001); Ly[9] = Ly[9] | ((bitMapL[3] >> j) & 0x001); Ly[10] = Ly[10] | ((bitMapL[4] >> j) & 0x001); show(120); // 表示 Ly[6] = Ly[6] << 1; // 次回表示のために左スクロール Ly[7] = Ly[7] << 1; Ly[8] = Ly[8] << 1; Ly[9] = Ly[9] << 1; Ly[10] = Ly[10] << 1; } for (int j = 22; j >= 0; j--) { // 残り画面をスクロール Ly[6] = Ly[6] << 1; Ly[7] = Ly[7] << 1; Ly[8] = Ly[8] << 1; Ly[9] = Ly[9] << 1; Ly[10] = Ly[10] << 1; show(120); // 表示 } clearArray(); show(200); } } void propeller(int n) { // プロペラ表示 int a; for (int i = 0; i < n; i++) { // 引数で指定された回数繰り返す for (a = 0; a < 1680 * 2; a += 7) { // 正回転(1680は16,14,12,10 の最小公倍数) invertV(a); // 指定角度で逆V字表示 show(5); } for (a = 1680 * 2; a > 0; a -= 7) { // 逆回転 invertV(a); show(5); } } delay(300); } void invertV(int k) { // 指定角度で逆V字型に点灯(引数840で半回転) Ly[0] = 0b00000000000000011000000000000000; // 頂上の2個は常時点灯 Ly[1] = 0b00000000000000101000000000000000 >> ((k / 420) % 2); // V字パターンを指定角度に移動 Ly[2] = 0b00000000000001001000000000000000 >> ((k / 280) % 3); // なお840は8,7,6,5,4,3,2の最小公倍数 Ly[3] = 0b00000000000010001000000000000000 >> ((k / 210) % 4); Ly[4] = 0b00000000000100001000000000000000 >> ((k / 168) % 5); Ly[5] = 0b00000000001000001000000000000000 >> ((k / 140) % 6); Ly[6] = 0b00000000010000001000000000000000 >> ((k / 120) % 7); Ly[7] = 0b00000000100000001000000000000000 >> ((k / 105) % 8); Ly[8] = 0b00000001000000001000000000000000 >> ((k / 93) % 9); // Ly[9] = 0b00000010000000001000000000000000 >> ((k / 84) % 10); Ly[10] = 0b00000100000000001000000000000000 >> ((k / 76) % 11); } void invertV_test(int k) { // 指定角度で逆V字型に点灯(引数840で半回転) Ly[0] = 0b00000000000000000000000000000000; // 頂上の2個は常時点灯 Ly[1] = 0b00000000000000000000000000000000 >> ((k / 420) % 2); // V字パターンを指定角度に移動 Ly[2] = 0b00000000000000000000000000000000 >> ((k / 280) % 3); // なお840は8,7,6,5,4,3,2の最小公倍数 Ly[3] = 0b00000000000000000000000000000000 >> ((k / 210) % 4); Ly[4] = 0b00000000000000000000000000000000 >> ((k / 168) % 5); Ly[5] = 0b00000000000000000000000000000000 >> ((k / 140) % 6); Ly[6] = 0b00000000000111110000000000000000 >> ((k / 120) % 7); Ly[7] = 0b00000000000001000000000000000000 >> ((k / 105) % 8); Ly[8] = 0b00000000000010000000000000000000 >> ((k / 93) % 9); // Ly[9] = 0b00000000000010000000000000000000 >> ((k / 84) % 10); Ly[10] = 0b0000000000100000000000000000000 >> ((k / 76) % 11); } void starSpiralUp(int n) { // 回転しながら下から上に向かってLEDを一つづ点灯 for (int i = 0; i < n; i++) { // 指定回数 Ly[10] = 0x00000020; // 一番下に種を仕込んで show(20); // for (int j = 0; j <= 132; j++) { // 一番上まで spiralUp(); // スパイラル上昇 show(20); // 点灯 } clearArray(); delay(200); } } void fallingRing(int c) { // リングを上から落とす for (int n = 0; n < c; n++) { // 指定回数 clearArray(); Ly[0] = 0xFFFFFFFF; // 先頭にネタを仕込んで show(100); // 見せるためにちょっと待機 for (int i = 0; i < 10; i++) { Ly[i + 1] = Ly[i]; // 一つ後ろ(下)にずらす Ly[i] = 0; show(70); // 待機 } } clearArray(); // 最後に消灯 delay(200); } void topExplosion(int c) { // 先端で爆発 for (int n = 0; n < c; n++) { // 指定回数 clearArray(); for (int i = 0; i < 11; i++) { Ly[i] = 0xFFFFFFFF; // 上から下に向かって点灯 show(30); // 待機 } } delay(500); // 全点灯でちょっと待つ } void stackUpDown(int n) { // 積み上げで点灯、積み下げで消灯 for (int i = 0; i < n; i++) { for (int z = 10; z >= 0; z--) { // 下から上に順に積み上げ点灯 Ly[z] = 0xFFFFFFFF; show(30); } show(200); // 全点灯でちょっと待つ for (int z = 10; z >= 0; z--) { // 下から上へ消灯 Ly[z] = 0x0000; show(30); } show(200); // 全消灯でちょっと待つ for (int z = 0; z <= 10; z++) { // 上から下へ逆積みで点灯 Ly[z] = 0xFFFFFFFF; show(30); } show(200); // 全点灯でちょっと待つ for (int z = 0; z <= 10; z++) { // 上から下へ消灯 Ly[z] = 0x0000; show(30); } show(300); // 全消灯でちょっと待つ } // n回繰り返し } void swing(int n) { // 斜め線を右移動 for (int i = 0; i < n; i++) { // 指定回数 for (int j = 0; j < 1; j++) { // 左回転で1回 Ly[0] = 0x00010000; // 左側に斜め線を仕込む Ly[1] = 0x00020000; Ly[2] = 0x00040000; Ly[3] = 0x00080000; Ly[4] = 0x00100000; Ly[5] = 0x00200000; Ly[6] = 0x00400000; Ly[7] = 0x00800000; Ly[8] = 0x01000000; Ly[9] = 0x02000000; Ly[10] = 0x04000000; for (int k = 0; k < 22; k++) { // 22回 for (int m = 0; m < 11; m++) { // 各層の Ly[m] = Ly[m] >> 1; // 像を右シフト } show(50); // 表示のために待機 } } show(200); for (int j = 0; j < 1; j++) { // 右回転で1回 Ly[0] = 0x00008000; // 右側に斜め線を仕込む Ly[1] = 0x00004000; Ly[2] = 0x00002000; Ly[3] = 0x00001000; Ly[4] = 0x00000800; Ly[5] = 0x00000400; Ly[6] = 0x00000200; Ly[7] = 0x00000100; Ly[8] = 0x00000080; Ly[9] = 0x00000040; Ly[10] = 0x00000020; for (int k = 0; k < 22; k++) { // 22回 for (int m = 0; m < 11; m++) { Ly[m] = Ly[m] << 1; // 像を右シフト } show(50); // 表示のために待機 } } show(200); for (int j = 0; j < 1; j++) { // 交差スイングで1回 Ly_a[0] = 0x00010000; Ly_b[0] = 0x00008000; // 両側に斜め線を仕込む Ly_a[1] = 0x00020000; Ly_b[1] = 0x00004000; Ly_a[2] = 0x00040000; Ly_b[2] = 0x00002000; Ly_a[3] = 0x00080000; Ly_b[3] = 0x00001000; Ly_a[4] = 0x00100000; Ly_b[4] = 0x00000800; Ly_a[5] = 0x00200000; Ly_b[5] = 0x00000400; Ly_a[6] = 0x00400000; Ly_b[6] = 0x00000200; Ly_a[7] = 0x00800000; Ly_b[7] = 0x00000100; Ly_a[8] = 0x01000000; Ly_b[8] = 0x00000080; Ly_a[9] = 0x02000000; Ly_b[9] = 0x00000040; Ly_a[10] = 0x04000000; Ly_b[10] = 0x00000020; for (int k = 0; k < 22; k++) { // 22回 for (int m = 0; m < 11; m++) { Ly_a[m] = Ly_a[m] >> 1; // aバッファの像を右シフト } for (int m = 0; m < 11; m++) { Ly_b[m] = Ly_b[m] << 1; // bバッファの像を左シフト } for (int m = 0; m < 11; m++) { Ly[m] = Ly_a[m] | Ly_b[m]; // 表示メモリに合成 } show(50); // 表示のために待機 } } show(300); } } void verticalCut(int n) { // 縦切りで横に点灯、消灯 clearArray(); for (int i = 0; i < n; i++) { // 指定回数 vSliceTogle(1); cutShow(); // 右から左に点灯 vSliceTogle(2); cutShow(); vSliceTogle(3); cutShow(); vSliceTogle(4); cutShow(); vSliceTogle(5); cutShow(); vSliceTogle(6); cutShow(); vSliceTogle(7); cutShow(); vSliceTogle(8); cutShow(); vSliceTogle(9); cutShow(); vSliceTogle(10); cutShow(); vSliceTogle(11); cutShow(); vSliceTogle(12); // 全点灯 show(500); vSliceTogle(1); cutShow(); // 右から左に消灯(XORで反転させる) vSliceTogle(2); cutShow(); vSliceTogle(3); cutShow(); vSliceTogle(4); cutShow(); vSliceTogle(5); cutShow(); vSliceTogle(6); cutShow(); vSliceTogle(7); cutShow(); vSliceTogle(8); cutShow(); vSliceTogle(9); cutShow(); vSliceTogle(10); cutShow(); vSliceTogle(11); cutShow(); vSliceTogle(12); cutShow(); show(500); // 全消灯 vSliceTogle(12); cutShow(); // 左から右に点灯 vSliceTogle(11); cutShow(); vSliceTogle(10); cutShow(); vSliceTogle(9); cutShow(); vSliceTogle(8); cutShow(); vSliceTogle(7); cutShow(); vSliceTogle(6); cutShow(); vSliceTogle(5); cutShow(); vSliceTogle(4); cutShow(); vSliceTogle(3); cutShow(); vSliceTogle(2); cutShow(); vSliceTogle(1); cutShow(); show(500); // 全点灯 vSliceTogle(12); cutShow(); // 左から右に消灯 vSliceTogle(11); cutShow(); vSliceTogle(10); cutShow(); vSliceTogle(9); cutShow(); vSliceTogle(8); cutShow(); vSliceTogle(7); cutShow(); vSliceTogle(6); cutShow(); vSliceTogle(5); cutShow(); vSliceTogle(4); cutShow(); vSliceTogle(3); cutShow(); vSliceTogle(2); cutShow(); vSliceTogle(1); cutShow(); show(500); // 全消灯 clearArray(); } } void parallelCut(int n) { // 縦切りで横に点灯、消灯 clearArray(); for (int i = 0; i < n; i++) { // 指定回数 vSliceTogle(1); vSliceTogle(12); cutShow(); vSliceTogle(2); vSliceTogle(11); cutShow(); vSliceTogle(3); vSliceTogle(10); cutShow(); vSliceTogle(4); vSliceTogle(9); cutShow(); vSliceTogle(5); vSliceTogle(8); cutShow(); vSliceTogle(6); vSliceTogle(7); show(1000); vSliceTogle(1); vSliceTogle(12); cutShow(); vSliceTogle(2); vSliceTogle(11); cutShow(); vSliceTogle(3); vSliceTogle(10); cutShow(); vSliceTogle(4); vSliceTogle(9); cutShow(); vSliceTogle(5); vSliceTogle(8); cutShow(); vSliceTogle(6); vSliceTogle(7); show(1000); clearArray(); } } void verticalSlice(int n) { clearArray(); for (int i = 0; i < n; i++) { // 指定回数 vSliceTogle(1); cutShow(); vSliceTogle(1); vSliceTogle(2); cutShow(); // 右から左へスライス移動 vSliceTogle(2); vSliceTogle(3); cutShow(); vSliceTogle(3); vSliceTogle(4); cutShow(); vSliceTogle(4); vSliceTogle(5); cutShow(); vSliceTogle(5); vSliceTogle(6); cutShow(); vSliceTogle(6); vSliceTogle(7); cutShow(); vSliceTogle(7); vSliceTogle(8); cutShow(); vSliceTogle(8); vSliceTogle(9); cutShow(); vSliceTogle(9); vSliceTogle(10); cutShow(); vSliceTogle(10); vSliceTogle(11); cutShow(); vSliceTogle(11); vSliceTogle(12); cutShow(); vSliceTogle(12); delay(200); vSliceTogle(12); cutShow(); vSliceTogle(12); vSliceTogle(11); cutShow(); // 左から右 vSliceTogle(11); vSliceTogle(10); cutShow(); vSliceTogle(10); vSliceTogle(9); cutShow(); vSliceTogle(9); vSliceTogle(8); cutShow(); vSliceTogle(8); vSliceTogle(7); cutShow(); vSliceTogle(7); vSliceTogle(6); cutShow(); vSliceTogle(6); vSliceTogle(5); cutShow(); vSliceTogle(5); vSliceTogle(4); cutShow(); vSliceTogle(4); vSliceTogle(3); cutShow(); vSliceTogle(3); vSliceTogle(2); cutShow(); vSliceTogle(2); vSliceTogle(1); cutShow(); vSliceTogle(1); delay(400); } } void cutShow() { // 指定時間待つ(ソース短縮対策) show(50); } void vSliceTogle(int n) { // 指定の列を反転(XORで縦切りにビットを反転) switch (n) { case 1: Ly[10] ^= 0b00000000000000000000010000000000; break; case 2: Ly[8] ^= 0b00000000000000000000100000000000; Ly[9] ^= 0b00000000000000000000110000000000; Ly[10] ^= 0b00000000000000000000101000000000; break; case 3: Ly[6] ^= 0b00000000000000000001000000000000; Ly[7] ^= 0b00000000000000000001100000000000; Ly[8] ^= 0b00000000000000000001010000000000; Ly[9] ^= 0b00000000000000000001001000000000; Ly[10] ^= 0b00000000000000000001000100000000; break; case 4: Ly[4] ^= 0b00000000000000000010000000000000; Ly[5] ^= 0b00000000000000000011000000000000; Ly[6] ^= 0b00000000000000000010100000000000; Ly[7] ^= 0b00000000000000000010010000000000; Ly[8] ^= 0b00000000000000000010001000000000; Ly[9] ^= 0b00000000000000000010000100000000; Ly[10] ^= 0b00000000000000000010000010000000; break; case 5: Ly[2] ^= 0b00000000000000000100000000000000; Ly[3] ^= 0b00000000000000000110000000000000; Ly[4] ^= 0b00000000000000000101000000000000; Ly[5] ^= 0b00000000000000000100100000000000; Ly[6] ^= 0b00000000000000000100010000000000; Ly[7] ^= 0b00000000000000000100001000000000; Ly[8] ^= 0b00000000000000000100000100000000; Ly[9] ^= 0b00000000000000000100000010000000; Ly[10] ^= 0b00000000000000000100000001000000; break; case 6: Ly[0] ^= 0b00000000000000001000000000000000; Ly[1] ^= 0b00000000000000001100000000000000; Ly[2] ^= 0b00000000000000001010000000000000; Ly[3] ^= 0b00000000000000001001000000000000; Ly[4] ^= 0b00000000000000001000100000000000; Ly[5] ^= 0b00000000000000001000010000000000; Ly[6] ^= 0b00000000000000001000001000000000; Ly[7] ^= 0b00000000000000001000000100000000; Ly[8] ^= 0b00000000000000001000000010000000; Ly[9] ^= 0b00000000000000001000000001000000; Ly[10] ^= 0b00000000000000001000000000100000; break; case 7: Ly[0] ^= 0b00000000000000010000000000000000; Ly[1] ^= 0b00000000000000110000000000000000; Ly[2] ^= 0b00000000000001010000000000000000; Ly[3] ^= 0b00000000000010010000000000000000; Ly[4] ^= 0b00000000000100010000000000000000; Ly[5] ^= 0b00000000001000010000000000000000; Ly[6] ^= 0b00000000010000010000000000000000; Ly[7] ^= 0b00000000100000010000000000000000; Ly[8] ^= 0b00000001000000010000000000000000; Ly[9] ^= 0b00000010000000010000000000000000; Ly[10] ^= 0b00000100000000010000000000000000; break; case 8: Ly[2] ^= 0b00000000000000100000000000000000; Ly[3] ^= 0b00000000000001100000000000000000; Ly[4] ^= 0b00000000000010100000000000000000; Ly[5] ^= 0b00000000000100100000000000000000; Ly[6] ^= 0b00000000001000100000000000000000; Ly[7] ^= 0b00000000010000100000000000000000; Ly[8] ^= 0b00000000100000100000000000000000; Ly[9] ^= 0b00000001000000100000000000000000; Ly[10] ^= 0b00000010000000100000000000000000; break; case 9: Ly[4] ^= 0b00000000000001000000000000000000; Ly[5] ^= 0b00000000000011000000000000000000; Ly[6] ^= 0b00000000000101000000000000000000; Ly[7] ^= 0b00000000001001000000000000000000; Ly[8] ^= 0b00000000010001000000000000000000; Ly[9] ^= 0b00000000100001000000000000000000; Ly[10] ^= 0b00000001000001000000000000000000; break; case 10: Ly[6] ^= 0b00000000000010000000000000000000; Ly[7] ^= 0b00000000000110000000000000000000; Ly[8] ^= 0b00000000001010000000000000000000; Ly[9] ^= 0b00000000010010000000000000000000; Ly[10] ^= 0b00000000100010000000000000000000; break; case 11: Ly[8] ^= 0b00000000000100000000000000000000; Ly[9] ^= 0b00000000001100000000000000000000; Ly[10] ^= 0b00000000010100000000000000000000; break; case 12: Ly[10] ^= 0b00000000001000000000000000000000; break; default: break; } } void rotateAndClimb(int n) { // 回転しながら登る clearArray(); for (int i = 0; i < n; i++) { // 指定回数 for (int j = 0; j < 140; j++) { if ( (j % 18) > 8) { // 8回置きに、 Ly[10] |= 0x00000040; // 一番下に星を埋め込む } else { Ly[10] &= ~0x00000040; // 星を消す } show(40); spiralUp(); } for (int j = 0; j < 132; j++) { Ly[10] &= ~0x00000040; show(40); spiralUp(); } } clearArray(); delay(500); } void changeBrightness(float r, int n) { // 明るさ補正係数(bMag)を指定回数(n)、指定比率(r)変更 for (int i = 0; i <= n; i++) { // 指定回数 bMag *= r; // 明るさをちょっと変更して show(30); // 待つ } } int interval(int x, int p1, int p2, int nnn) { // p1からp2にnnn回でCOSカーブでd回で変化させる時の、x番目の値を求める float fx, fp1, fp2, fnnn; int y; fx = x; // 計算用に浮動小数点化 fp1 = p1; fp2 = p2; fnnn = nnn; y = fp2 + (fp1 - fp2) * 0.5 * (1.0 + cos(3.1416 * fx / fnnn)); return y; } void rotateCW() { // 各層を時計回りに1ステップ回転させる(等速移動なので上の方が回転速度が速い) Ly[0] = Ly[0] << 1; if ( Ly[0] & 0x0400) Ly[0] |= 0x0040; // 先端だけは4ビット存在するものとして操作 Ly[1] = Ly[1] << 1; if ( Ly[1] & 0x0400) Ly[1] |= 0x0040; Ly[2] = Ly[2] << 1; if ( Ly[2] & 0x0800) Ly[2] |= 0x0020; Ly[3] = Ly[3] << 1; if ( Ly[3] & 0x1000) Ly[3] |= 0x0010; Ly[4] = Ly[4] << 1; if ( Ly[4] & 0x2000) Ly[4] |= 0x0008; Ly[5] = Ly[5] << 1; if ( Ly[5] & 0x4000) Ly[5] |= 0x0004; Ly[6] = Ly[6] << 1; if ( Ly[6] & 0x8000) Ly[6] |= 0x0002; Ly[0] &= 0x03C0; // ゴミ消し Ly[1] &= 0x03C0; Ly[2] &= 0x07E0; Ly[3] &= 0x0FF0; Ly[4] &= 0x1FF8; Ly[5] &= 0x3FFC; Ly[6] &= 0x7FFE; } void rotateCWCCW() { // 各層を時計回り、反時計回りに1ステップ回転させる(等速移動なので上の方が回転速度が速い) Ly[0] = Ly[0] << 1; if ( Ly[0] & 0x0400) Ly[0] |= 0x0040; // 先端だけは4ビット存在するものとして操作 Ly[1] = Ly[1] >> 1; if ( Ly[1] & 0x0020) Ly[1] |= 0x0200; Ly[2] = Ly[2] << 1; if ( Ly[2] & 0x0800) Ly[2] |= 0x0020; Ly[3] = Ly[3] >> 1; if ( Ly[3] & 0x0008) Ly[3] |= 0x0800; Ly[4] = Ly[4] << 1; if ( Ly[4] & 0x2000) Ly[4] |= 0x0008; Ly[5] = Ly[5] >> 1; if ( Ly[5] & 0x0002) Ly[5] |= 0x2000; Ly[6] = Ly[6] << 1; if ( Ly[6] & 0x8000) Ly[6] |= 0x0002; Ly[0] &= 0x03C0; // ゴミ消し Ly[1] &= 0x03C0; Ly[2] &= 0x07E0; Ly[3] &= 0x0FF0; Ly[4] &= 0x1FF8; Ly[5] &= 0x3FFC; Ly[6] &= 0x7FFE; } void randomStar(int n) { // ランダムに点灯 for (int i = 0; i < n; i++) { // 引数で指定された回数 for (int j = 0; j < 40; j++) { // 6秒間(0.15秒x40回) Ly[0] |= 0x00018000; // 先端の2個は常時点灯 Ly[1] = random(0, 0xFFFFFFF) & random(0, 0xFFFFFFF); // 確率1/4で点灯 Ly[2] = random(0, 0xFFFFFFF) & random(0, 0xFFFFFFF); // 乱数の上限を32ビットフルにすると動かなかったので28ビットに留めている Ly[3] = random(0, 0xFFFFFFF) & random(0, 0xFFFFFFF); Ly[4] = random(0, 0xFFFFFFF) & random(0, 0xFFFFFFF); Ly[5] = random(0, 0xFFFFFFF) & random(0, 0xFFFFFFF); Ly[6] = random(0, 0xFFFFFFF) & random(0, 0xFFFFFFF); Ly[7] = random(0, 0xFFFFFFF) & random(0, 0xFFFFFFF); Ly[8] = random(0, 0xFFFFFFF) & random(0, 0xFFFFFFF); Ly[9] = random(0, 0xFFFFFFF) & random(0, 0xFFFFFFF); Ly[10] = random(0, 0xFFFFFFF) & random(0, 0xFFFFFFF); show(150); } } // n clearArray(); show(1000); } void fallingSnow(int m) { // 雪が降る mは表示時間倍率 int p = 20; // 雪の出現確率(確率= 1/p) clearArray(); for (int n = 0; n < 22; n++) { // 末端カウンタをリセット L10count[n] = 0; } for (int k = 0; k < (150 * m); k++) { if (random(0, p) == 0) Ly_b[1] |= 0x00004000; // 末端 0の種 (b面に仕込む) if (random(0, p) == 0) Ly_b[1] |= 0x00008000; // 末端 1の種 if (random(0, p) == 0) Ly_b[2] |= 0x00008000; // 末端 2の種 if (random(0, p) == 0) Ly_b[3] |= 0x00008000; // 末端 3の種 if (random(0, p) == 0) Ly_b[4] |= 0x00008000; // 末端 4の種 if (random(0, p) == 0) Ly_c[0] |= 0x00008000; // 末端 5の種 (c面に仕込む) if (random(0, p) == 0) Ly_a[4] |= 0x00000800; // 末端 6の種 (a面に仕込む) if (random(0, p) == 0) Ly_a[3] |= 0x00001000; // 末端 7の種 if (random(0, p) == 0) Ly_a[2] |= 0x00002000; // 末端 8の種 if (random(0, p) == 0) Ly_a[1] |= 0x00004000; // 末端 9の種 if (random(0, p) == 0) Ly_a[1] |= 0x00008000; // 末端10の種 if (random(0, p) == 0) Ly_a[1] |= 0x00010000; // 末端11の種 if (random(0, p) == 0) Ly_a[1] |= 0x00020000; // 末端12の種 if (random(0, p) == 0) Ly_a[2] |= 0x00040000; // 末端13の種 if (random(0, p) == 0) Ly_a[3] |= 0x00080000; // 末端14の種 if (random(0, p) == 0) Ly_a[4] |= 0x00100000; // 末端15の種 if (random(0, p) == 0) Ly_c[0] |= 0x00010000; // 末端16の種 (c面に仕込む) if (random(0, p) == 0) Ly_b[4] |= 0x00010000; // 末端17の種 (b面に仕込む) if (random(0, p) == 0) Ly_b[3] |= 0x00010000; // 末端18の種 if (random(0, p) == 0) Ly_b[2] |= 0x00010000; // 末端19の種 if (random(0, p) == 0) Ly_b[1] |= 0x00010000; // 末端20の種 if (random(0, p) == 0) Ly_b[1] |= 0x00020000; // 末端21の種 for (int j = 0; j < 11; j++) { Ly[j] = Ly_a[j] | Ly_b[j] | Ly_c[j]; // レイヤーを合成して表示メモリに書き込み } Ly[0] |= 0x00018000; // 先頭を点灯 show(70); // 星の落ちる速さ stepDown(); // 星を一つ下に流す } // next k clearArray(); show(1000); } void stepDown() { // 雪の粒を所定のルートで落とす // 末端0の処理 if (Ly_b[9] & 0x00000040) L10count[0] = 3; else L10count[0]--; // A4 最下段は4回光ったままにする if (L10count[0] < 0) L10count[0] = 0; if (L10count[0] > 0 ) Ly_b[10] |= 0x00000020; else Ly_b[10] &= ~0x00000020UL; // 注意:notのビット操作は明示しておかないと if (Ly_b[8] & 0x00000080) Ly_b[9] |= 0x00000040; else Ly_b[9] &= ~0x00000040UL; // 16ビットだけしか行われない if (Ly_b[7] & 0x00000100) Ly_b[8] |= 0x00000080; else Ly_b[8] &= ~0x00000080UL; if (Ly_b[6] & 0x00000200) Ly_b[7] |= 0x00000100; else Ly_b[7] &= ~0x00000100UL; if (Ly_b[5] & 0x00000400) Ly_b[6] |= 0x00000200; else Ly_b[6] &= ~0x00000200UL; if (Ly_b[4] & 0x00000800) Ly_b[5] |= 0x00000400; else Ly_b[5] &= ~0x00000400UL; if (Ly_b[3] & 0x00001000) Ly_b[4] |= 0x00000800; else Ly_b[4] &= ~0x00000800UL; if (Ly_b[2] & 0x00002000) Ly_b[3] |= 0x00001000; else Ly_b[3] &= ~0x00001000UL; if (Ly_b[1] & 0x00004000) Ly_b[2] |= 0x00002000; else Ly_b[2] &= ~0x00002000UL; Ly_b[1] &= ~0x00004000UL; // 末端1の処理 if (Ly_b[9] & 0x00000080) L10count[1] = 3; else L10count[1]--; // A4 最下段は4回光ったままにする if (L10count[1] < 0) L10count[1] = 0; if (L10count[1] > 0 ) Ly_b[10] |= 0x00000040; else Ly_b[10] &= ~0x00000040UL; if (Ly_b[8] & 0x00000100) Ly_b[9] |= 0x00000080; else Ly_b[9] &= ~0x00000080UL; if (Ly_b[7] & 0x00000200) Ly_b[8] |= 0x00000100; else Ly_b[8] &= ~0x00000100UL; if (Ly_b[6] & 0x00000400) Ly_b[7] |= 0x00000200; else Ly_b[7] &= ~0x00000200UL; if (Ly_b[5] & 0x00000800) Ly_b[6] |= 0x00000400; else Ly_b[6] &= ~0x00000400UL; if (Ly_b[4] & 0x00001000) Ly_b[5] |= 0x00000800; else Ly_b[5] &= ~0x00000800UL; if (Ly_b[3] & 0x00002000) Ly_b[4] |= 0x00001000; else Ly_b[4] &= ~0x00001000UL; if (Ly_b[2] & 0x00004000) Ly_b[3] |= 0x00002000; else Ly_b[3] &= ~0x00002000UL; if (Ly_b[1] & 0x00008000) Ly_b[2] |= 0x00004000; else Ly_b[2] &= ~0x00004000UL; Ly_b[1] &= ~0x00008000UL; // 末端2の処理 if (Ly_b[9] & 0x00000100) L10count[2] = 3; else L10count[2]--; // A4 最下段は4回光ったままにする if (L10count[2] < 0) L10count[2] = 0; if (L10count[2] > 0 ) Ly_b[10] |= 0x00000080; else Ly_b[10] &= ~0x00000080UL; if (Ly_b[8] & 0x00000200) Ly_b[9] |= 0x00000100; else Ly_b[9] &= ~0x00000100UL; if (Ly_b[7] & 0x00000400) Ly_b[8] |= 0x00000200; else Ly_b[8] &= ~0x00000200UL; if (Ly_b[6] & 0x00000800) Ly_b[7] |= 0x00000400; else Ly_b[7] &= ~0x00000400UL; if (Ly_b[5] & 0x00001000) Ly_b[6] |= 0x00000800; else Ly_b[6] &= ~0x00000800UL; if (Ly_b[4] & 0x00002000) Ly_b[5] |= 0x00001000; else Ly_b[5] &= ~0x00001000UL; if (Ly_b[3] & 0x00004000) Ly_b[4] |= 0x00002000; else Ly_b[4] &= ~0x00002000UL; if (Ly_b[2] & 0x00008000) Ly_b[3] |= 0x00004000; else Ly_b[3] &= ~0x00004000UL; Ly_b[2] &= ~0x00008000UL; // 末端3の処理 if (Ly_b[9] & 0x00000200) L10count[2] = 3; else L10count[2]--; // A4 最下段は4回光ったままにする if (L10count[2] < 0) L10count[2] = 0; if (L10count[2] > 0 ) Ly_b[10] |= 0x00000100; else Ly_b[10] &= ~0x00000100UL; if (Ly_b[8] & 0x00000400) Ly_b[9] |= 0x00000200; else Ly_b[9] &= ~0x00000200UL; if (Ly_b[7] & 0x00000800) Ly_b[8] |= 0x00000400; else Ly_b[8] &= ~0x00000400UL; if (Ly_b[6] & 0x00001000) Ly_b[7] |= 0x00000800; else Ly_b[7] &= ~0x00000800UL; if (Ly_b[5] & 0x00002000) Ly_b[6] |= 0x00001000; else Ly_b[6] &= ~0x00001000UL; if (Ly_b[4] & 0x00004000) Ly_b[5] |= 0x00002000; else Ly_b[5] &= ~0x00002000UL; if (Ly_b[3] & 0x00008000) Ly_b[4] |= 0x00004000; else Ly_b[4] &= ~0x00004000UL; Ly_b[3] &= ~0x00008000UL; // 末端4の処理 if (Ly_b[9] & 0x00000400) L10count[2] = 3; else L10count[2]--; // A4 最下段は4回光ったままにする if (L10count[2] < 0) L10count[2] = 0; if (L10count[2] > 0 ) Ly_b[10] |= 0x00000200; else Ly_b[10] &= ~0x00000200UL; if (Ly_b[8] & 0x00000800) Ly_b[9] |= 0x00000400; else Ly_b[9] &= ~0x00000400UL; if (Ly_b[7] & 0x00001000) Ly_b[8] |= 0x00000800; else Ly_b[8] &= ~0x00000800UL; if (Ly_b[6] & 0x00002000) Ly_b[7] |= 0x00001000; else Ly_b[7] &= ~0x00001000UL; if (Ly_b[5] & 0x00004000) Ly_b[6] |= 0x00002000; else Ly_b[6] &= ~0x00002000UL; if (Ly_b[4] & 0x00008000) Ly_b[5] |= 0x00004000; else Ly_b[5] &= ~0x00004000UL; Ly_b[4] &= ~0x00008000UL; // 末端5の処理 if (Ly_c[8] & 0x00000800) L10count[5] = 3; else L10count[5]--; // A2 最下段は4回光ったままにする if (L10count[5] < 0) L10count[5] = 0; if (L10count[5] > 0 ) Ly_c[10] |= 0x00000400; else Ly_c[10] &= ~0x00000400UL; if (Ly_c[6] & 0x00001000) Ly_c[8] |= 0x00000800; else Ly_c[8] &= ~0x00000800UL; if (Ly_c[4] & 0x00002000) Ly_c[6] |= 0x00001000; else Ly_c[6] &= ~0x00001000UL; if (Ly_c[2] & 0x00004000) Ly_c[4] |= 0x00002000; else Ly_c[4] &= ~0x00002000UL; if (Ly_c[0] & 0x00008000) Ly_c[2] |= 0x00004000; else Ly_c[2] &= ~0x00004000UL; Ly_c[0] &= ~0x00008000UL; // 末端6の処理 if (Ly_a[9] & 0x00000800) L10count[6] = 3; else L10count[6]--; // A2 最下段は4回光ったままにする if (L10count[6] < 0) L10count[6] = 0; if (L10count[6] > 0 ) Ly_a[10] |= 0x00000800; else Ly_a[10] &= ~0x00000800UL; if (Ly_a[8] & 0x00000800) Ly_a[9] |= 0x00000800; else Ly_a[9] &= ~0x00000800UL; if (Ly_a[7] & 0x00000800) Ly_a[8] |= 0x00000800; else Ly_a[8] &= ~0x00000800UL; if (Ly_a[6] & 0x00000800) Ly_a[7] |= 0x00000800; else Ly_a[7] &= ~0x00000800UL; if (Ly_a[5] & 0x00000800) Ly_a[6] |= 0x00000800; else Ly_a[6] &= ~0x00000800UL; if (Ly_a[4] & 0x00000800) Ly_a[5] |= 0x00000800; else Ly_a[5] &= ~0x00000800UL; Ly_a[4] &= ~0x00000800UL; // 末端7の処理 if (Ly_a[9] & 0x00001000) L10count[7] = 3; else L10count[7]--; // A2 最下段は4回光ったままにする if (L10count[7] < 0) L10count[7] = 0; if (L10count[7] > 0 ) Ly_a[10] |= 0x00001000; else Ly_a[10] &= ~0x00001000UL; if (Ly_a[8] & 0x00001000) Ly_a[9] |= 0x00001000; else Ly_a[9] &= ~0x00001000UL; if (Ly_a[7] & 0x00001000) Ly_a[8] |= 0x00001000; else Ly_a[8] &= ~0x00001000UL; if (Ly_a[6] & 0x00001000) Ly_a[7] |= 0x00001000; else Ly_a[7] &= ~0x00001000UL; if (Ly_a[5] & 0x00001000) Ly_a[6] |= 0x00001000; else Ly_a[6] &= ~0x00001000UL; if (Ly_a[4] & 0x00001000) Ly_a[5] |= 0x00001000; else Ly_a[5] &= ~0x00001000UL; if (Ly_a[3] & 0x00001000) Ly_a[4] |= 0x00001000; else Ly_a[4] &= ~0x00001000UL; Ly_a[3] &= ~0x00001000UL; // 末端8の処理 if (Ly_a[9] & 0x00002000) L10count[8] = 3; else L10count[8]--; // A2 最下段は4回光ったままにする if (L10count[8] < 0) L10count[8] = 0; if (L10count[8] > 0 ) Ly_a[10] |= 0x00002000; else Ly_a[10] &= ~0x00002000UL; if (Ly_a[8] & 0x00002000) Ly_a[9] |= 0x00002000; else Ly_a[9] &= ~0x00002000UL; if (Ly_a[7] & 0x00002000) Ly_a[8] |= 0x00002000; else Ly_a[8] &= ~0x00002000UL; if (Ly_a[6] & 0x00002000) Ly_a[7] |= 0x00002000; else Ly_a[7] &= ~0x00002000UL; if (Ly_a[5] & 0x00002000) Ly_a[6] |= 0x00002000; else Ly_a[6] &= ~0x00002000UL; if (Ly_a[4] & 0x00002000) Ly_a[5] |= 0x00002000; else Ly_a[5] &= ~0x00002000UL; if (Ly_a[3] & 0x00002000) Ly_a[4] |= 0x00002000; else Ly_a[4] &= ~0x00002000UL; if (Ly_a[2] & 0x00002000) Ly_a[3] |= 0x00002000; else Ly_a[3] &= ~0x00002000UL; Ly_a[2] &= ~0x00002000UL; // 末端9の処理 if (Ly_a[9] & 0x00004000) L10count[9] = 3; else L10count[9]--; // A2 最下段は4回光ったままにする if (L10count[9] < 0) L10count[9] = 0; if (L10count[9] > 0 ) Ly_a[10] |= 0x00004000; else Ly_a[10] &= ~0x00004000UL; if (Ly_a[8] & 0x00004000) Ly_a[9] |= 0x00004000; else Ly_a[9] &= ~0x00004000UL; if (Ly_a[7] & 0x00004000) Ly_a[8] |= 0x00004000; else Ly_a[8] &= ~0x00004000UL; if (Ly_a[6] & 0x00004000) Ly_a[7] |= 0x00004000; else Ly_a[7] &= ~0x00004000UL; if (Ly_a[5] & 0x00004000) Ly_a[6] |= 0x00004000; else Ly_a[6] &= ~0x00004000UL; if (Ly_a[4] & 0x00004000) Ly_a[5] |= 0x00004000; else Ly_a[5] &= ~0x00004000UL; if (Ly_a[3] & 0x00004000) Ly_a[4] |= 0x00004000; else Ly_a[4] &= ~0x00004000UL; if (Ly_a[2] & 0x00004000) Ly_a[3] |= 0x00004000; else Ly_a[3] &= ~0x00004000UL; if (Ly_a[1] & 0x00004000) Ly_a[2] |= 0x00004000; else Ly_a[2] &= ~0x00004000UL; Ly_a[1] &= ~0x00004000UL; // 末端10の処理 if (Ly_a[9] & 0x00008000) L10count[10] = 3; else L10count[10]--; // A5 最下段は4回光ったままにする この部分に原因不明のバグがある if (L10count[10] < 0) L10count[10] = 0; if (L10count[10] > 0 ) Ly_a[10] |= 0x00008000; else Ly_a[10] &= ~0x00008000UL; if (Ly_a[8] & 0x00008000) Ly_a[9] |= 0x00008000; else Ly_a[9] &= ~0x00008000UL; if (Ly_a[7] & 0x00008000) Ly_a[8] |= 0x00008000; else Ly_a[8] &= ~0x00008000UL; if (Ly_a[6] & 0x00008000) Ly_a[7] |= 0x00008000; else Ly_a[7] &= ~0x00008000UL; if (Ly_a[5] & 0x00008000) Ly_a[6] |= 0x00008000; else Ly_a[6] &= ~0x00008000UL; if (Ly_a[4] & 0x00008000) Ly_a[5] |= 0x00008000; else Ly_a[5] &= ~0x00008000UL; if (Ly_a[3] & 0x00008000) Ly_a[4] |= 0x00008000; else Ly_a[4] &= ~0x00008000UL; if (Ly_a[2] & 0x00008000) Ly_a[3] |= 0x00008000; else Ly_a[3] &= ~0x00008000UL; if (Ly_a[1] & 0x00008000) Ly_a[2] |= 0x00008000; else Ly_a[2] &= ~0x00008000UL; Ly_a[1] &= ~0x00008000UL; // 末端11の処理 if (Ly_a[9] & 0x00010000) L10count[11] = 3; else L10count[11]--; // A4 最下段は4回光ったままにする if (L10count[11] < 0) L10count[11] = 0; if (L10count[11] > 0 ) Ly_a[10] |= 0x00010000; else Ly_a[10] &= ~0x00010000UL; if (Ly_a[8] & 0x00010000) Ly_a[9] |= 0x00010000; else Ly_a[9] &= ~0x00010000UL; if (Ly_a[7] & 0x00010000) Ly_a[8] |= 0x00010000; else Ly_a[8] &= ~0x00010000UL; if (Ly_a[6] & 0x00010000) Ly_a[7] |= 0x00010000; else Ly_a[7] &= ~0x00010000UL; if (Ly_a[5] & 0x00010000) Ly_a[6] |= 0x00010000; else Ly_a[6] &= ~0x00010000UL; if (Ly_a[4] & 0x00010000) Ly_a[5] |= 0x00010000; else Ly_a[5] &= ~0x00010000UL; if (Ly_a[3] & 0x00010000) Ly_a[4] |= 0x00010000; else Ly_a[4] &= ~0x00010000UL; if (Ly_a[2] & 0x00010000) Ly_a[3] |= 0x00010000; else Ly_a[3] &= ~0x00010000UL; if (Ly_a[1] & 0x00010000) Ly_a[2] |= 0x00010000; else Ly_a[2] &= ~0x00010000UL; Ly_a[1] &= ~0x00010000UL; // 末端12の処理 if (Ly_a[9] & 0x00020000) L10count[12] = 3; else L10count[12]--; // 最下段は3回光ったままにする if (L10count[12] < 0) L10count[12] = 0; if (L10count[12] > 0 ) Ly_a[10] |= 0x00020000; else Ly_a[10] &= ~0x00020000UL; if (Ly_a[8] & 0x00020000) Ly_a[9] |= 0x00020000; else Ly_a[9] &= ~0x00020000UL; if (Ly_a[7] & 0x00020000) Ly_a[8] |= 0x00020000; else Ly_a[8] &= ~0x00020000UL; if (Ly_a[6] & 0x00020000) Ly_a[7] |= 0x00020000; else Ly_a[7] &= ~0x00020000UL; if (Ly_a[5] & 0x00020000) Ly_a[6] |= 0x00020000; else Ly_a[6] &= ~0x00020000UL; if (Ly_a[4] & 0x00020000) Ly_a[5] |= 0x00020000; else Ly_a[5] &= ~0x00020000UL; if (Ly_a[3] & 0x00020000) Ly_a[4] |= 0x00020000; else Ly_a[4] &= ~0x00020000UL; if (Ly_a[2] & 0x00020000) Ly_a[3] |= 0x00020000; else Ly_a[3] &= ~0x00020000UL; if (Ly_a[1] & 0x00020000) Ly_a[2] |= 0x00020000; else Ly_a[2] &= ~0x00020000UL; Ly_a[1] &= ~0x00020000UL; // 末端13の処理 if (Ly_a[9] & 0x00040000) L10count[13] = 3; else L10count[13]--; // 最下段は3回光ったままにする if (L10count[13] < 0) L10count[13] = 0; if (L10count[13] > 0 ) Ly_a[10] |= 0x00040000; else Ly_a[10] &= ~0x00040000UL; if (Ly_a[8] & 0x00040000) Ly_a[9] |= 0x00040000; else Ly_a[9] &= ~0x00040000UL; if (Ly_a[7] & 0x00040000) Ly_a[8] |= 0x00040000; else Ly_a[8] &= ~0x00040000UL; if (Ly_a[6] & 0x00040000) Ly_a[7] |= 0x00040000; else Ly_a[7] &= ~0x00040000UL; if (Ly_a[5] & 0x00040000) Ly_a[6] |= 0x00040000; else Ly_a[6] &= ~0x00040000UL; if (Ly_a[4] & 0x00040000) Ly_a[5] |= 0x00040000; else Ly_a[5] &= ~0x00040000UL; if (Ly_a[3] & 0x00040000) Ly_a[4] |= 0x00040000; else Ly_a[4] &= ~0x00040000UL; if (Ly_a[2] & 0x00040000) Ly_a[3] |= 0x00040000; else Ly_a[3] &= ~0x00040000UL; Ly_a[2] &= ~0x00040000UL; // 末端14の処理 if (Ly_a[9] & 0x00080000) L10count[14] = 3; else L10count[14]--; // 最下段は3回光ったままにする if (L10count[14] < 0) L10count[14] = 0; if (L10count[14] > 0 ) Ly_a[10] |= 0x00080000; else Ly_a[10] &= ~0x00080000UL; if (Ly_a[8] & 0x00080000) Ly_a[9] |= 0x00080000; else Ly_a[9] &= ~0x00080000UL; if (Ly_a[7] & 0x00080000) Ly_a[8] |= 0x00080000; else Ly_a[8] &= ~0x00080000UL; if (Ly_a[6] & 0x00080000) Ly_a[7] |= 0x00080000; else Ly_a[7] &= ~0x00080000UL; if (Ly_a[5] & 0x00080000) Ly_a[6] |= 0x00080000; else Ly_a[6] &= ~0x00080000UL; if (Ly_a[4] & 0x00080000) Ly_a[5] |= 0x00080000; else Ly_a[5] &= ~0x00080000UL; if (Ly_a[3] & 0x00080000) Ly_a[4] |= 0x00080000; else Ly_a[4] &= ~0x00080000UL; Ly_a[3] &= ~0x00080000UL; // 末端15の処理 if (Ly_a[9] & 0x00100000) L10count[15] = 3; else L10count[15]--; // 最下段は3回光ったままにする if (L10count[15] < 0) L10count[14] = 0; if (L10count[15] > 0 ) Ly_a[10] |= 0x00100000; else Ly_a[10] &= ~0x00100000UL; if (Ly_a[8] & 0x00100000) Ly_a[9] |= 0x00100000; else Ly_a[9] &= ~0x00100000UL; if (Ly_a[7] & 0x00100000) Ly_a[8] |= 0x00100000; else Ly_a[8] &= ~0x00100000UL; if (Ly_a[6] & 0x00100000) Ly_a[7] |= 0x00100000; else Ly_a[7] &= ~0x00100000UL; if (Ly_a[5] & 0x00100000) Ly_a[6] |= 0x00100000; else Ly_a[6] &= ~0x00100000UL; if (Ly_a[4] & 0x00100000) Ly_a[5] |= 0x00100000; else Ly_a[5] &= ~0x00100000UL; Ly_a[4] &= ~0x00100000UL; // 末端16の処理 if (Ly_c[8] & 0x00100000) L10count[16] = 3; else L10count[16]--; // A2 最下段は4回光ったままにする if (L10count[16] < 0) L10count[16] = 0; if (L10count[16] > 0 ) Ly_c[10] |= 0x00200000; else Ly_c[10] &= ~0x00200000UL; if (Ly_c[6] & 0x00080000) Ly_c[8] |= 0x00100000; else Ly_c[8] &= ~0x00100000UL; if (Ly_c[4] & 0x00040000) Ly_c[6] |= 0x00080000; else Ly_c[6] &= ~0x00080000UL; if (Ly_c[2] & 0x00020000) Ly_c[4] |= 0x00040000; else Ly_c[4] &= ~0x00040000UL; if (Ly_c[0] & 0x00010000) Ly_c[2] |= 0x00020000; else Ly_c[2] &= ~0x00020000UL; Ly_c[0] &= ~0x00010000UL; // 末端17の処理 if (Ly_b[9] & 0x00200000) L10count[17] = 3; else L10count[17]--; // 最下段は3回光ったままにする if (L10count[17] < 0) L10count[14] = 0; if (L10count[17] > 0 ) Ly_b[10] |= 0x00400000; else Ly_b[10] &= ~0x00400000UL; if (Ly_b[8] & 0x00100000) Ly_b[9] |= 0x00200000; else Ly_b[9] &= ~0x00200000UL; if (Ly_b[7] & 0x00080000) Ly_b[8] |= 0x00100000; else Ly_b[8] &= ~0x00100000UL; if (Ly_b[6] & 0x00040000) Ly_b[7] |= 0x00080000; else Ly_b[7] &= ~0x00080000UL; if (Ly_b[5] & 0x00020000) Ly_b[6] |= 0x00040000; else Ly_b[6] &= ~0x00040000UL; if (Ly_b[4] & 0x00010000) Ly_b[5] |= 0x00020000; else Ly_b[5] &= ~0x00020000UL; Ly_b[4] &= ~0x00010000UL; // 末端18の処理 if (Ly_b[9] & 0x00200000) L10count[18] = 3; else L10count[18]--; // 最下段は3回光ったままにする if (L10count[18] < 0) L10count[18] = 0; if (L10count[18] > 0 ) Ly_b[10] |= 0x00800000; else Ly_b[10] &= ~0x00800000UL; if (Ly_b[8] & 0x00200000) Ly_b[9] |= 0x00400000; else Ly_b[9] &= ~0x00400000UL; if (Ly_b[7] & 0x00100000) Ly_b[8] |= 0x00200000; else Ly_b[8] &= ~0x00200000UL; if (Ly_b[6] & 0x00080000) Ly_b[7] |= 0x00100000; else Ly_b[7] &= ~0x00100000UL; if (Ly_b[5] & 0x00040000) Ly_b[6] |= 0x00080000; else Ly_b[6] &= ~0x00080000UL; if (Ly_b[4] & 0x00020000) Ly_b[5] |= 0x00040000; else Ly_b[5] &= ~0x00040000UL; if (Ly_b[3] & 0x00010000) Ly_b[4] |= 0x00020000; else Ly_b[4] &= ~0x00020000UL; Ly_b[3] &= ~0x00010000UL; // 末端19の処理 if (Ly_b[9] & 0x00800000) L10count[19] = 3; else L10count[19]--; // 最下段は3回光ったままにする if (L10count[19] < 0) L10count[19] = 0; if (L10count[19] > 0 ) Ly_b[10] |= 0x01000000; else Ly_b[10] &= ~0x01000000UL; if (Ly_b[8] & 0x00400000) Ly_b[9] |= 0x00800000; else Ly_b[9] &= ~0x00800000UL; if (Ly_b[7] & 0x00200000) Ly_b[8] |= 0x00400000; else Ly_b[8] &= ~0x00400000UL; if (Ly_b[6] & 0x00100000) Ly_b[7] |= 0x00200000; else Ly_b[7] &= ~0x00200000UL; if (Ly_b[5] & 0x00080000) Ly_b[6] |= 0x00100000; else Ly_b[6] &= ~0x00100000UL; if (Ly_b[4] & 0x00040000) Ly_b[5] |= 0x00080000; else Ly_b[5] &= ~0x00080000UL; if (Ly_b[3] & 0x00020000) Ly_b[4] |= 0x00040000; else Ly_b[4] &= ~0x00040000UL; if (Ly_b[2] & 0x00010000) Ly_b[3] |= 0x00020000; else Ly_b[3] &= ~0x00020000UL; Ly_b[2] &= ~0x00010000UL; // 末端20の処理 if (Ly_b[9] & 0x00800000) L10count[20] = 3; else L10count[20]--; // 最下段は3回光ったままにする if (L10count[20] < 0) L10count[20] = 0; if (L10count[20] > 0 ) Ly_b[10] |= 0x02000000; else Ly_b[10] &= ~0x02000000UL; if (Ly_b[8] & 0x00800000) Ly_b[9] |= 0x01000000; else Ly_b[9] &= ~0x01000000UL; if (Ly_b[7] & 0x00400000) Ly_b[8] |= 0x00800000; else Ly_b[8] &= ~0x00800000UL; if (Ly_b[6] & 0x00200000) Ly_b[7] |= 0x00400000; else Ly_b[7] &= ~0x00400000UL; if (Ly_b[5] & 0x00100000) Ly_b[6] |= 0x00200000; else Ly_b[6] &= ~0x00200000UL; if (Ly_b[4] & 0x00080000) Ly_b[5] |= 0x00100000; else Ly_b[5] &= ~0x00100000UL; if (Ly_b[3] & 0x00040000) Ly_b[4] |= 0x00080000; else Ly_b[4] &= ~0x00080000UL; if (Ly_b[2] & 0x00020000) Ly_b[3] |= 0x00040000; else Ly_b[3] &= ~0x00040000UL; if (Ly_b[1] & 0x00010000) Ly_b[2] |= 0x00020000; else Ly_b[2] &= ~0x00020000UL; Ly_b[1] &= ~0x00010000UL; // 末端21の処理 if (Ly_b[9] & 0x00800000) L10count[21] = 3; else L10count[21]--; // 最下段は3回光ったままにする if (L10count[21] < 0) L10count[21] = 0; if (L10count[21] > 0 ) Ly_b[10] |= 0x04000000; else Ly_b[10] &= ~0x04000000UL; if (Ly_b[8] & 0x00800000) Ly_b[9] |= 0x02000000; else Ly_b[9] &= ~0x02000000UL; if (Ly_b[7] & 0x00400000) Ly_b[8] |= 0x01000000; else Ly_b[8] &= ~0x01000000UL; if (Ly_b[6] & 0x00200000) Ly_b[7] |= 0x00800000; else Ly_b[7] &= ~0x00800000UL; if (Ly_b[5] & 0x00100000) Ly_b[6] |= 0x00400000; else Ly_b[6] &= ~0x00400000UL; if (Ly_b[4] & 0x00080000) Ly_b[5] |= 0x00200000; else Ly_b[5] &= ~0x00200000UL; if (Ly_b[3] & 0x00040000) Ly_b[4] |= 0x00100000; else Ly_b[4] &= ~0x00100000UL; if (Ly_b[2] & 0x00020000) Ly_b[3] |= 0x00080000; else Ly_b[3] &= ~0x00080000UL; if (Ly_b[1] & 0x00020000) Ly_b[2] |= 0x00040000; else Ly_b[2] &= ~0x00040000UL; Ly_b[1] &= ~0x00020000UL; } void dimming(int c) { // ゆっくり増光、減光 float x, ratio; bMag = 0.0; // 一旦光量ゼロに設定 show(10); // 明るさ設定値を反映させる allOn(); // 全点灯 x = OCR2B; // 開始時の明るさを記録 ratio = pow(2.0 * x, 1.0 / 40.0); // 明るさを2倍にするための増光比率を計算 for (int j = 0; j < c; j++) { // 指定回数 bMag = 1.0 / x; for (int i = 0; i <= 40; i++) { // 等比級数で増光 bMag *= ratio; // 値を補正 show(30); } for (int i = 40; i >= 0; i--) { // 減光 bMag /= ratio; show(30); } show(100); } clearArray(); // パターンメモリーを消す bMag = 1.0; // 明るさ補正係数をデフォルトに戻す // show(500); // 最後に消灯 } void ledOff() { // ポート操作で全LED消灯(LEDピンを全て入力でLowに設定) PORTD &= B00000011; // D2-7をLOW PORTB &= B11100000; // D8-12をLOW PORTC &= B11111110; // A0をLow DDRD &= B00000010; // D2-7を入力にアサイン(D0,D1はシリアル) DDRB &= B11100000; // D8-12を入力にアサイン DDRC &= B11111110; // A0を入力にアサイン } void clearArray() { // パターンメモリー消去 for (int i = 0; i < 11; i++) { Ly[i] = 0; Ly_a[i] = 0; Ly_b[i] = 0; Ly_c[i] = 0; } } void allOn() { // パターンメモリーの全LEDをONにする) Ly[0] = 0x00018000; Ly[1] = 0x0003C000; Ly[2] = 0x0007E000; Ly[3] = 0x000FF000; Ly[4] = 0x001FF800; Ly[5] = 0x003FFC00; Ly[6] = 0x007FFE00; Ly[7] = 0x00FFFF00; Ly[8] = 0x01FFFF80; Ly[9] = 0x03FFFFC0; Ly[10] = 0x07FFFFE0; } void spiralUp() { // スパイラル上昇 Ly[0] &= 0x00018000; // 表示領域外をクリア Ly[1] &= 0x0003C000; Ly[2] &= 0x0007E000; Ly[3] &= 0x000FF000; Ly[4] &= 0x001FF800; Ly[5] &= 0x003FFC00; Ly[6] &= 0x007FFE00; Ly[7] &= 0x00FFFF00; Ly[8] &= 0x01FFFF80; Ly[9] &= 0x03FFFFC0; Ly[10] &= 0x07FFFFE0; Ly[0] = Ly[0] << 1; if (Ly[1] & 0x00020000) Ly[0] |= 0x00008000; // Ly[1]の左端が1だったら、Ly[0]の右端を1にする Ly[1] = Ly[1] << 1; if (Ly[2] & 0x00040000) Ly[1] |= 0x00004000; // Ly[2]の左端が1だったら、Ly[1]の右端を1にする Ly[2] = Ly[2] << 1; if (Ly[3] & 0x00080000) Ly[2] |= 0x00002000; // Ly[3]の左端が1だったら、Ly[2]の右端を1にする Ly[3] = Ly[3] << 1; if (Ly[4] & 0x00100000) Ly[3] |= 0x00001000; // Ly[4]の左端が1だったら、Ly[3]の右端を1にする Ly[4] = Ly[4] << 1; if (Ly[5] & 0x00200000) Ly[4] |= 0x00000800; // Ly[5]の左端が1だったら、Ly[4]の右端を1にする Ly[5] = Ly[5] << 1; if (Ly[6] & 0x00400000) Ly[5] |= 0x00000400; // Ly[6]の左端が1だったら、Ly[5]の右端を1にする Ly[6] = Ly[6] << 1; if (Ly[7] & 0x00800000) Ly[6] |= 0x00000200; // Ly[7]の左端が1だったら、Ly[6]の右端を1にする Ly[7] = Ly[7] << 1; if (Ly[8] & 0x01000000) Ly[7] |= 0x00000100; // Ly[8]の左端が1だったら、Ly[7]の右端を1にする Ly[8] = Ly[8] << 1; if (Ly[9] & 0x02000000) Ly[8] |= 0x00000080; // Ly[9]の左端が1だったら、Ly[8]の右端を1にする Ly[9] = Ly[9] << 1; if (Ly[10] & 0x04000000) Ly[9] |= 0x00000040; // Ly[10]の左端が1だったら、Ly[9]の右端を1にする Ly[10] = Ly[10] << 1; } void show(unsigned long t) { // 見せるために指定時間待機。同時に調光計算を行う int x; delay(t); if (digitalRead(BRIGHT_MODE_PIN) == LOW) { // 可変抵抗による明るさ調整が有効だったら x = analogRead(BRIGHTNESS_PIN); // 明るさセンサの値を読む x = map(x, 0, 1023, 10, 240); // ADCの値を10-240の範囲にスケーリング } else { // 可変抵抗を使用しない場合は x = map(BRIGHT, 0, 100, 10, 240); // プログラムの設定値のBRIGHTの値を使う } x = x * bMag + bOffset; // 明るさ補正計算 bSet = constrain(x, 0, 240); // 最終的な明るさ(割込みルーチンでPWMの設定値として使用) } void tc2Setup() { // ダイナミック点灯用のTC2の設定 // 設定方法は居酒屋ガレージ日記さんから下記の記事で教えてもらった。感謝! // http://igarage.cocolog-nifty.com/blog/2020/12/post-4c28b8.html cli(); // 割込禁止 TCCR2B = 0x00; // タイマー2いったん停止 TCCR2A = 0b00000010; // あらためてモード設定 // |||| ++--- WGM: CTCモード OCR2Aでクリア // ||++------- COM2B D3 PD3 標準ポート操作(OC2A切断) // ++--------- COM2A D11 PB3 標準ポート操作(OC2B切断) TCCR2B = 0b00000100; // クロック設定 1/64 (段数増加に伴いチラツキ防止のため高速化) // |+++--- CS:1/64 : 250kHz(4μsステップ) // +------ WGM02 /* //  (下記は変更前) TCCR2B = 0b00000101; // クロック設定 1/128 // |+++--- CS:1/128 : 125kHz(8μsステップ) // +------ WGM02 */ OCR2A = 250 - 1; // 250カウント周期(1ms周期で割り込み) OCR2B = 10 - 1; // 10カウント(40us)で割り込み(値は仮設定) TIMSK2 = 0b00000110; // ||+---- TOIE2 オーバーフロー割り込みは無し // |+----- OCIE2A コンペアマッチA割り込み有効 // +------ OCIE2B コンペアマッチB割り込み有効 sei(); // 割込許可 } ISR(TIMER2_COMPA_vect) { // タイマー2 A割り込み(指定LEDを点灯),1ms周期で割り込み static int scanN = 0; // リフレッシュ位置カウンタ static int ttt = 0; // 経過時間カウンタ ttt++; if (ttt >= 1000) { // 1秒経ったら ttt = 0; timeElapsed++; // 表示時間タイマーを1秒インクリメント(値は自動消灯タイマーで使用) } if (bSet > 0) { // 明るさ設定値が0以上なら(bSetは8ビットなので割込み禁止しなくてもOK) ledOff(); // 全LED消灯(舞台裏を見せないために消灯) switch (scanN) { // スキャン番号に対応したLEDを点灯(時分割で点灯される) case 0: d2High(); break; case 1: d3High(); break; case 2: d4High(); break; case 3: d5High(); break; case 4: d6High(); break; case 5: d7High(); break; case 6: d8High(); break; case 7: d9High(); break; case 8: d10High(); break; case 9: d11High(); break; case 10: d12High(); break; case 11: a0High(); break; default: break; } } scanN ++; // スキャン番号を更新 if (scanN >= 12) { // 上限超えたらゼロに戻す scanN = 0; } // scanN = 11; // デバッグ用に値を強制セット } ISR(TIMER2_COMPB_vect) { // タイマー2 B割り込み(消灯と明るさ設定) int bSetBuff; ledOff(); // 全LED消灯 bSetBuff = bSet; // 処理中に値が変わると困るのでコピー(bSetは8ビットなので割込み禁止しなくてもOK) if (bSetBuff <= 0) { // 0かマイナスなら OCR2B = 0; // OCR2Bに0を設定(0を設定しても最小時間光るので COMPA 側で強制消灯させる) } else { // そうでなければ(1以上なら) OCR2B = bSetBuff - 1; // マイナス1した値を設定 } } // チャーリープレクシングで該当するLEDを点灯 void d2High() { // D2からHighを出力し、指定のLEDを点灯(相手のポートをLowにする) if ( Ly[10] & 0x02000000 ) DDRC |= B00000001; // A0 if ( Ly[10] & 0x00800000 ) DDRB |= B00010000; // D12 if ( Ly[10] & 0x00200000 ) DDRB |= B00001000; // D11 if ( Ly[10] & 0x00080000 ) DDRB |= B00000100; // D10 if ( Ly[10] & 0x00020000 ) DDRB |= B00000010; // D9 if ( Ly[10] & 0x00008000 ) DDRB |= B00000001; // D8 if ( Ly[10] & 0x00002000 ) DDRD |= B10000000; // D7 if ( Ly[10] & 0x00000800 ) DDRD |= B01000000; // D6 if ( Ly[10] & 0x00000200 ) DDRD |= B00100000; // D5 if ( Ly[10] & 0x00000080 ) DDRD |= B00010000; // D4 if ( Ly[10] & 0x00000020 ) DDRD |= B00001000; // D3 DDRD |= B00000100; // D2を出力にアサイン PORTD |= B00000100; // D2をHigh。これでLED点灯(光量最小化のため最後にやる) } void a0High() { // A0からHighを出力し、指定のLEDを点灯(相手のポートをLowにする) if ( Ly[9] & 0x01000000 ) DDRB |= B00010000; // D12 if ( Ly[9] & 0x00400000 ) DDRB |= B00001000; // D11 if ( Ly[9] & 0x00100000 ) DDRB |= B00000100; // D10 if ( Ly[9] & 0x00040000 ) DDRB |= B00000010; // D9 if ( Ly[9] & 0x00010000 ) DDRB |= B00000001; // D8 if ( Ly[9] & 0x00004000 ) DDRD |= B10000000; // D7 if ( Ly[9] & 0x00001000 ) DDRD |= B01000000; // D6 if ( Ly[9] & 0x00000400 ) DDRD |= B00100000; // D5 if ( Ly[9] & 0x00000100 ) DDRD |= B00010000; // D4 if ( Ly[9] & 0x00000040 ) DDRD |= B00001000; // D3 if ( Ly[10] & 0x04000000 ) DDRD |= B00000100; // D2 DDRC |= B00000001; // A0を出力にアサイン PORTC |= B00000001; // A0をHigh。これでLED点灯(光量最小化のため最後にやる) } void d3High() { // D3からHighを出力し、指定のLEDを点灯 if ( Ly[8] & 0x00800000 ) DDRB |= B00010000; // D12 if ( Ly[8] & 0x00200000 ) DDRB |= B00001000; // D11 if ( Ly[8] & 0x00080000 ) DDRB |= B00000100; // D10 if ( Ly[8] & 0x00020000 ) DDRB |= B00000010; // D9 if ( Ly[8] & 0x00008000 ) DDRB |= B00000001; // D8 if ( Ly[8] & 0x00002000 ) DDRD |= B10000000; // D7 if ( Ly[8] & 0x00000800 ) DDRD |= B01000000; // D6 if ( Ly[8] & 0x00000200 ) DDRD |= B00100000; // D5 if ( Ly[8] & 0x00000080 ) DDRD |= B00010000; // D4 if ( Ly[9] & 0x00000080 ) DDRC |= B00000001; // A0 if ( Ly[10] & 0x00000040 ) DDRD |= B00000100; // D2 DDRD |= B00001000; // D3を出力にアサイン PORTD |= B00001000; // D3をHigh(これでLEDが光る) } void d12High() { // D12からHighを出力し、指定のLEDを点灯 if ( Ly[7] & 0x00400000 ) DDRB |= B00001000; // D11 if ( Ly[7] & 0x00100000 ) DDRB |= B00000100; // D10 if ( Ly[7] & 0x00040000 ) DDRB |= B00000010; // D9 if ( Ly[7] & 0x00010000 ) DDRB |= B00000001; // D8 if ( Ly[7] & 0x00004000 ) DDRD |= B10000000; // D7 if ( Ly[7] & 0x00001000 ) DDRD |= B01000000; // D6 if ( Ly[7] & 0x00000400 ) DDRD |= B00100000; // D5 if ( Ly[7] & 0x00000100 ) DDRD |= B00010000; // D4 if ( Ly[8] & 0x01000000 ) DDRD |= B00001000; // D3 if ( Ly[9] & 0x02000000 ) DDRC |= B00000001; // A0 if ( Ly[10] & 0x01000000 ) DDRD |= B00000100; // D2 DDRB |= B00010000; // D12を出力にアサイン PORTB |= B00010000; // D12をHigh(これでLEDが光る) } void d4High() { // D4からHighを出力し、指定のLEDを点灯 if ( Ly[6] & 0x00200000 ) DDRB |= B00001000; // D11 if ( Ly[6] & 0x00080000 ) DDRB |= B00000100; // D10 if ( Ly[6] & 0x00020000 ) DDRB |= B00000010; // D9 if ( Ly[6] & 0x00008000 ) DDRB |= B00000001; // D8 if ( Ly[6] & 0x00002000 ) DDRD |= B10000000; // D7 if ( Ly[6] & 0x00000800 ) DDRD |= B01000000; // D6 if ( Ly[6] & 0x00000200 ) DDRD |= B00100000; // D5 if ( Ly[7] & 0x00000200 ) DDRB |= B00010000; // D12 if ( Ly[8] & 0x00000100 ) DDRD |= B00001000; // D3 if ( Ly[9] & 0x00000200 ) DDRC |= B00000001; // A0 if ( Ly[10] & 0x00000100 ) DDRD |= B00000100; // D2 DDRD |= B00010000; // D4を出力にアサイン PORTD |= B00010000; // D4をHigh(これでLEDが光る) } void d11High() { // D11からHighを出力し、指定のLEDを点灯 if ( Ly[5] & 0x00100000 ) DDRB |= B00000100; // D10 if ( Ly[5] & 0x00040000 ) DDRB |= B00000010; // D9 if ( Ly[5] & 0x00010000 ) DDRB |= B00000001; // D8 if ( Ly[5] & 0x00004000 ) DDRD |= B10000000; // D7 if ( Ly[5] & 0x00001000 ) DDRD |= B01000000; // D6 if ( Ly[5] & 0x00000400 ) DDRD |= B00100000; // D5 if ( Ly[6] & 0x00400000 ) DDRD |= B00010000; // D4 if ( Ly[7] & 0x00800000 ) DDRB |= B00010000; // D12 if ( Ly[8] & 0x00400000 ) DDRD |= B00001000; // D3 if ( Ly[9] & 0x00800000 ) DDRC |= B00000001; // A0 if ( Ly[10] & 0x00400000 ) DDRD |= B00000100; // D2 DDRB |= B00001000; // D11を出力にアサイン PORTB |= B00001000; // D11をHigh(これでLEDが光る) } void d5High() { // D5からHighを出力し、指定のLEDを点灯 if ( Ly[4] & 0x00080000 ) DDRB |= B00000100; // D10 if ( Ly[4] & 0x00020000 ) DDRB |= B00000010; // D9 if ( Ly[4] & 0x00008000 ) DDRB |= B00000001; // D8 if ( Ly[4] & 0x00002000 ) DDRD |= B10000000; // D7 if ( Ly[4] & 0x00000800 ) DDRD |= B01000000; // D6 if ( Ly[5] & 0x00000800 ) DDRB |= B00001000; // D11 if ( Ly[6] & 0x00000400 ) DDRD |= B00010000; // D4 if ( Ly[7] & 0x00000800 ) DDRB |= B00010000; // D12 if ( Ly[8] & 0x00000400 ) DDRD |= B00001000; // D3 if ( Ly[9] & 0x00000800 ) DDRC |= B00000001; // A0 if ( Ly[10] & 0x00000400 ) DDRD |= B00000100; // D2 DDRD |= B00100000; // D5を出力にアサイン PORTD |= B00100000; // D5をHigh(これでLEDが光る) } void d10High() { // D10からHighを出力し、指定のLEDを点灯 if ( Ly[3] & 0x00040000 ) DDRB |= B00000010; // D9 if ( Ly[3] & 0x00010000 ) DDRB |= B00000001; // D8 if ( Ly[3] & 0x00004000 ) DDRD |= B10000000; // D7 if ( Ly[3] & 0x00001000 ) DDRD |= B01000000; // D6 if ( Ly[4] & 0x00100000 ) DDRD |= B00100000; // D5 if ( Ly[5] & 0x00200000 ) DDRB |= B00001000; // D11 if ( Ly[6] & 0x00100000 ) DDRD |= B00010000; // D4 if ( Ly[7] & 0x00200000 ) DDRB |= B00010000; // D12 if ( Ly[8] & 0x00100000 ) DDRD |= B00001000; // D3 if ( Ly[9] & 0x00200000 ) DDRC |= B00000001; // A0 if ( Ly[10] & 0x00100000 ) DDRD |= B00000100; // D2 DDRB |= B00000100; // D10を出力にアサイン PORTB |= B00000100; // D10をHigh(これでLEDが光る) } void d6High() { // D6からHighを出力し、指定のLEDを点灯 if ( Ly[2] & 0x00020000 ) DDRB |= B00000010; // D9 if ( Ly[2] & 0x00008000 ) DDRB |= B00000001; // D8 if ( Ly[2] & 0x00002000 ) DDRD |= B10000000; // D7 if ( Ly[3] & 0x00002000 ) DDRB |= B00000100; // D10 if ( Ly[4] & 0x00001000 ) DDRD |= B00100000; // D5 if ( Ly[5] & 0x00002000 ) DDRB |= B00001000; // D11 if ( Ly[6] & 0x00001000 ) DDRD |= B00010000; // D4 if ( Ly[7] & 0x00002000 ) DDRB |= B00010000; // D12 if ( Ly[8] & 0x00001000 ) DDRD |= B00001000; // D3 if ( Ly[9] & 0x00002000 ) DDRC |= B00000001; // A0 if ( Ly[10] & 0x00001000 ) DDRD |= B00000100; // D2 DDRD |= B01000000; // D6を出力にアサイン PORTD |= B01000000; // D6をHigh(これでLEDが光る) } void d9High() { // D9からHighを出力し、指定のLEDを点灯 if ( Ly[1] & 0x00010000 ) DDRB |= B00000001; // D8 if ( Ly[1] & 0x00004000 ) DDRD |= B10000000; // D7 if ( Ly[2] & 0x00040000 ) DDRD |= B01000000; // D6 if ( Ly[3] & 0x00080000 ) DDRB |= B00000100; // D10 if ( Ly[4] & 0x00040000 ) DDRD |= B00100000; // D5 if ( Ly[5] & 0x00080000 ) DDRB |= B00001000; // D11 if ( Ly[6] & 0x00040000 ) DDRD |= B00010000; // D4 if ( Ly[7] & 0x00080000 ) DDRB |= B00010000; // D12 if ( Ly[8] & 0x00040000 ) DDRD |= B00001000; // D3 if ( Ly[9] & 0x00080000 ) DDRC |= B00000001; // A0 if ( Ly[10] & 0x00040000 ) DDRD |= B00000100; // D2 DDRB |= B00000010; // D9を出力にアサイン PORTB |= B00000010; // D9をHigh(これでLEDが光る) } void d7High() { // D7からHighを出力し、指定のLEDを点灯 if ( Ly[0] & 0x00008000 ) DDRB |= B00000001; // D8 if ( Ly[1] & 0x00008000 ) DDRB |= B00000010; // D9 if ( Ly[2] & 0x00004000 ) DDRD |= B01000000; // D6 if ( Ly[3] & 0x00008000 ) DDRB |= B00000100; // D10 if ( Ly[4] & 0x00004000 ) DDRD |= B00100000; // D5 if ( Ly[5] & 0x00008000 ) DDRB |= B00001000; // D11 if ( Ly[6] & 0x00004000 ) DDRD |= B00010000; // D4 if ( Ly[7] & 0x00008000 ) DDRB |= B00010000; // D12 if ( Ly[8] & 0x00004000 ) DDRD |= B00001000; // D3 if ( Ly[9] & 0x00008000 ) DDRC |= B00000001; // A0 if ( Ly[10] & 0x00004000 ) DDRD |= B00000100; // D2 DDRD |= B10000000; // D7を出力にアサイン PORTD |= B10000000; // D7をHigh(これでLEDが光る) } void d8High() { // D8からHighを出力し、指定のLEDを点灯 if ( Ly[0] & 0x00010000 ) DDRD |= B10000000; // D7 if ( Ly[1] & 0x00020000 ) DDRB |= B00000010; // D9 if ( Ly[2] & 0x00010000 ) DDRD |= B01000000; // D6 if ( Ly[3] & 0x00020000 ) DDRB |= B00000100; // D10 if ( Ly[4] & 0x00010000 ) DDRD |= B00100000; // D5 if ( Ly[5] & 0x00020000 ) DDRB |= B00001000; // D11 if ( Ly[6] & 0x00010000 ) DDRD |= B00010000; // D4 if ( Ly[7] & 0x00020000 ) DDRB |= B00010000; // D12 if ( Ly[8] & 0x00010000 ) DDRD |= B00001000; // D3 if ( Ly[9] & 0x00020000 ) DDRC |= B00000001; // A0 if ( Ly[10] & 0x00010000 ) DDRD |= B00000100; // D2 DDRB |= B00000001; // D8を出力にアサイン PORTB |= B00000001; // D8をHigh(これでLEDが光る) }