LoginSignup
4
2

More than 3 years have passed since last update.

M5StickC Plusでマイポモドーロタイマーを作る

Last updated at Posted at 2020-12-27

はじめに

タスクを効率的にこなすための時間管理術として、ポモドーロテクニック1が知られています。これは25分間のタスク集中期間と5分間の休憩期間を繰り返し、タスクをこなしていく手法です。

時間の計測手段はキッチンタイマーでも良いですし、ポモドーロテクニックに特化したWebサービスを利用するのも手です。しかしながらキッチンタイマーはハードとして完成している都合上、機能拡張が難しいです。またWebサービスは便利なのですが周りのノイズが気になります(タイマー起動前についついネットサーフィンしてしまったり…)。
そこで今回、M5StickC Plusと呼ばれる製品を利用して、キッチンタイマーよりも少し高機能なポモドーロタイマーを作りました。
image.png

開発環境

今回用いた環境は以下となります。Windows PCにM5StickC Plusを接続し、プログラムの書き込みを行っています。M5StickC Plusはスイッチサイエンスで購入しました。

  • Windows10 Pro
  • M5StickC Plus
  • Arduino IDE

M5StickC Plusのセットアップ

M5StickC Plusのセットアップに少し手間取ったので、下記に手順を書いておきます。

ドライバのインストール

M5StickC Plusの開発を始めるにあたって、PCにドライバをインストールする必要があります。通常、CP2104 Driverと呼ばれるものをインストールすることで、デバイスマネージャーから認識されるようですが、私の環境では"不明なデバイス"と表示されている状況でした。
そこで色々と試してみたところ、FTDIドライバの2.12.26をインストールすることで正常に認識されるようになりました(記事執筆時点の最新バージョンは2.12.28ですが、2.12.28では認識されませんでした)。
デバイスマネージャーで正常に認識されることで、Arduino IDEからの書き込みが可能となります。

M5StickC Plusでのサンプルプログラムの実行

PCで正常に認識された後、Arduino IDEからM5Stick Cのライブラリをインストールし、サンプルプログラムを動作させてみました。しかし画面表示が小さく、なんだかおかしいです。

image.png

スイッチサイエンスの商品ページにも書かれていますが、M5StickCとM5StickC Plusではライブラリが異なり、M5StickC Plus用のライブラリをインストールする必要があります。
M5StickC Plus用のライブラリはGitHubで公開されています。GitHubのページからzip形式でファイルをダウンロードし、Arduino IDEのスケッチ→ライブラリをインクルード→.ZIP形式のライブラリをインストールから、ダウンロードしたZIPファイルを読み込むことで、M5StickC Plus用のライブラリが利用可能になります。
このライブラリにはFactoryTestのサンプルプログラムしか同梱されていませんが、M5StickCのサンプルプログラムについてもプログラム中の#include <M5StickC.h>#include <M5StickCPlus.h>と変更することで実行できます(簡単にしか検証していないので、動かないものもあるかもしれません)。

ポモドーロタイマーの機能

セットアップが完了したためポモドーロタイマーの製作に入っていきます。今回実装した機能は下記です。

  • 液晶にはタイマー、1日のポモドーロ数、累計ポモドーロ数が表示される
  • 正面のボタン(BtnA)を押すと25分のカウントダウンタイマー(集中期間)が開始する
  • 25分経過するとブザーが鳴り、1日のポモドーロ数と累計ポモドーロ数がカウントアップする。同時に5分のカウントダウンタイマー(休憩期間)が開始する
  • タイマーのカウントダウン中に正面のボタンを押すとタイマーがリセットされる
  • 下部のボタン(BtnB)を押すと1日のポモドーロ数がリセットされる
  • 累計ポモドーロ数は電源OFFされてもリセットされないようにEEPROMに情報を書き込む

プログラム

上記機能を実装したプログラムは下記のようなものです。
タイマー部分はM5Stack TFT_Clock_Digitalのサンプルを参考にしています。

#include <M5StickCPlus.h>
#include "EEPROM.h" 

const uint8_t PomodoroMinute = 25;
const uint8_t BreakMinute = 5;
const uint8_t LcdWidth = 240;
const uint8_t LcdHeight = 135;
const uint8_t Offset = 15;
const int EEPROMAddress = 0;

