/* AVR MEGA 328P用 ライツアウトプログラム * このプログラムを使用した、如何なる損害にも責任を負いません * 著作権は放棄してませんが、個人での使用などはご自由にどうぞ * https://miso-engine.hatenablog.com/entry/2015/07/20/221014 TimerOneを使用したタイマー割り込み tone(pin,frequency, duration)//ピン番号、周波数、出力時間[ms](オプション) noTone(pin)//tone()の停止 スリープ(powerDown)外部割込み復帰の為にD2とD12の配線を入れ替える 今回は割り込み0(D2pin) */ //#include #include #include //スリープを使えるようにする #include //割込みが使えるようにする int Tpin [5] = {4,3,12,1,0};//トランジスタ接続ピン int SW[5]={19,18,17,16,15};//SWピン int LEDpin [5] = {9,8,7,6,5};//LED接続ピン int SUB[3]={2,13,14};//ソフトキー 左、中央、右 int EDITLED = 11;//右端LED int SPK =10;//スピーカー接続 boolean transistor [5] = {0};//トランジスタ出力保存 boolean LED [5] = {0};//LED出力保存 /*ステージ構成*/ boolean STAGE_01[5][5]= {{1,1,0,1,1}, {1,0,1,0,1}, {0,1,1,1,0}, {1,0,1,0,1}, {1,1,0,1,1}}; boolean STAGE_02[5][5]= {{0,0,0,0,0}, {1,1,0,1,1}, {0,0,0,0,0}, {1,1,0,1,1}, {0,0,0,0,0}}; boolean STAGE_03[5][5]= {{0,1,0,1,0}, {0,0,1,0,0}, {0,1,1,1,0}, {0,0,1,0,0}, {0,1,0,1,0}}; boolean STAGE_04[5][5]= {{1,0,1,0,1}, {0,1,0,1,0}, {1,0,1,0,1}, {0,1,0,1,0}, {1,0,1,0,1}}; boolean STAGE_05[5][5]= {{1,0,1,0,1}, {0,0,0,0,0}, {1,0,1,0,1}, {0,0,0,0,0}, {1,0,1,0,1}}; boolean STAGE_06[5][5]= {{1,1,1,0,0}, {0,1,0,1,1}, {1,0,1,0,1}, {1,0,0,0,1}, {0,1,1,1,0}}; boolean STAGE_07[5][5]= {{0,1,1,1,0}, {0,0,0,1,0}, {1,0,1,0,0}, {0,1,1,0,1}, {0,1,0,1,1}}; boolean STAGE_08[5][5]= {{1,0,1,1,1}, {1,1,0,1,1}, {1,1,1,0,1}, {0,1,0,0,1}, {0,1,0,1,0}}; boolean STAGE_09[5][5]= {{0,1,0,1,0}, {0,1,0,1,0}, {1,1,0,1,1}, {1,0,0,0,1}, {0,1,0,1,0}}; boolean STAGE_10[5][5]= {{1,0,0,0,1}, {0,1,0,1,0}, {0,0,0,0,0}, {0,1,0,1,0}, {1,0,0,0,1}}; boolean STAGE_11[5][5]= {{0,1,1,1,0}, {1,1,0,1,1}, {1,0,1,0,1}, {1,1,0,1,1}, {0,1,1,1,0}}; boolean STAGE_12[5][5]= {{0,1,1,0,0}, {1,1,0,1,1}, {1,0,0,1,1}, {0,1,0,0,0}, {1,1,0,0,0}}; boolean STAGE_13[5][5]= {{0,1,1,1,1}, {0,0,1,1,1}, {0,1,1,0,1}, {1,0,1,1,0}, {0,0,1,0,0}}; boolean STAGE_14[5][5]= {{0,1,0,1,0}, {1,0,1,0,1}, {0,1,1,1,0}, {1,0,1,0,1}, {0,1,0,1,0}}; boolean STAGE_15[5][5]= {{0,1,0,1,0}, {1,1,0,1,1}, {0,0,0,0,0}, {1,1,0,1,1}, {0,1,0,1,0}}; boolean STAGE_16[5][5]= {{0,0,0,1,0}, {1,0,0,0,1}, {1,0,1,1,1}, {0,0,0,0,1}, {0,1,1,1,0}}; boolean STAGE_17[5][5]= {{0,0,1,0,1}, {0,1,1,1,1}, {1,0,1,1,1}, {1,0,0,0,0}, {1,1,1,1,1}}; boolean STAGE_18[5][5]= {{1,1,0,1,1}, {0,0,0,0,0}, {0,0,1,0,1}, {0,1,0,1,0}, {0,1,0,0,0}}; boolean STAGE_19[5][5]= {{0,1,0,1,0}, {1,0,0,1,1}, {0,0,1,0,1}, {1,1,1,1,1}, {1,0,0,0,0}}; boolean STAGE_20[5][5]= {{1,0,1,0,0}, {0,1,0,1,0}, {1,0,0,0,1}, {0,1,0,1,0}, {0,0,1,0,1}}; boolean STAGE_21[5][5]= {{0,1,0,1,0}, {1,1,0,1,1}, {0,0,0,0,0}, {0,1,0,1,0}, {1,0,0,0,1}}; boolean STAGE_22[5][5]= {{0,1,1,1,0}, {1,0,0,0,1}, {1,0,1,0,1}, {1,0,0,0,1}, {0,1,1,1,0}}; boolean STAGE_23[5][5]= {{1,1,1,1,1}, {0,0,1,0,0}, {1,1,0,1,1}, {0,0,1,0,0}, {1,1,1,1,1}}; boolean STAGE_24[5][5]= {{0,1,0,0,0}, {0,0,1,0,1}, {0,1,0,1,0}, {1,0,1,0,0}, {0,0,0,1,0}}; boolean STAGE_25[5][5]= {{1,0,1,1,0}, {0,1,1,1,0}, {1,1,0,0,0}, {0,1,0,1,0}, {1,1,0,0,0}}; boolean LEDbit[5][5]={0}; //メイン表示用 MOD=0 boolean STAGE_bit[5][5]={0}; //クリアステージ保存 MOD=1 boolean STAGE_EDIT[5][5]={0}; //EDITMODE MOD=2 //int MOD =0;//表示モード選択 boolean ON=0; //ビット書き換えフラグ boolean SUB_L=0; boolean old_SUB_L=0; boolean SUB_C=0; boolean old_SUB_C=0; boolean SUB_R=0;//EDITMODフラグ boolean old_SUB_R=0; volatile boolean SWbit[5][5]={0}; volatile boolean SWbit_old[5][5]={0}; volatile int L = 0; volatile int N = 0; volatile int n = 0; volatile int E = 0;//EDITモードで使用 volatile int i =0;//行制御 volatile int T =0; volatile int O =0; volatile int I =0;//LEDbit書き換え用 int SLEEPcnt=0; int SLEEPmin=0; int PlaySTAGE; int C =0; //int t =LOW; //int s =LOW; //int Scr =0; volatile int phase = 0;//モード切替用のフラグ void SLEEP_set(){ for(n=0;n<5;n++){ //各種ピン出力OFF digitalWrite(Tpin[n],0); digitalWrite(LEDpin[n],0); } digitalWrite(SPK,0); digitalWrite(EDITLED,0); sleep_enable(); set_sleep_mode(SLEEP_MODE_PWR_DOWN);//スリープモード設定 SLEEPcnt=0; SLEEPmin=0; //Sleep::powerDownAndWakeupExternalEvent(0); sei(); attachInterrupt(0,wakeup , RISING);//割り込み0(D2pin)に変化があれば割り込み //RISING D2がLOW → HIGH で割り込み //CHANGE D2に変化があれば割り込み /*LOW:信号がLOWの状態(入力がない場合)、LOWの限りは割り込み処理が何回でも発生します。 CHANGE:LOW⇔HIGHで変化したときに発生 RISING:LOW→HIGHに変化したときに発生 FALLING:HIGH→LOWに変化したときに発生*/ //set_sleep_mode(SLEEP_MODE_PWR_DOWN);//スリープモードをパワーダウンに設定 sleep_cpu(); sleep_disable();//スリープの無効 /* set_sleep_mode(SLEEP_MODE_IDLE); * set_sleep_mode(SLEEP_MODE_ADC); // ADC低減モードの処理 set_sleep_mode(SLEEP_MODE_PWR_SAVE); // パワーセーブモードの処理q set_sleep_mode(SLEEP_MODE_STANDBY); // スタンバイモードの処理 set_sleep_mode(SLEEP_MODE_PWR_DOWN); // パワーダウンモードの処理 */ } void wakeup(){ sleep_disable();//スリープの無効 cli(); // Timer1.initialize(1000); // 1000μs period=1ms // Timer1.attachInterrupt(flash); tone(SPK,2000,50); detachInterrupt(0); // 割り込み停止 SLEEPcnt=0; SLEEPmin=0; SUB_L=1; old_SUB_L=1; } void LEDmatrix(){ //LEDを1列づつ表示 i,L,N for(i=0;i<5;i++){transistor[i]=0; //トランジスタ初期化 LED[i]=LEDbit[i][L];} //各種bitから選択後、出力用に代入 transistor[L]=1; //表示列を指定 for(N=0;N<5;N++){digitalWrite(Tpin[N],0); //出力の初期化 digitalWrite(LEDpin[N],0);} digitalWrite(Tpin[L],1); //列を指定 for(N=0;N<5;N++){digitalWrite(LEDpin[N],LED[N]);}//LEDの点灯 } void STAGE_CASE(){ for(I=0;I<5;I++){ for(N=0;N<5;N++){ switch(PlaySTAGE){ case 1: LEDbit[I][N] = STAGE_01[I][N]; break; case 2: LEDbit[I][N] = STAGE_02[I][N]; break; case 3: LEDbit[I][N] = STAGE_03[I][N]; break; case 4: LEDbit[I][N] = STAGE_04[I][N]; break; case 5: LEDbit[I][N] = STAGE_05[I][N]; break; case 6: LEDbit[I][N] = STAGE_06[I][N]; break; case 7: LEDbit[I][N] = STAGE_07[I][N]; break; case 8: LEDbit[I][N] = STAGE_08[I][N]; break; case 9: LEDbit[I][N] = STAGE_09[I][N]; break; case 10: LEDbit[I][N] = STAGE_10[I][N]; break; case 11: LEDbit[I][N] = STAGE_11[I][N]; break; case 12: LEDbit[I][N] = STAGE_12[I][N]; break; case 13: LEDbit[I][N] = STAGE_13[I][N]; break; case 14: LEDbit[I][N] = STAGE_14[I][N]; break; case 15: LEDbit[I][N] = STAGE_15[I][N]; break; case 16: LEDbit[I][N] = STAGE_16[I][N]; break; case 17: LEDbit[I][N] = STAGE_17[I][N]; break; case 18: LEDbit[I][N] = STAGE_18[I][N]; break; case 19: LEDbit[I][N] = STAGE_19[I][N]; break; case 20: LEDbit[I][N] = STAGE_20[I][N]; break; case 21: LEDbit[I][N] = STAGE_21[I][N]; break; case 22: LEDbit[I][N] = STAGE_22[I][N]; break; case 23: LEDbit[I][N] = STAGE_23[I][N]; break; case 24: LEDbit[I][N] = STAGE_24[I][N]; break; case 25: LEDbit[I][N] = STAGE_25[I][N]; break; case 26: LEDbit[I][N] = STAGE_EDIT[I][N]; break; }}} } void OP(){ if(T==0){ switch(O){ case 1: LEDbit[0][n]=1; LEDbit[4][4-n]=1; break; case 2: LEDbit[3][n]=1; LEDbit[1][4-n]=1; break; case 3: LEDbit[2][n]=1; LEDbit[2][4-n]=1; break; case 4: for(I=0;I<5;I++){LEDbit[I][n]=0;} break; case 5: phase=1; break; } } T++; if(T==50){T=0; n++; if(n==6){n=0; O++;}} } void STAGE(){ for(i=0;i<5;i++){ if((SWbit[i][L] == 1) && (SWbit_old[i][L] == 0)){ tone(SPK,1000,50); LEDbit[i][L] = 1; PlaySTAGE = 1+L+5*i; STAGE_CASE(); phase=2;//プレイモードへ ON=0; }}}//ステージ選択修了 void UD(){ //列ごとの上下の反転処理 switch(i){ case 0: LEDbit[i+1][L] = !LEDbit[i+1][L];//上隣を反転 break; case 4: LEDbit[i-1][L] = !LEDbit[i-1][L];//下隣を反転 break; default: LEDbit[i+1][L] = !LEDbit[i+1][L];//上隣を反転 LEDbit[i-1][L] = !LEDbit[i-1][L];//下隣を反転 break; } } void SW_input(){ //スイッチ読み込み for(i=0;i<5;i++){ SWbit[i][L] = digitalRead(SW[i]);} } void L_CHIKA(){ //LED反転 for(i=0;i<5;i++){ if((SWbit[i][L] == 1) && (SWbit_old[i][L] == 0)){ tone(SPK,1000,50); LEDbit[i][L] = !LEDbit[i][L]; switch(L){ case 0: LEDbit[i][L+1] = !LEDbit[i][L+1];//右隣を反転 break; case 4: LEDbit[i][L-1] = !LEDbit[i][L-1];//左隣を反転 break; default: LEDbit[i][L+1] = !LEDbit[i][L+1];//右隣を反転 LEDbit[i][L-1] = !LEDbit[i][L-1];//左隣を反転 break; } UD(); } } } void flash(){ //SW_LED(); LEDmatrix();//LEDマトリクスに表示 switch(phase){ case 0://OP_MOD OP(); break; case 1://STAGEセレクト //if(ON==0){ for(I=0;I<5;I++){ for(N=0;N<5;N++){ LEDbit[I][N] = STAGE_bit[I][N];}} //ON =1;}//STAGE_bitへ書き換え SW_input(); STAGE(); SUB_R=digitalRead(SUB[2]); //EDITMODへ移動 if((SUB_R == 1) && (old_SUB_R == 0)){ tone(SPK,1000,50); phase=4; } old_SUB_R = SUB_R; break; case 2: SW_input(); L_CHIKA(); SUB_L=digitalRead(SUB[0]); //PLAYMODへ移動 if((SUB_L == 1) && (old_SUB_L == 0)){phase=1; //ステージ選択へ戻る tone(SPK,1000,50);} old_SUB_L =SUB_L; SUB_C=digitalRead(SUB[1]); //PLAYMODへ移動 if((SUB_C == 1) && (old_SUB_C == 0)){STAGE_CASE(); //やり直し tone(SPK,800,50);} old_SUB_C =SUB_C; if(L==0){ C=0; //クリア判定 for(I=0;I<5;I++){ for(N=0;N<5;N++){ C =C+ LEDbit[I][N];}} if(C==0){ if(PlaySTAGE!=26){STAGE_bit[(PlaySTAGE-1)/5][(PlaySTAGE-1)%5]=1;} phase=3;}} break; case 3: tone(SPK,2000,500); phase=1; break; case 4://EDIT_MOD digitalWrite(EDITLED,1); if(E==0){ for(I=0;I<5;I++){ for(N=0;N<5;N++){ LEDbit[I][N]=STAGE_EDIT[I][N];}} E=1;} /**/ SUB_L=digitalRead(SUB[0]); //PLAYMODへ移動 if((SUB_L == 1) && (old_SUB_L == 0)){ phase=1; //ステージ選択へ戻る tone(SPK,1000,50); digitalWrite(EDITLED,0); E=0; } old_SUB_L =SUB_L; SUB_C=digitalRead(SUB[1]); // if((SUB_C == 1) && (old_SUB_C == 0)){E=0; //やり直し tone(SPK,800,50);} old_SUB_C =SUB_C; SW_input(); for(i=0;i<5;i++){ if((SWbit[i][L] == 1) && (SWbit_old[i][L] == 0)){ tone(SPK,1000,50); LEDbit[i][L] = !LEDbit[i][L];}} C=0; //ゼロ判定 for(I=0;I<5;I++){ for(N=0;N<5;N++){ C =C+ LEDbit[I][N];}} SUB_R=digitalRead(SUB[2]); //PLAYMODへ移動 if((SUB_R == 1) && (old_SUB_R == 0)){ for(I=0;I<5;I++){ for(N=0;N<5;N++){ STAGE_EDIT[I][N]=LEDbit[I][N];}} tone(SPK,1000,50); if(C!=0){ phase=2; PlaySTAGE=26; E=0; digitalWrite(EDITLED,0); } else{ tone(SPK,600,50); phase=1; E=0; digitalWrite(EDITLED,0); } E=0; digitalWrite(EDITLED,0); } old_SUB_R = SUB_R; break; } L++; if(L==5){ L=0; SLEEPcnt++;} if(SLEEPcnt==12000){SLEEPcnt=0;//12000一分毎にカウントアップ SLEEPmin++;} if(SLEEPmin==5){SLEEPmin=0; //5分でスリープ SLEEP_set(); }//スリープモード移行 for(i=0;i<5;i++){ if(digitalRead(SW[i])==1){ SLEEPcnt=0; SLEEPmin=0;}} for(i=0;i<3;i++){ if(digitalRead(SUB[i])==1){ SLEEPcnt=0; SLEEPmin=0;}} /* for(i=0;i<3;i++){ if(digitalRead(SUB[i])==1){ SLEEPcnt=0; SLEEPmin=0;}}*/ for(i=0;i<5;i++){ SWbit_old[i][L] = SWbit[i][L] ; } } void setup() { for(n=0;n<5;n++){ //各種ピンモード選択 pinMode(Tpin[n],OUTPUT); pinMode(LEDpin[n],OUTPUT); pinMode(SW[n],INPUT); } for(n=0;n<4;n++){ pinMode(SUB[n],INPUT);} pinMode(SPK,OUTPUT); tone(SPK,2000);//ピ delay(100); noTone(SPK); tone(SPK,1000);//ポ delay(200); noTone(SPK); // MsTimer2::set(1, flash); // 5ms period // MsTimer2::start(); Timer1.initialize(1000); // 1000μs period=1ms Timer1.attachInterrupt(flash); } void loop() { }