YouTubeに夢中な娘をお風呂へ!パパのDIY『お風呂時間タイマー』制作記録

子育て×DIY

最近、我が家の娘がYouTubeに夢中で、なかなかお風呂に入ってくれない日が続いております。
「これ終わってから!」「他の人と入る!」(結局入らない)と毎晩押し問答。
止めさせる → 泣き出す、もしくは「あと10分!」(結局止めない)→ これの繰り返し…

毎日のこのやり取りに、ついにパパが立ち上がりました。 「だったら、約束した時間が来たら音楽と光でお知らせする装置を作ろう!娘の好きな音楽で!」

今回は、Arduinoを使って作った『お風呂時間タイマー』の制作記録をご紹介します。 LEDと音楽、ディスプレイを使って子どもに楽しくお風呂を促す、ちょっとユニークな育児×電子工作の記録です。


用意した材料と費用目安

部品名使用数概算価格備考
Arduino Uno(互換機)1約1,000円マイコン本体
DFPlayer mini1約300円音楽再生モジュール
OLEDディスプレイ(I2C)1約400円128×64表示用
赤色LED2数十円10分前・5分前で点灯
タクトスイッチ1数十円タイマー停止・切替用
スピーカー(8Ω1W)1約200円DFPlayer mini用
microSDカード(2〜32GB)1前回購入した物を使用0001.mp3を保存
ブレッドボード+配線一式約500円手持ち

合計:約2,500円前後(ケース除く)


どんな機能?

  • ディスプレイに残り時間を表示(分:秒)
  • スタート後10分前にLED①が点灯、5分前にLED②も点灯
  • 時間になると音楽(好きなMP3)が流れる!
  • ボタンでタイマーを3種類(20分 / 10分 / 5分)に切り替え可能
  • ボタンで音楽の停止もできる

☝5分モードはこんな感じ!
起動後、モードが表示されて2秒後にタイマー開始
同時にLED①(画像左側)LED②(画像右側)が点灯

☝10分モードはこんな感じ!
起動後、モードが表示されて2秒後にタイマー開始
同時にLED①(画像左側)のみ点灯

☝20分モードはこんな感じ!
起動後、モードが表示されて2秒後にタイマー開始
カウントダウン終了10前ににLED①が点灯
5分前にLED②っも点灯

カウントダウン終了後は音楽が再生されます。

共通で、起動後2秒以内にスイッチ(画像黒スイッチ)を押すと
モード変更
カウントダウン終了後、音楽が再生している途中にスイッチを押すと
音楽停止後、またカウントダウン開始します。

配線方法

1. OLEDディスプレイ(I2C)

OLED端子Arduino端子備考
VCC5V電源供給
GNDGNDグランド(マイナス)
SDAA4I2Cデータ線
SCLA5I2Cクロック線

2. DFPlayer mini

DFPlayer端子Arduino端子備考
VCC5V電源供給
GNDGND共通グランド
TXD11ソフトウェアシリアル(Arduino RX)
RXD10ソフトウェアシリアル(Arduino TX)※1kΩプルダウンが安定
SPK+スピーカー+側8Ω 1W推奨
SPK-スピーカー−側同上

3. 赤色LED ×2

LED名Arduino端子接続方法
LED①(10分前用)D2220Ω抵抗を介してGNDへ
LED②(5分前用)D3同上

※LEDの「長い脚=プラス(アノード)」をArduino側へ接続


4. タクトスイッチ(1つ)

Arduino端子配線方法
D4スイッチ片側 → D4ピンに接続
もう片方 → GNDに接続



プログラム

Arduino IDEでのスケッチ紹介します。

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <SoftwareSerial.h>
#include <DFRobotDFPlayerMini.h>

#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

SoftwareSerial mySerial(10, 11); // DFPlayer接続ピン RX, TX
DFRobotDFPlayerMini myDFPlayer;

const int led10 = 2;
const int led5 = 3;
const int buttonPin = 4;