uint8_t mm = PomodoroMinute;
uint8_t ss = 0;
uint32_t targetTime = 0;

uint8_t dailyPomo = 0;
int totalPomo = 0;

enum Status{
  SLEEP,
  POMODORO,
  BREAK,
};
enum Status status = SLEEP;

void setup(){
  M5.begin();
  M5.Lcd.setRotation(3);
  EEPROM.begin(10);
  totalPomo=EEPROM.read(EEPROMAddress);
  printTime();
  printDailyPomodoro();
  printTotalPomodoro();
}

void loop() {
  M5.update();
  if(M5.BtnA.wasReleased()) {
    // タイマー未起動の場合は起動、起動中の場合はリセット
    alert(1);
    switch(status){
      case SLEEP:
        targetTime = millis() + 1000;
        status = POMODORO;
        break;
      case POMODORO:
      case BREAK:
        mm = PomodoroMinute;
        ss = 0;
        status = SLEEP;
        M5.Lcd.fillScreen(TFT_BLACK);              
        M5.Lcd.setTextColor(TFT_WHITE, TFT_BLACK);
        break;
    }
  }
  // Pomodoroカウントをリセット
  if(M5.BtnB.wasReleased()) {
    dailyPomo=0;
  }
  // タイマー起動中の場合は1秒ごとにカウントダウン
  if (status == POMODORO || status == BREAK){
    if (targetTime < millis()) {
      targetTime += 1000;
      ss--;
      if (ss == 255) {
        ss = 59;
        mm--;
        if(mm == 255) {
          alert(3);
          // カウントが終了した場合
          switch(status){
            case POMODORO:  // BREAKステータスに移行
              status = BREAK;
              mm = BreakMinute;
              ss = 0;
              // pomodoroカウントをカウントアップ
              dailyPomo++;
              totalPomo++;
              EEPROM.write(EEPROMAddress, totalPomo);
              EEPROM.commit();
              
              M5.Lcd.fillScreen(TFT_DARKCYAN);
              M5.Lcd.setTextColor(TFT_WHITE, TFT_DARKCYAN);
              break;
            case BREAK:  // SLEEPステータスに移行
              status = SLEEP;
              mm = PomodoroMinute;
              ss = 0;
              M5.Lcd.fillScreen(TFT_BLACK);              
              M5.Lcd.setTextColor(TFT_WHITE, TFT_BLACK);
              break;
          }
        }
      }
    }
  }
  printTime();
  printDailyPomodoro();
  printTotalPomodoro();
}

void printTime() {
  M5.Lcd.setTextSize(8);
  M5.Lcd.setCursor(Offset, Offset);
  M5.Lcd.printf("%02d:%02d", mm, ss);
}

void printDailyPomodoro() {
  M5.Lcd.setTextSize(3);
  M5.Lcd.setCursor(LcdWidth/2 + 8, 80);
  M5.Lcd.printf("%4dP", dailyPomo);  
}

void printTotalPomodoro() {
  M5.Lcd.setTextSize(3);
  M5.Lcd.setCursor(LcdWidth/2 + 8, 110);
  M5.Lcd.printf("%4dP", totalPomo);  
}

void alert(int count) {
  for(int i = 0; i < count; i++){
    M5.Beep.tone(800);
    delay(100);
    M5.Beep.mute();
    delay(100);    
  }
}

動作の様子

上記プログラムを動作させた様子が以下です。
ボタンを押すとタイマーが始まります。
pomodoro.gif

25分経過すると、ポモドーロ数がカウントアップし、5分のタイマーが起動します。
pomodoro2.gif

おわりに

理想のポモドーロタイマーが欲しい!ということで作ってみましたが、今のところ特に不自由なく活用できています。累計ポモドーロ数が表示されるのが案外良く、数字が徐々に増えていくのが楽しいです。
常時給電しないと25分持たずにバッテリー切れになってしまうので、電源には常に接続しています。万一電源が切れた場合についても、累計ポモドーロ数はEEPROMに記録されているので消失しません。
機能拡張は自由自在であるため、過去の履歴を表示したり、ネットワーク接続してポモドーロ数を外部DBに記録したりしても面白いかもしれません。
マイポモドーロタイマーが欲しい方はぜひ試してみてください!

  1. Wikipedia ポモドーロテクニック

4
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2