工場改善 IoT Arduino開発

現場の悩みに解決手段を

M5StakCでBluetoothストップウォッチ作ってみた

タイトルの通りBluetooth HID入力できるストップウォッチ作りました。

まずは作ろうと思ったきっかけです。
私が所属している部署の機能の1つに図面に対して標準時間を設定する業務がありまして、その根拠となる時間研究をしています。

紙に経過時間と要素作業名を書いてExcelに手入力して、関数で計算してect...
とにかく時間と手間がかかるわ、入力ミスの懸念もあるわと大変なんです。

そこの担当者がデシマルストップウォッチ故障して買い替えたいと1.2万のものを数個個買いたいと課長に予算の承認依頼したときに
「ストップウォッチの情報って無線で直接送れるやつとか売ってないの?」
「IoTとか言ってる時代なんだから世の中あるんじゃないの?」
と言われてたので私も調べてみたらフェリカとか使って通信しているものを見つけました。

しかし、まぁ高いし、ドライバーインストールして、かざしてCSVで保存して、コピペして、時分秒を秒に換算して...ぁあ~もう




....なんか面白くない!値段高いしあんまり変わらんやんけ。
ピッて押して、Excelのフォーマットに直接バット入ってうぇ~い!!
ってなって欲しいのですよ。


私の知る限りまだ世の中にないので作ります。
よかったらこのアイディアで商品開発したいくらいです。

時間研究とは
工場や事務所,倉庫などにおける作業を基本動作に分解して,各動作の時間を測定し,これを分析して各作業の標準時間を決定する技法。科学的管理法の始祖 F.W.テーラーが提唱したもので,現実の方法としては,ストップウォッチを用いて測定する方法,作業動作を要素に分解して記号化していくワーク・ファクター法,作業の基本動作に標準時間値テーブルを用いるMTMなどがある。作業方法の標準化,作業計画,作業量の決定などに利用される。
出典 ブリタニカ国際大百科事典 小項目事典ブリタニカ国際大百科事典 小項目事典について

【作業の流れ】

①現場で作業とストップウォッチをみながら紙に経過時間と要素作業名を書く。
②事務所に戻って時間と要素作業をExcelにて入力。
③時間を秒に換算ためにExcel関数を入力して計算。
④要素ごとの時間をExcel関数を入力して計算。
⑤項目毎に集計したり、なんやかんやして標準時間を設定。

今回やりたいことは①~④の時間の入力と計算の手数を極限まで減らしたいのです。
やりましょう。


【開発環境】
・Windows10 2H1
Arduino IDE 1.8.15
Arduino IDEに手動で入れたBluetooth HIDキーボードライブラリ
 github.com
Arduino IDEのボードマネージャーでインストール:M5Stack by M5Stack official 1.0.7

【使用機器】

・M5StickC M5StickC - スイッチサイエンス

【機能】

 Aボタン :スタート/ラップタイム/再開
 Bボタン :ストップ
 電源ボタン:リセット

f:id:kesokonpatata:20210623003857j:plain

【コード】

/*
  キーボードライブラリをインストール
  https://github.com/asterics/esp32_mouse_keyboard
  ・最大約49日まで
  ・件数は65535まで
*/
//Bluetooth HIDプロファイルの設定ライブラリ、キーボード送信用
#include <BleKeyboard.h> 
//Bluetoothペアリング時の表示名
BleKeyboard bleKeyboard("M5StickC StopWatch 002"); 

#include <M5StickC.h>

uint16_t count;
float tm;
float startTime;
float LastTime;

float Lap1;
float Lap2;
float Lap3;
float Time1;
float Time2;
float Time3;

bool stopF = false;
float stopTime;
float stopTimeSum;
uint16_t i;
uint16_t BtnF;

void m5lcd() {
  M5.Lcd.fillScreen(BLACK);  //背景色
  M5.Lcd.setTextColor(WHITE); //テキストカラー
  M5.Lcd.setTextSize(1);   //文字サイズ

  M5.Lcd.setCursor(0, 0); M5.Lcd.println("StopWatch 002");
  M5.Lcd.setCursor(90, 0);

  if (BtnF == 1) {
    M5.Lcd.print("Start");
    M5.Lcd.setTextColor(GREEN);
  } else if (BtnF == 2) {
    M5.Lcd.print("Stop");
    M5.Lcd.setTextColor(RED);
  } else if (BtnF == 3) {
    M5.Lcd.print("Reset");
    M5.Lcd.setTextColor(YELLOW);
  } else {
    M5.Lcd.setTextColor(YELLOW);
  }

  M5.Lcd.setTextSize(2);
  if (count > 0) {
    M5.Lcd.setCursor(0, 10); M5.Lcd.printf("Cnt :%d", count);
    M5.Lcd.setCursor(0, 25); M5.Lcd.printf("lap :%.2f", Lap1);
    M5.Lcd.setCursor(0, 40); M5.Lcd.printf("Time:%.2f", Time1);

    M5.Lcd.setTextSize(1);     //文字サイズ
    M5.Lcd.setTextColor(WHITE);
    if (count > 1) {
      M5.Lcd.setCursor(0, 60); M5.Lcd.printf("lap2:%.2f Time:%.2f", Lap2, Time2);
      if (count > 2) {
        M5.Lcd.setCursor(0, 70); M5.Lcd.printf("lap3:%.2f Time:%.2f",  Lap3, Time3);
      }
    }
  }
}
void setup() {
  Serial.begin(115200);  //通信速度bps
  delay(30);
  bleKeyboard.begin();   //BLE接続開始

  M5.begin();

  M5.Axp.ScreenBreath(9); //バックライトの輝度(デフォルト12)
  setCpuFrequencyMhz(160); //CPU周波数を下げる(デフォルト240)
  M5.Lcd.setRotation(1);
  
  m5lcd();

  Serial.println("M5Stack StopWatch");
}

