eepooのアイコン画像
eepoo 2021年02月28日作成 (2021年03月13日更新)
製作品 製作品 閲覧数 2072
eepoo 2021年02月28日作成 (2021年03月13日更新) 製作品 製作品 閲覧数 2072

シンプル時間設定キッチンタイマー

シンプル時間設定キッチンタイマー

世の中のキッチンタイマーはユーザインタフェースがなっとらん!ということで、最小の手間で使えるキッチンタイマーを目指しました。
キャプションを入力できます

電源スイッチ以外にはロータリエンコーダだけ!
スイッチを入れると電源が入りバッテリーの電圧を表示します。
つまみ(ロータリエンコーダ)を右に回すと設定時間の分をインクリメント。
左に回すと10秒ずつ時間を減らします。
ロータリエンコーダをクリックするとカウントダウンを開始し、0秒で音を鳴らします。

中を開いたところはこんな感じ

上の方にまとまっているのは、背面に取り付けてあるネオジ磁石です。
ネオジ磁石をワッシャ代わりにして筐体を締結している

バッテリーは携帯電話の電池ですので電圧が下がりすぎないようにしないといけません。なので起動時に電圧を測るようにしています。しかし、電池がマイコンのADCの基準電圧でもあるので、単にADCで測っても客観的に測ることができません。
ツェナーダイオードの電圧との比率でバッテリーの電圧を算出しています。

スピーカーはピエゾスピーカです。ちゃんと使えばどえらい音が鳴るはずなのですが、直接PWM波形を入れるだけにして音圧は控えめにしています。

全部品を3D CADでモデル化し、筐体を設計。3D プリンタで出力。

外観 フロントカバーを外したところ

回路図

ソースは以下の通り。

#define ROTA 3
#define ROTB 4
#define ROTSW 2
#define PWMPIN 9

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 32 // OLED display height, in pixels
// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
#define OLED_RESET     4 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

byte currMin = 0;
byte currSec = 0;
byte lastROTA = HIGH;

byte setTens = 0;
byte setMins = 0;

byte state = 0;//idle 回転でセット受付 クリック待ち ⇒クリックで 1になる 時刻になると 警告音発する 2 1以上でクリックでリセット
bool statusChanged = false;
long nextSec = 0;
bool first = true;

#define BEEPMAX 100  //100回beepしたら自動で止まる
#define BUZZONTIME 10
#define BUZZOFFTIME 300
int beepcount = 0;
bool buzzOn = false;
long nextBuzz = 0;

#define LEFTALONE 60000
long leftAlone = LEFTALONE;//これを過ぎたら警告音
#define LFAC 30
byte lfAlarmCount = LFAC;

#define STATUSMASK  200
long nextSSReady = 0;
bool ssReady = false;

void startStop() {
  if (ssReady) {
    statusChanged = true;
    ssReady = false;
  }
}

void setup() {
  //Serial.begin(115200);
  pinMode(ROTA, INPUT_PULLUP);
  pinMode(ROTB, INPUT_PULLUP);
  pinMode(ROTSW, INPUT_PULLUP);
  pinMode(PWMPIN, OUTPUT);
  pinMode(A0, INPUT);

  attachInterrupt(0, startStop, FALLING);

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

  int voltage = analogRead(A0);
  float vol = -0.017653 * voltage + 14.40377551;

  display.setTextSize(4);      // Normal 1:1 pixel scale
  display.setTextColor(SSD1306_WHITE); // Draw white text
  display.setCursor(0, 0);
  display.print(vol);
  display.print("V");
  display.display();
  delay(500);
  showSetTime();
}

void resetLeftAlone() {
  leftAlone = millis() + LEFTALONE;
  lfAlarmCount = LFAC;
}

void showSetTime() {
  display.clearDisplay();
  display.setCursor(0, 0);
  display.print(setMins);
  display.setCursor(64, 0);
  display.println(setTens * 10);
  display.display();
  resetLeftAlone();
}

