見出し画像

プチDXコンテスト2022「kintone × obniz × MESH でプチDXソリューション」400メートルLap/Splitカウンタを作ってみた。

プチDXコンテスト2022「kintone × obniz × MESH でプチDXソリューション」用の作品です。すごくないやつ。😅

プチDXコンテスト2022

ProtoPedia

参加を迷っていましたが、手厚い「もくもく会」のおかげで参加を決めました。ありがとうございました。

何つくろう

さて、問題はここから…。😅

技術も時間もないし、MESHブロックも試しに買ったボタンブロックひとつだけ。どうしたものかと考えた結果、以前 M5StickC Plusでやったのを obniz と MESHでもやってみることにしました。

要するに、400メートル走用のカウンタ(ストップウォッチ)の作成です。

簡単な仕様

1)100メートルごとにラップが取得できる
ボタンをダブルクリックするたびに、4回タイムを記録
0m(スタート)→100m→200m→300m→400m(ゴール)
の想定。以降は記録しない。

2)記録データをkintoneに送信できる
ボタンを長押しすることで、kintoneにデータを送信する。

3)リセット
ボタンをダブルクリックするとリセットされる

4)単位はミリセック

ネットワーク構成はこんな感じ。既に基本部分は「もくもく会」で動作確認済み。

obniz用JavaScript

もくもく会」でレビューしてもらったJavaScriptをちょこっと改造しました。

元記事は Yosuke Toyota 様。大変参考になりました。ありがとうございます。

JS

const Obniz = require("obniz");
const { KintoneRestAPIClient } = require("@kintone/rest-api-client");

const Config = {
  kintone: {
    apiToken: "ABCdefgHijklMnOpqrstuVwxYzAbcdefgHiJkLmN",
    baseUrl: "https://piyo.cybozu.com",
    appId: 1234,
  },
  obnizId: "1234-5678",
};

const client = new KintoneRestAPIClient({
  baseUrl: Config.kintone.baseUrl,
  auth: {
    apiToken: Config.kintone.apiToken,
  },
});

const sendToKintone = async (test0, test1, test2, test3, test4, macAddr) => {
  await client.record.addRecord({
    app: Config.kintone.appId,
    record: {
      カウント0: { value: test0 },
      カウント1: { value: test1 },
      カウント2: { value: test2 },
      カウント3: { value: test3 },
      カウント4: { value: test4 },
      MACアドレス: { value: macAddr },
      内容: { value: "obnizMESH" },
    },
  });
};

//カウンタ
let counter = 0;

//ミリ秒計算用
let startsec = Date.now();
let oldsec = Date.now();
let nowsec = Date.now();

//ミリ秒保管用配列
let secArr = [0,0,0,0,0]; 

let LAP = 0;
let SPLIT = 0;

const obniz = new Obniz(Config.obnizId, {access_token: 'ABCdefgHijklMnOpqrstuVwxYzABCdefgHijklMnOpqrstuVwxYzABCdefgHijkl'});

obniz.onconnect = async () => {
  log("obniz connected");

  //CLEAR
  obniz.switch.onchange = function (state) {
    if (state === "push") {
      log("switch push");

      obniz.display.clear();
    }
  };

  await obniz.ble.initWait();

  const MESH_100BU = Obniz.getPartsClass("MESH_100BU");
  obniz.ble.scan.onfind = async (peripheral) => {
    log("name:", peripheral.localName);
    if (!MESH_100BU.isMESHblock(peripheral)) {
      return;
    }
    log("found: MESH_100BU");

    const buttonBlock = new MESH_100BU(peripheral);
    await buttonBlock.connectWait();
    log(`connected: ${buttonBlock.peripheral.localName}`);

    //MESHシリアル番号
    macAddr = buttonBlock.peripheral.localName;

    buttonBlock.onSinglePressed = () => {
      output("COUNT - Single pressed");

      //COUNT
      nowsec = Date.now();
      LAP = (nowsec - oldsec);
      SPLIT = (nowsec - startsec);
      oldsec = nowsec;

      secArr[counter] = SPLIT;
      log(secArr[0],secArr[1],secArr[2],secArr[3],secArr[4]);
      counter++;

    };

    buttonBlock.onDoublePressed = () => {
      output("RESET - Double pressed");

      //RESET
      counter = 0;
      secArr.fill(0);

      nowsec = Date.now();
      startsec = nowsec;
      oldsec = startsec;

      LAP = (nowsec - oldsec);
      SPLIT = (nowsec - startsec);

      secArr[counter] = LAP;
      log(secArr[0],secArr[1],secArr[2],secArr[3],secArr[4]);

    };

    buttonBlock.onLongPressed = () => {
      output("SEND - Long pressed");

      //SEND
      sendToKintone(secArr[0],secArr[1],secArr[2],secArr[3],secArr[4],macAddr).catch((e) => {
        log("error", e);
      });

    };
  };

  await obniz.ble.scan.startWait(
    { localNamePrefix: "MESH-100" },
    { duration: null }
  );
};