void loop() {
  M5.update();
  int axpButton = M5.Axp.GetBtnPress();

  //Aボタンでタイマー開始、ラップタイム記録
  if (M5.BtnA.wasPressed()) {
    if (startTime == 0.0) {
      startTime = (float)millis() / 1000.0;
      LastTime = startTime;

      Serial.println("RAPCOUNT,RAP,TIME");

      BtnF = 1;
      m5lcd();

      //Bluetooth HIDプロファイルで送信
      bleKeyboard.print("RAPCOUNT"); 
      bleKeyboard.write(KEY_TAB);  //TAB(0xB3)
      bleKeyboard.print("LAP"); 
      bleKeyboard.write(KEY_TAB);  //TAB(0xB3)
      bleKeyboard.print("TIME"); 
      bleKeyboard.write(KEY_TAB);  //TAB(0xB3)
      bleKeyboard.write(KEY_RETURN); //改行(0xB0)

      //ストップ後の再開
    } else if (stopF == true) {
      tm = (float)millis() / 1000.0;

      stopTime = tm - stopTime;
      stopTimeSum += stopTime;

      stopF = false;

      //LCD表示
      BtnF = 1;
      m5lcd();

      //ラップタイム
    } else {
      tm = (float)millis() / 1000.0;
      count += 1;

      Time3 = Time2;
      Time2 = Time1;
      Time1 = tm - startTime - stopTimeSum;

      Lap3 = Lap2;
      Lap2 = Lap1;
      Lap1 = tm - LastTime - stopTime;

      LastTime = tm;
      stopTime = 0.0;

      //serial出力
      Serial.printf("%d,%.2f,%.2f\r\n", count, Lap1, Time1);

      //LCD表示
      BtnF = 1;
      m5lcd();

      //Bluetooth HIDプロファイルで送信
      bleKeyboard.print(count);
      bleKeyboard.write(KEY_TAB); //TAB(0xB3)
      bleKeyboard.print(Lap1, 2);
      bleKeyboard.write(KEY_TAB);  //TAB(0xB3)
      bleKeyboard.print(Time1, 2); 
      bleKeyboard.write(KEY_TAB);  //TAB(0xB3)
      bleKeyboard.write(KEY_RETURN); //改行(0xB0)
    }

  //Bボタンでタイマーリセット
  } else if (M5.BtnB.wasPressed()) {  
    count = 0;
    startTime = 0.0; LastTime = 0.0;
    Time1 = 0.0; Time2 = 0.0; Time3 = 0.0;
    Lap1 = 0.0; Lap2 = 0.0; Lap3 = 0.0;
    stopF = false; stopTime = 0.0; stopTimeSum = 0.0;

    Serial.println("Timer Reset");

    BtnF = 3;
    m5lcd();

  //電源ボタンでタイマーストップ
  } else if (axpButton == 2 && stopF == false && startTime > 0.0) {
    stopTime = (float)millis() / 1000.0;
    stopF = true;

    Serial.println("Timer Stop");

    BtnF = 2;
    m5lcd();
  }

  //一定時間毎にPCロックがかからないようにShiftキーを押す。
  if (i >= 24000) {
    Serial.println("Shift");
    bleKeyboard.write(0x81); //KEY_LEFT_SHIFT
    i = 0;
  }
  i += 1;

  delay(10);
}

【その他】

モバイルバッテリー繋いで使ってみたんですがすぐ切れちゃうんですが、消費電力低いせいですかね。
輝度下げたり、CPUのクロック下げたりとか知らずにやって省電力化を試みたけど気づかなかった~
逆に負荷抵抗とか入れて消費電力増やしたいんですが、なんかいい方法ないかなぁ。

写真だと見えないんですが、ボールペンと一体にしたくて、アルミでブラケットを作ってもらったんですが、フィット感抜群でした(笑)協力してもらった方には感謝です。

とりあえず課長にも担当者にも見せたら結構ウケたので業務に採用してもらえそうです。
1個あたり既製品:12,000円→今回のおもちゃ:3000円で節約できました。開発工数考慮するとあれですが、自宅で趣味としてやってたからまぁ...あれですね。

おしまい