unsigned long durations[] = {300, 600, 1200};  // 5分, 10分, 20分(秒)
const char* modeNames[] = {"5 min mode", "10 min mode", "20 min mode"};

int mode = 0;
bool isStarted = false;
bool isPlaying = false;
bool isFinished = false;
unsigned long startMillis = 0;
unsigned long lastButtonPress = 0;
bool buttonState = HIGH;
bool prevButtonState = HIGH;

void setup() {
  pinMode(led10, OUTPUT);
  pinMode(led5, OUTPUT);
  pinMode(buttonPin, INPUT_PULLUP);

  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  display.clearDisplay();
  display.display();

  mySerial.begin(9600);
  myDFPlayer.begin(mySerial);
  myDFPlayer.volume(25);
  myDFPlayer.EQ(DFPLAYER_EQ_NORMAL);

  showMode();
  lastButtonPress = millis();
}

void loop() {
  buttonState = digitalRead(buttonPin);

  if (buttonState == LOW && prevButtonState == HIGH) {
    if (isPlaying) {
      // 音楽が鳴っている最中にボタンを押したら、音を止める
      myDFPlayer.stop();
      isPlaying = false;
      isFinished = false;
      showMode();
    } else if (!isStarted) {
      // タイマー停止中:モード切り替え
      mode = (mode + 1) % 3;
      showMode();
      lastButtonPress = millis();
    }
    delay(200);
  }
  prevButtonState = buttonState;

  // タイマー開始条件(2秒放置)
  if (!isStarted && millis() - lastButtonPress > 2000 && !isFinished) {
    isStarted = true;
    startMillis = millis();
    digitalWrite(led10, LOW);
    digitalWrite(led5, LOW);
  }

  if (isStarted) {
    unsigned long elapsed = (millis() - startMillis) / 1000;
    unsigned long remain = (durations[mode] > elapsed) ? durations[mode] - elapsed : 0;

    // 表示更新
    int minutes = remain / 60;
    int seconds = remain % 60;
    display.clearDisplay();
    display.setTextSize(3);
    display.setTextColor(SSD1306_WHITE);
    display.setCursor(25, 20);
    display.print(minutes);
    display.print(":");
    if (seconds < 10) display.print("0");
    display.print(seconds);
    display.display();

    if (remain <= 600) digitalWrite(led10, HIGH);  // 10分以下
    if (remain <= 300) digitalWrite(led5, HIGH);   // 5分以下

    if (remain == 0 && !isPlaying && !isFinished) {
      isPlaying = true;
      isStarted = false;
      isFinished = true;

      myDFPlayer.play(1);

      display.clearDisplay();
      display.setTextSize(2);
      display.setTextColor(SSD1306_WHITE);
      display.setCursor(0, 20);
      display.println("Bath time!");
      display.display();
    }
  }

  delay(100);
}

void showMode() {
  display.clearDisplay();
  display.setTextSize(2);
  display.setTextColor(SSD1306_WHITE);
  display.setCursor(0, 20);
  display.println(modeNames[mode]);
  display.display();
}

実際に使ってみた(試運転)反応は…?

「パパ何してるの?」と不思議そうな娘たちがパパ部屋に入って来たので
タイマーを10秒に変更してスイッチを押してもらいました。

「光った!音が鳴った!!」と大はしゃぎ!
「これはお風呂に入る時間をお知らせしてくれるおもちゃだよ」
と伝えたら納得してくれたようでした。

外箱も綺麗に作れたら、もう一度お披露目して反応を確かめてみます!


今後のアップデート予定

  • 外箱を用意して見た目をスッキリ
  • ディスプレイにお風呂アイコンを表示(Bitmapで)
  • 音楽をランダム再生や、曜日ごとに変える
  • 「お風呂入れたらポイントが貯まる」仕組みと連動も?

まとめ

今回のように「子どもの困りごとをDIYで解決する」のは、
育児にもモノづくりにもやりがいがあります。
もし似たようなお風呂の悩みがある方は、ぜひ、試してみてください!

タイトルとURLをコピーしました