void checkRotation() {
  bool rotA = digitalRead(ROTA);
  if (lastROTA == HIGH) {
    if (rotA == LOW) {
      byte rotB = digitalRead(ROTB);
      if (rotB == LOW) {
        setMins++;
        setTens = 0;
      }
      else {// CCW 10秒戻す
        if (setTens == 0) {//0秒からなので分桁下がり
          if (setMins > 0) {
            setTens = 5;
            setMins = setMins - 1;
          }
          else {
            setTens = 0;
            setMins = 0;
          }
        }
        else {
          setTens = setTens - 1;
        }
      }
      showSetTime();
      ssReady = true;
      delay(50);
    }
  }
  lastROTA = rotA;
}

void showCurrTime() {
  display.clearDisplay();
  display.display();
  display.setTextSize(4);
  display.setTextColor(SSD1306_WHITE);
  display.setCursor(0, 0);
  display.print(currMin);
  display.setCursor(64, 0);
  display.println(currSec);
  display.display();
  resetLeftAlone();
}

void loop() {
  long curr = millis();
  if (curr > leftAlone) {
    if (lfAlarmCount > 0) {
      digitalWrite(PWMPIN, HIGH);
      delay(5);
      digitalWrite(PWMPIN, LOW);
      delay(100);
      digitalWrite(PWMPIN, HIGH);
      delay(5);
      digitalWrite(PWMPIN, LOW);
      delay(100);
      lfAlarmCount--;
      leftAlone = curr + 1000;
    }
  }
  //Serial.println(state);
  if (!ssReady) {
    if (curr > nextSSReady) {
      ssReady = true;
    }
  }
  switch (state) {
    case 0:// idle 分秒セット ロータリスイッチをチェックする
      checkRotation();
      if (statusChanged) {
        statusChanged = false;
        nextSSReady = curr + STATUSMASK;
        state = 1;
        currMin = setMins;
        currSec = setTens * 10;
        nextSec = curr + 1000;
      }
      break;
    case 1://開始されたので、カウントダウンする
      if ( curr > nextSec) {
        //Serial.println(millis());
        nextSec = nextSec + 1000;
        if (currSec == 1) {
          currSec = 0;
          if (currMin == 0) {
            //Mode変えてBeepしはじめる
            state = 2;
            beepcount = 0;
            buzzOn = true;
          } else {
            currSec = 0; //だけにして次の秒に分桁下がり
          }
        }
        else {
          if (currSec == 0) {
            currMin = currMin - 1;
            currSec = 59;
          }
          else {
            currSec = currSec - 1;
          }
        }
        showCurrTime();
      }
      //クリックで Abort
      if (statusChanged) {
        statusChanged = false;
        nextSSReady = curr + STATUSMASK;
        state = 0;
        setMins = 0;
        setTens = 0;
        showSetTime();
      }
      break;

    case 2://beepする
      if (buzzOn) {
        digitalWrite(PWMPIN, HIGH);
        delay(BUZZONTIME);
        digitalWrite(PWMPIN, LOW);
        buzzOn = false;
        beepcount++;
        nextBuzz = curr + BUZZOFFTIME;
      } else {
        if (curr > nextBuzz) {
          buzzOn = true;
        }
      }

      if (beepcount > BEEPMAX) {
        digitalWrite(PWMPIN, LOW);
        state = 0;
        setMins = 0;
        setTens = 0;
        showSetTime();
      }
      //クリックで Beepを止める
      if (statusChanged) {
        statusChanged = false;
        nextSSReady = curr + STATUSMASK;
        digitalWrite(PWMPIN, LOW);
        state = 0;
        setMins = 0;
        setTens = 0;
        showSetTime();
      }
      break;
  }
}
eepooのアイコン画像
プログラミング大好きな本業メカ屋 arduinoからマイコンに手を出し、BluePillやESP32などでいろいろ作っています。 HUB75のLED Matrix Panelのライブラリを作ったりもしています。
ログインしてコメントを投稿する