将棋の神様〜0と1の世界〜

「三間飛車のひとくちメモ」管理人、兼「フラ盤」&「チェスクロイド」作者がおくる、将棋コラム

対局時計を自作(3)「ブザー音追加」時点のスケッチ公開

(2)で述べたように、「ブザー音追加」時点のスケッチを公開しておく。
pin13のHIGH/LOWをブザー音に利用。
次は、ダイナミック駆動用に配線済みの7セグLEDを購入し、2桁(99秒)までの秒読みに対応できるようにしたい。

#define TM_LIMIT 10  // 持ち時間

// 状態 stateCC(CCはChessClockの略)
// 1 (CNTDOWN): 秒読み状態
// 2 (CNTSTOP): 時間切れ状態
#define CNTDOWN 0
#define CNTSTOP 1
volatile int stateCC = CNTDOWN;

int countBuf = 0;  // 着手時のmillis時間保持用
int usingSec = 0;  // 使用時間

// 0〜9の7セグ表示パターン
boolean LEDArray[10][7]={ {0,0,0,0,0,0,1},
                          {1,0,0,1,1,1,1},
                          {0,0,1,0,0,1,0},
                          {0,0,0,0,1,1,0},
                          {1,0,0,1,1,0,0},
                          {0,1,0,0,1,0,0},
                          {0,1,0,0,0,0,0},
                          {0,0,0,1,1,0,1},
                          {0,0,0,0,0,0,0},
                          {0,0,0,0,1,0,0} };
// 数字表示
void dispNum(int num){
  int j;
  for(int i=0; i<7; i++){
    // pin2は割り込み処理用に空ける
    if(i>=2){ j=i+1; }
    else    { j=i; }
    digitalWrite(j,LEDArray[num%10][i]);
    // ↑現状一桁対応で、10を1にするためnum%10としている
  }
}
void setup(){
  int j;
  
  // 7セグ用
  for(int i=0; i<=7; i++){
    // pin2は割り込み処理用に空ける
    if(i>=2){ j=i+1; }
    else    { j=i; }
    pinMode(j,OUTPUT);
  }
  // ブザー用
  pinMode(13,OUTPUT);
  
  // チェスクロボタン押しで割り込み発生  
  attachInterrupt(0, pushButton, RISING);
}
void pushButton(){
  switch(stateCC){
  case CNTDOWN:
    usingSec = 0;
    countBuf = millis();  // チェスクロボタン押した時の時刻保持
    break;
  case CNTSTOP:
  default:
    break;
  }
}
void loop(){
  switch(stateCC){
  case CNTDOWN:
    usingSec = millis() - countBuf;

    // 7セグ関連
    dispNum(TM_LIMIT - usingSec/1000);  // カウントダウン表示

    // ブザー音関連
    if(usingSec <= 50){  // ボタン押し直後は鳴らさない
      digitalWrite(13,LOW);
    }      
    else if(TM_LIMIT - usingSec/1000 <= 5){  // ラスト5秒
      digitalWrite(13,HIGH);
    }
    else if(TM_LIMIT - usingSec/1000 <= 10){  // ラスト10秒
      if(usingSec%1000 >= 0 &&
         usingSec%1000 <= 50){
        digitalWrite(13,HIGH);
      }
      else{digitalWrite(13,LOW);}
    }
    else if((usingSec/1000) % 10 >= 0 && 
            (usingSec/1000) % 10 <= 50){  // それ以前は10秒毎
      digitalWrite(13,HIGH);
    }
    else{digitalWrite(13,LOW);}

    // 時間使い切った場合
    if(usingSec == TM_LIMIT*1000){
      stateCC = CNTSTOP;
    }    
    break;
  case CNTSTOP:
    dispNum(0);
    digitalWrite(13,LOW);
    break;
  default:
    break;
  }
}