const output = (inputString) => {
  obniz.display.clear();
  obniz.display.print("MESH: \n");
  obniz.display.print(inputString);
  log(inputString);
};

const log = (...args) => {
  console.log(new Date(), ...args);
};

const wait = (ms) => {
  return new Promise((resolve) => {
    setTimeout(resolve, ms);
  });
};

log("program start");

一部トークンを伏せたり変更してますが、おおむねこんな感じのソースです。

今回は、MACアドレスよりMESHの個体識別をしたほうが利用用途があるとおもって、MACの代わりにMESHのシリアル番号を入れています。

kintoneアプリ

こちらは、M5StickC Plus の時作成したアプリがそのまま使えました。

フィールド名:カウント4
数値
フィールドコード:カウント4
以下 カウント3~カウント0まで添え字以外同じ

フィールド名:Lap4
計算式:(カウント4-カウント3)/1000
数値 小数点以下の表示桁数 3
単位:sec ◎後ろに付ける(例:100km)
フィールドコード Lap4

以下 Lap3~Lap0までの式
Lap3:(カウント3-カウント2)/1000
Lap2:(カウント2-カウント1)/1000
Lap1:(カウント1-カウント0)/1000
Lap0:(カウント0-カウント0)/1000

フィールド名:Split4
(カウント4-カウント0)/1000
計算式:(カウント4-カウント3)/1000
数値 小数点以下の表示桁数 3
単位:sec ◎後ろに付ける(例:100km)
フィールドコード Split4

以下 Split3~Split0までの式
Split3:(カウント3-カウント0)/1000
Split2:(カウント2-カウント0)/1000
Split1:(カウント1-カウント0)/1000
Split0:(カウント0-カウント0)/1000

動作テスト

以前私が400メートル走を走った動画がありましたので、それを使って動作テストしてみました。

実際の動画です。MESHを100メートルごとにクリックしてラップ計測、4回ラップ取得後、MESHボタンを長押ししてkitntoneにデータを送信、kintoneで確認している様子です。ちなみに一番ビリが私です。😂

結果ログの主要部分は以下。

c:\obniz>node sprint04.js
2022-11-22T23:47:32.201Z program start
2022-11-22T23:47:33.110Z obniz connected
2022-11-22T23:47:35.650Z name: MESH-100BU1234567
2022-11-22T23:47:35.652Z found: MESH_100BU
2022-11-22T23:47:42.141Z connected: MESH-100BU1234567
:
2022-11-23T02:47:34.318Z RESET - Double pressed
2022-11-23T02:47:34.319Z 0 0 0 0 0
2022-11-23T02:48:06.814Z COUNT - Single pressed
2022-11-23T02:48:06.815Z 32496 0 0 0 0
2022-11-23T02:48:20.979Z COUNT - Single pressed
2022-11-23T02:48:20.980Z 32496 46661 0 0 0
2022-11-23T02:48:36.199Z COUNT - Single pressed
2022-11-23T02:48:36.200Z 32496 46661 61881 0 0
2022-11-23T02:48:49.120Z COUNT - Single pressed
2022-11-23T02:48:49.121Z 32496 46661 61881 74802 0
2022-11-23T02:49:06.936Z COUNT - Single pressed
2022-11-23T02:49:06.936Z 32496 46661 61881 74802 92617
2022-11-23T02:49:10.783Z SEND - Long pressed

kintoneの結果は以下のようになりました。

やったー!できた。できた。

ちなみに私は定期的に300メートルダッシュを練習として取り入れてるのでそれのグラフも参考までに紹介します。一番上が今回の結果。タイムが良いのはテストが適当だからです。🤣

最後に

短期間にも関わらず、なんとか「プチDXコンテスト2022」に参加できました。

実際、屋外でも試したのですが結構いろいろ大変でした。最初はMESHだけ持って走ればいいやとふわっと思ってましたが、考えてみたらBluetoothがそんなに飛ぶわけもなく(10メートルくらい)とりあえずobnizもいっしょに持って走ることに。

となるとobnizにはバッテリーの確保が必要になってくる。また屋外に基盤むき出しのままでは心もとない。加えて振動対策としてケーブルの接触もシビアなレベルが要求される。かといって大げさに対策すると機器が大きく重くなって走りに影響するので軽量化や小型化の検討が必要になってくるなどなど…。

まあ根本的にミリセックのタイムを計ろうとする装置に遅延の発生するネットワークを使用するところに無理があるのですが(実際動画をよくみると遅延してる様子が伺えます)。

誤解のないように言いますと、この辺はIoT機器の問題ではなく単に私の技術のチョイスの問題です。とはいえ、まあちょっと遊んでみる分にはそんなの気にしなくていいし、そこからの気付きや色んな工夫もできて楽しい。そして結果としてべつにうまくいかなくてもよいかなとも思います。

いろいろ勉強になって面白かったです。ありがとうございました。

P.S.

obnizの純正カバー買いました。基盤の「obniz Boad」と同じロゴが透明カバーにも刻印されてて、組み立てるとちょうど重なるようになってる。カッコイイ!😊



この記事が気に入ったらサポートをしてみませんか?