結婚式のカラードレス当てのために時限爆弾を作ってみた！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1339052/11ba011b-e1bd-01c0-fddc-6d04fa3a8356.png)

今回は友人から
「結婚式のカラードレス当てで面白いことができないか(´・ω・`)」と
話をもらったので
「それだったら時限爆弾を作ってカラードレスと同じ色の線を切れば爆弾が止まる。
間違った線を切ったら爆発するのはどう？(・∀・)」
という冗談から本当に作ることになってしまったので記事にした！
（本当の時限爆弾ではありませんよ(；・∀・)）

#### 人生のうちに本当に時限爆弾を止めることなんてないから面白そう！！

ちなみに結婚式では大いに盛り上がり、無事終了することができました！
友達もめちゃくちゃ喜んでくれて良かったです＼(^o^)／

もし同じように結婚式のカラードレス当てで
時限爆弾を使いたいなら相談くださいねー
有償で作成します！笑

自分で作れる人は以下をご参考に！！


## ハードウェア

### 購入部品（BOM）
1、電池ケース
https://akizukidenshi.com/catalog/g/g110197/

2、コンデンサ
https://akizukidenshi.com/catalog/g/g100090/

3、ダイオード
https://akizukidenshi.com/catalog/g/g100934/

4、電子ブザー
https://akizukidenshi.com/catalog/g/g109704/

5、小型振動モーター
https://www.amazon.co.jp/gp/product/B0BNKM1HQS

6、トランジスタ
https://akizukidenshi.com/catalog/g/g109406/

7、1k抵抗
https://akizukidenshi.com/catalog/g/g125102/

8、220k抵抗
https://akizukidenshi.com/catalog/g/g125221/

9、510k抵抗
https://akizukidenshi.com/catalog/g/g125511/

10、DCDCコンバータ
https://akizukidenshi.com/catalog/g/g113066/

11、7セグLED
https://akizukidenshi.com/catalog/g/g109970/

12、AVRマイコン　ATmega328P
https://akizukidenshi.com/catalog/g/g103142/

13、ATMega328p用ソケット
https://akizukidenshi.com/catalog/g/g100013

14、配線
https://www.amazon.co.jp/dp/B0B74WJH25/


### 電子回路図
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1339052/91a70ab4-c636-a037-08a9-77dd7d76ff27.png)

### PCB
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1339052/b3816edf-a9b4-9751-2f94-600e5307d909.png)


## ソフトウェア

### Arduino
```c
#include <avr/sleep.h>  // スリープライブラリ

#define L_D_COM 11
#define L_1_COM 14
#define L_2_COM 13
#define L_3_COM 9
#define L_4_COM 8
#define L_A 17
#define L_B 15
#define L_C 18
#define L_D 12
#define L_E 10
#define L_F 19
#define L_G 16

#define M_ON 3
#define BUZZER 4

#define BLUE 21
#define RED 5
#define ORANGE 6
#define GREEN 7


#define START 2

byte i;
unsigned long time, tDiff;
bool StopFg;

void setup() {
  // put your setup code here, to run once:
  delay(1000);

  Serial.begin(9600);

  //ピンの設定
  pinMode(L_D_COM, OUTPUT);
  pinMode(L_1_COM, OUTPUT);
  pinMode(L_2_COM, OUTPUT);
  pinMode(L_3_COM, OUTPUT);
  pinMode(L_4_COM, OUTPUT);
  pinMode(L_A, OUTPUT);
  pinMode(L_B, OUTPUT);
  pinMode(L_C, OUTPUT);
  pinMode(L_D, OUTPUT);
  pinMode(L_E, OUTPUT);
  pinMode(L_F, OUTPUT);
  pinMode(L_G, OUTPUT);

  pinMode(M_ON, OUTPUT);
  pinMode(BUZZER, OUTPUT);

  pinMode(ORANGE, INPUT_PULLUP);
  pinMode(RED, INPUT_PULLUP);
  pinMode(GREEN, INPUT_PULLUP);
  pinMode(BLUE, INPUT_PULLUP);

  pinMode(START, INPUT_PULLUP);

  digitalWrite(M_ON, LOW);  //モータ停止

  time = 610000;

  digitalWrite(BUZZER, HIGH);  //ブザー起動
  delay(400);
  digitalWrite(BUZZER, LOW);  //ブザー停止
}

void (*resetFunc)(void) = 0;  //リセット用コマンド

void loop() {
  unsigned long Clock, T;

  //ストップフラグが立っていない場合は時限爆弾起動
  if (StopFg == false) {
    tDiff = time - millis();
  }
  if(tDiff <= 100){
    time = time + 600000;
  }

  //STARTピンが刺さっているときは何もしない
  if (digitalRead(START) == LOW) {
    //LEDを消す
    LedCtrl(0, 10);
    LedCtrl(1, 10);
    LedCtrl(2, 10);
    LedCtrl(3, 10);
    LedCtrl(4, 10);

    digitalWrite(BUZZER, LOW);  //ブザー停止
    digitalWrite(M_ON, LOW);    //モータ停止

    //スリープ状態に入る ピンが抜かれたら次の処理に移行
    interrupt();  // 割り込みのスリープを設定
    resetFunc();  // 再起動

  } else {  //ピンが外れたら処理スタート
    delay(2);

    byte ORANGEST, RedST, GREENST, BlueST;
    ORANGEST = digitalRead(ORANGE);
    RedST = digitalRead(RED);
    GREENST = digitalRead(GREEN);
    BlueST = digitalRead(BLUE);

    //線が切られていなかったら無視
    if (ORANGEST == LOW && RedST == LOW && GREENST == LOW && BlueST == LOW) {

      //青の線だけ切れていたら停止
    } else if (ORANGEST == LOW && RedST == LOW && GREENST == LOW && BlueST == HIGH) {
      digitalWrite(BUZZER, LOW);  //ブザー停止
      digitalWrite(M_ON, LOW);    //モータ停止
      StopFg = true;
      //それ以外の場合は爆発
    } else {
      //LEDを消す
      LedCtrl(0, 10);
      LedCtrl(1, 10);
      LedCtrl(2, 10);
      LedCtrl(3, 10);
      LedCtrl(4, 10);
      digitalWrite(BUZZER, HIGH);  //ブザー起動
      digitalWrite(M_ON, HIGH);    //モータ起動
      delay(4000);
      digitalWrite(BUZZER, LOW);  //ブザー停止
      digitalWrite(M_ON, LOW);    //モータ停止
      while (digitalRead(START) == HIGH) {
        delay(10);
      }
      resetFunc();  // 再起動
    }
    //------------------------------------------------

    //音処理----------------------------------------
    Clock = tDiff / 100;
    T = Clock % 10;
    if (T == 0 && StopFg == false) {
      digitalWrite(BUZZER, HIGH);  //ブザー起動
    } else {
      digitalWrite(BUZZER, LOW);  //ブザー停止
    }
    //表示処理-----------------------------------------
    //桁切り替わり用の処理
    byte digit, data;
    if (i == 5) {
      i = 0;
    }
    digit = i % 5;

    //Dの桁
    if (digit == 0) {
      Clock = tDiff / 500;
      T = Clock % 2;
      if (T == 0) {
        LedCtrl(digit, 10);
      } else {
        LedCtrl(digit, 99);
      }
    } else if (digit == 4) {  //1の位
      Clock = tDiff / 1000;
      T = Clock % 10;
      LedCtrl(digit, T);
    } else if (digit == 3) {  //10の位
      Clock = tDiff / 10000;
      T = Clock % 6;
      LedCtrl(digit, T);
    } else if (digit == 2) {  //100の位
      Clock = tDiff / 60000;
      T = Clock % 10;
      // Serial.print(T);
      LedCtrl(digit, T);
    } else if (digit == 1) {  //1000の位
      Clock = tDiff / 600000;
      T = Clock;
      // Serial.println(T);
      LedCtrl(digit, T);
    }
    i++;
  }
}
//LEDの表示処理
//digit=設定する桁入力　data=表示する内容
void LedCtrl(byte digit, byte data) {

  digitalWrite(L_A, HIGH);
  digitalWrite(L_B, HIGH);
  digitalWrite(L_C, HIGH);
  digitalWrite(L_D, HIGH);
  digitalWrite(L_E, HIGH);
  digitalWrite(L_F, HIGH);
  digitalWrite(L_G, HIGH);

  if (digit == 0) {
    digitalWrite(L_D_COM, HIGH);
    digitalWrite(L_1_COM, LOW);
    digitalWrite(L_2_COM, LOW);
    digitalWrite(L_3_COM, LOW);
    digitalWrite(L_4_COM, LOW);
  } else if (digit == 1) {
    digitalWrite(L_D_COM, LOW);
    digitalWrite(L_1_COM, HIGH);
    digitalWrite(L_2_COM, LOW);
    digitalWrite(L_3_COM, LOW);
    digitalWrite(L_4_COM, LOW);
  } else if (digit == 2) {
    digitalWrite(L_D_COM, LOW);
    digitalWrite(L_1_COM, LOW);
    digitalWrite(L_2_COM, HIGH);
    digitalWrite(L_3_COM, LOW);
    digitalWrite(L_4_COM, LOW);
  } else if (digit == 3) {
    digitalWrite(L_D_COM, LOW);
    digitalWrite(L_1_COM, LOW);
    digitalWrite(L_2_COM, LOW);
    digitalWrite(L_3_COM, HIGH);
    digitalWrite(L_4_COM, LOW);
  } else if (digit == 4) {
    digitalWrite(L_D_COM, LOW);
    digitalWrite(L_1_COM, LOW);
    digitalWrite(L_2_COM, LOW);
    digitalWrite(L_3_COM, LOW);
    digitalWrite(L_4_COM, HIGH);
  }

  if (data == 0) {
    digitalWrite(L_A, LOW);
    digitalWrite(L_B, LOW);
    digitalWrite(L_C, LOW);
    digitalWrite(L_D, LOW);
    digitalWrite(L_E, LOW);
    digitalWrite(L_F, LOW);
    digitalWrite(L_G, HIGH);
  } else if (data == 1) {
    digitalWrite(L_A, HIGH);
    digitalWrite(L_B, LOW);
    digitalWrite(L_C, LOW);
    digitalWrite(L_D, HIGH);
    digitalWrite(L_E, HIGH);
    digitalWrite(L_F, HIGH);
    digitalWrite(L_G, HIGH);
  } else if (data == 2) {
    digitalWrite(L_A, LOW);
    digitalWrite(L_B, LOW);
    digitalWrite(L_C, HIGH);
    digitalWrite(L_D, LOW);
    digitalWrite(L_E, LOW);
    digitalWrite(L_F, HIGH);
    digitalWrite(L_G, LOW);
  } else if (data == 3) {
    digitalWrite(L_A, LOW);
    digitalWrite(L_B, LOW);
    digitalWrite(L_C, LOW);
    digitalWrite(L_D, LOW);
    digitalWrite(L_E, HIGH);
    digitalWrite(L_F, HIGH);
    digitalWrite(L_G, LOW);
  } else if (data == 4) {
    digitalWrite(L_A, HIGH);
    digitalWrite(L_B, LOW);
    digitalWrite(L_C, LOW);
    digitalWrite(L_D, HIGH);
    digitalWrite(L_E, HIGH);
    digitalWrite(L_F, LOW);
    digitalWrite(L_G, LOW);
  } else if (data == 5) {
    digitalWrite(L_A, LOW);
    digitalWrite(L_B, HIGH);
    digitalWrite(L_C, LOW);
    digitalWrite(L_D, LOW);
    digitalWrite(L_E, HIGH);
    digitalWrite(L_F, LOW);
    digitalWrite(L_G, LOW);
  } else if (data == 6) {
    digitalWrite(L_A, LOW);
    digitalWrite(L_B, HIGH);
    digitalWrite(L_C, LOW);
    digitalWrite(L_D, LOW);
    digitalWrite(L_E, LOW);
    digitalWrite(L_F, LOW);
    digitalWrite(L_G, LOW);
  } else if (data == 7) {
    digitalWrite(L_A, LOW);
    digitalWrite(L_B, LOW);
    digitalWrite(L_C, LOW);
    digitalWrite(L_D, HIGH);
    digitalWrite(L_E, HIGH);
    digitalWrite(L_F, LOW);
    digitalWrite(L_G, HIGH);
  } else if (data == 8) {
    digitalWrite(L_A, LOW);
    digitalWrite(L_B, LOW);
    digitalWrite(L_C, LOW);
    digitalWrite(L_D, LOW);
    digitalWrite(L_E, LOW);
    digitalWrite(L_F, LOW);
    digitalWrite(L_G, LOW);
  } else if (data == 9) {
    digitalWrite(L_A, LOW);
    digitalWrite(L_B, LOW);
    digitalWrite(L_C, LOW);
    digitalWrite(L_D, LOW);
    digitalWrite(L_E, HIGH);
    digitalWrite(L_F, LOW);
    digitalWrite(L_G, LOW);
  } else if (data == 99) {
    digitalWrite(L_A, LOW);
    digitalWrite(L_B, LOW);
    digitalWrite(L_C, HIGH);
    digitalWrite(L_D, HIGH);
    digitalWrite(L_E, HIGH);
    digitalWrite(L_F, HIGH);
    digitalWrite(L_G, HIGH);
  } else {
    digitalWrite(L_A, HIGH);
    digitalWrite(L_B, HIGH);
    digitalWrite(L_C, HIGH);
    digitalWrite(L_D, HIGH);
    digitalWrite(L_E, HIGH);
    digitalWrite(L_F, HIGH);
    digitalWrite(L_G, HIGH);
  }
}

//　外部入力割込みによる起動処理
void wakeUp() {
  //外部入力割込みの際に行いたい処理を記載
}

// 割り込みスリープ処理
void interrupt() {
  Serial.flush();  // シリアルバッファが空になるまで待つ

  // ADCを停止（消費電流 147→27μA）
  ADCSRA &= ~(1 << ADEN);

  set_sleep_mode(SLEEP_MODE_PWR_DOWN);  // パワーダウンモード指定
  attachInterrupt(0, START, HIGH);      // HIGHになった時にwakeUp関数起動
  sleep_enable();

  // BODを停止（消費電流 27→6.5μA）
  MCUCR |= (1 << BODSE) | (1 << BODS);            // MCUCRのBODSとBODSEに1をセット
  MCUCR = (MCUCR & ~(1 << BODSE)) | (1 << BODS);  // すぐに（4クロック以内）BODSSEを0, BODSを1に設定

  asm("sleep");  // 3クロック以内にスリープに入る sleep_mode();では間に合わなかった

  sleep_disable();        // 割り込みででここから動作再開
  ADCSRA |= (1 << ADEN);  // ADCの電源をON（BODはハードウエアで自動再開される）
  detachInterrupt(0);     //外部割込み停止
}
```

## 動作
PD2のショート状態を開放すると、時限爆弾が開始されます。
時限爆弾が開始されるとカウントダウンが始まり、
正解の線を切るとカウントダウンが停止。
間違った線を切るとブザー音＆振動モーターが起動し、
爆発したような演出を行います。

ちなみに花嫁さんは「青」のカラードレスだったため
青の線を切ると時限爆弾が停止するように作られています。

その他にも色々な開発＆企画を承っておりますので、
お気軽にご相談くださいね～！