/* クリスマスツリーイルミネーション CPUのプルアップ抵抗を使って17個のLEDを点灯 2017/11/19 ラジオペンチ http://radiopench.blog96.fc2.com/ */ unsigned long data = 0; int i, n; void setup() { startLoop(1); // 開始表示 } // pinModeを指定していないので全部inputになる void loop() { // メインループ while (millis() < 10800000UL) { // 6時間下記を実行(3hr*3600sec*1000ms=10800000) startLoop(1); // ループ開始表示 singleR(2); // 単発右回転 singleL(2); // 単発左回転 waveR(2); // ウェ−ブ右回転 waveL(2); // ウェーブ左回転 x_rotate(3); // 単発左右同時 VrotateR(4); // 縦線右移動 VrotateL(4); // 縦線左移動 VrotateR(4); // 縦線右移動 VrotateL(4); // 縦線左移動 updown(3); // 縦上昇/降下 randomFlash(75); // ランダム点灯 } timeUp(); // 指定時間終了後は停止中表示(センターLEDフラッシュ) } void startLoop(int count) { // 開始表示パターン for (i = 0; i < count; i++) { // 指定回数 led(0); delay(1000); led(0x1FFFF); // 全点灯 delay(1000); led(0); delay(500); } } void singleR( int count) { // 1灯単発右回転点灯 for (i = 1; i <= count; i++) { data = 0x01; // タネを仕込む for (n = 0; n <= 18; n++) { // タネが外に外れるまで実行 led(data); // LED表示 data = data << 1; // 左にシフト delay(80); } delay(100); } } void singleL( int count) { // 1灯左回転点灯 for (i = 1; i <= count; i++) { data = 0x10000; // タネを仕込む for (n = 0; n <= 18; n++) { // タネが外に外れるまで実行 led(data); // ビットパターンを表示 data = data >> 1; // 右にシフト delay(80); } delay(100); } } void x_rotate( int count) { // 左右同時回転 unsigned long a, b; for (i = 1; i <= count; i++) { a = 0x00001; // 下側のタネ b = 0x10000; // 上側のタネ for (n = 0; n <= 17; n++) { data = a | b; // 上下のタネを合成して、 led(data); // 表示 a = a << 1; // 下のタネを左シフト b = b >> 1; // 上のタネを右シフト delay(100); } } } void waveR(int count) { // 波のように表示(右回り) for (i = 1; i <= count; i++) { for (n = 0; n <= 16; n++) { data |= 0x01; // 最下位に1ビット追加 led(data); // LED表示 data = data << 1; // 左にシフト delay(50); } for (n = 0; n <= 16; n++) { data = data & 0x1FFFE; // 下位ビットを消す led(data); // LED表示 data = data << 1; // 左にシフト delay(50); } } } void waveL(int count) { // 波のように表示(左周り) for (i = 1; i <= count; i++) { for (n = 0; n <= 16; n++) { data |= 0x10000; // 最上位1ビット追加 led(data); // LED表示 data = data >> 1; // 右にシフト delay(50); } for (n = 0; n <= 16; n++) { data = data & 0x0FFF; // 右端のビットを消す led(data); // LED表示 data = data >> 1; // 右にシフト delay(50); } } } void VrotateR(int count) { // 縦線右移動 for (i = 1; i <= count; i++) { led(0b00000000110101010); delay(100); led(0b00000000101010101); delay(100); led(0b10101010100000000); delay(100); led(0b01010101100000000); delay(100); } } void VrotateL(int count) { // 縦線左移動 for (i = 1; i <= count; i++) { led(0b01010101100000000); delay(100); led(0b10101010100000000); delay(100); led(0b00000000101010101); delay(100); led(0b00000000110101010); delay(100); } } void updown(int count) { // 縦上昇/降下(下から上に点灯し、逆順で消す) unsigned long a, b; for (i = 1; i <= count; i++) { a = 0; b = 0; for (n = 0; n <= 9; n++) { // 下から上に点灯 data = a | b; // 左右のタネを合成 led(data); // LED表示 a = a << 1; // 下位を繰り上げて a |= 0x01; // 開いた場所は1を埋める b = b >> 1; // 上位を繰り下げて b |= 0x10000; // 開いた場所は1を埋める delay(100); } delay(300); // 全点灯したのでちょっと間をとる for (n = 0; n <= 8; n++) { // 下から上に消灯 data = a | b; // 左右のタネを合成 led(data); // LED表示 a = a << 1; // 下位を繰り上げて a &= 0x1FF; b = b >> 1; // 上位を繰り下げて b &= 0x1FF00; delay(100); } delay(300); // for (n = 0; n <= 8; n++) { // 上から下へ点灯 data = a | b; // 左右のタネを合成 data |= 0x100; led(data); // LED表示 a = a >> 1; // a |= 0x180; b = b << 1; // b |= 0x300; delay(100); } delay(300); // for (n = 0; n <= 9; n++) { // 上から下へ消灯 data = a | b; // 左右のタネを合成 led(data); // LED表示 a = a >> 1; // a &= 0x0FF; b = b << 1; // b &= 0x1FE00; delay(100); } delay(300); // } } void randomFlash( int count) { // ランダム点灯 for (i = 1; i <= count; i++) { data = random(0, 0x20000); // 0から0x1FFFFの範囲の乱数発生 data |= 0x100; // 中央のLEDは常時点灯 led(data); // LED表示 delay(150); } } void timeUp() { for (;;) { led(0x100); delay(50); led(0); delay(3000); } } void led(unsigned long x) { // LED点灯ルーチン /* 引数に対応するビットのLEDを点灯。 入力ピンにアサインした状態で1を書くと、プルアップ抵抗が有効になりLEDが点灯。 データーは17ビット、ポートとの対応は下記 data x xxxx xxxx xxxx xxxx PORTD 76 5432 digita 2-7 PORTB 432 10 digital 8-12 PORTC 5 4321 0 A 0-5 (digital 14-19) digital 0, 1, 13はブートローダーと干渉するので使わない。 クリスマスツリーのビット位置とLEDの配置 8 ← 先端 (0x100) 7 9 6 10 5 11 4 12 3 13 2 14 1 15 0 17 */ byte d; x = x & 0x1FFFF; // 変な値を排除 // 下位6ビットを digital 2-7 に出力 (0,1はTX,RXなので使わない) d = (x << 2) & B11111100; PORTD = d; // 6ビット目から5ビットを digital 8-12に出力(13は使わない) d = (x >> 6) & B00011111; PORTB = d; // 11ビット目から6ビットを analog0-5(digital 14-19)に出力 d = (x >> 11) & B00111111; PORTC = d; }