編集履歴一覧に戻る
neorobohonのアイコン画像

neorobohon が 2021年05月20日11時40分43秒 に編集

初版

タイトルの変更

+

模型レーシング用ラップカウンタ Rev.0.5

タグの変更

+

フォトインタラプタ

+

obniz

+

複数プログラムからの接続

メイン画像の変更

メイン画像が設定されました

本文の変更

+

1.概要 obniz deviceは最大5つのアプリから同時接続可能である(*1)。 先のelchika obniz IoTコンテスト 模型レーシング用ラップカウンタ [模型レーシング用ラップカウンタ Rev.0](https://elchika.com/article/f6c53743-6d35-443c-8937-3c166bfe9f37/) を使って遠隔地ネットワーク(*2)対戦レースを行うためのアプリを作成した。 2.ネットワーク環境 遠隔地ネットワークを再現するために2つの異なるプロバイダーを使用。 緑領域のラップカウンターと操作端末はauひかりに接続。 白領域のラップカウンターと操作端末は同領域内にある楽天モバイルルーター接続。 3.使用方法 どちらかをホストに,残りをクライアントに設定。 ホストはレース開始ボタンを押下することができる。 レース中はホストとクライアントのラップカウンタを参照表示。 規定周回数5回を先に走行したほうが勝ち。 4.技術的特徴 ホストによるレース開始通知はobniz ioポートを使用(*3)。 ホストはobniz bord 出力端子io4の値を変化させクライアントにレース開始を通知する。 クライアントはobniz bord ad4のアナログ値を読み取ってレース開始を検出する 実装例ブロックプログラム(後述)  f_host01 f_client01 f_broadcast_on f_broadcast_off 5.動画  便宜上,フォトリフレクタ検出は指で行った。 @[youtube](https://youtu.be/18lo2bTCNWQ) 6.課題 フォトリフレクタ検出信号を確実に取得記録するラップカウンターモジュール適用 obniz board(1Y)はラップカウンターモジュールからデータを取得する 7.ソースコード 7-1. ブロックプログラム ![メイン 1/6](https://camo.elchika.com/c94c3a3666d020461cba3f7d4953445d11f57886/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f35386661323733622d393261662d343864372d623561642d3865323061343364353566312f61383261653531352d616230322d343434342d623936332d653966346663663866633765/) ![obniz ID brodcast 2/6](https://camo.elchika.com/f6eaf5e130cbc5bc338b780fd6d7b17399a500c0/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f35386661323733622d393261662d343864372d623561642d3865323061343364353566312f37333439323062632d316465622d343739372d386664652d376231623738396234653362/) ![ホスト クライアント 3/6](https://camo.elchika.com/01d196133c84f61b733dc537e11aa3ffb34d24ba/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f35386661323733622d393261662d343864372d623561642d3865323061343364353566312f66343461636332372d336630642d343334662d613232302d343039613830323463633865/) ![ラップカウント 4/6](https://camo.elchika.com/5c5d7b1cca57163b9b1882efa8773894d49bceec/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f35386661323733622d393261662d343864372d623561642d3865323061343364353566312f39323562646261342d313266322d343936332d386566362d353161653035326438656466/) ![obniz 設定 5/6](https://camo.elchika.com/5756fa41fef225ab02563472ee19061d521b8085/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f35386661323733622d393261662d343864372d623561642d3865323061343364353566312f36366461373838362d323731342d343363612d613734382d653239623330623630633662/) ![デバッグ中 6/6](https://camo.elchika.com/625ea38ca799708595a9d66dbebdfaa4b06e960f/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f35386661323733622d393261662d343864372d623561642d3865323061343364353566312f32643834666530332d346238302d343539332d626134372d633536653530326665613931/) 7-2. テキスト <script> $("#bploading").text("RUNNING..."); (async function(){ var obniz01, vchar_obniz01, label01, label0101, detector01, label02, led0101, detector02, obniz02, led0201, led0102, vchar_obniz02, vchar_status, vnum_count01, label03, spk01, led0202, spk02, vnum_count02, led0103, led0203, btn_host01_start, vnum_count_max, obniz, btn_host01, btn_client01, vnum_btn_flag; /** * この関数の説明… */ async function f_def_obniz() { vchar_obniz01 = '0000-0000'; vchar_obniz02 = '1111-1111'; } /** * この関数の説明… */ async function f_host01() { await f_def_Lap(); vchar_status = '3分後にカウントダウンボタンを押してください'; await f_status(); btn_host01_start = new ObnizUI.Button('カウントダウン'); await f_led01_all_on(); while (!btn_host01_start.isClicked()) { await ObnizUI.Util.wait(0); } await f_broadcast_on(); while ((await obniz01.ad4.getWait()) < 2) { await ObnizUI.Util.wait(0); } await f_led01_all_on(); await f_countdown01(); await f_lapcount(); } /** * この関数の説明… */ async function f_def_Lap() { label01 = new ObnizUI.Label('label'); label02 = new ObnizUI.Label('label'); label03 = new ObnizUI.Label('label'); label01.setText((['レース:',vnum_count_max,'周'].join(''))); await f_disp_Lap(); } /** * この関数の説明… */ async function f_status() { label0101.setText(('状態:' + String(vchar_status))); await _ai.say(vchar_status); } /** * この関数の説明… */ async function f_detector() { detector01.on(); detector02.on(); } /** * この関数の説明… */ async function f_lapcount() { await f_detector(); vnum_count01 = -1; vnum_count02 = -1; while (vnum_count01 < vnum_count_max && vnum_count02 < vnum_count_max) { await ObnizUI.Util.wait(0); if ((await obniz01.ad2.getWait()) < 4) { vnum_count01 = (typeof vnum_count01 == 'number' ? vnum_count01 : 0) + 1; } if ((await obniz02.ad2.getWait()) < 4) { vnum_count02 = (typeof vnum_count02 == 'number' ? vnum_count02 : 0) + 1; } await f_disp_Lap(); } } /** * この関数の説明… */ async function f_broadcast_on() { obniz01.io4.output(true); obniz02.io4.output(true); } /** * この関数の説明… */ async function f_client01() { await f_def_Lap(); vchar_status = 'カウントダウンが開始されるまでお待ちください'; await f_status(); await f_led02_all_on(); while ((await obniz02.ad4.getWait()) < 2) { await ObnizUI.Util.wait(0); } await f_countdown02(); await f_lapcount(); } /** * この関数の説明… */ async function f_broadcast_off() { obniz01.io4.output(false); obniz02.io4.output(false); } /** * この関数の説明… */ async function f_disp_Lap() { label02.setText((['ホスト___:',vnum_count01,'周'].join(''))); label03.setText((['クライアント:',vnum_count02,'周'].join(''))); } /** * この関数の説明… */ async function f_init_obniz01() { detector01 = obniz01.wired("LED",{"anode":0, "cathode":1}); led0101 = obniz01.wired("LED",{"anode":7, "cathode":6}); led0102 = obniz01.wired("LED",{"anode":8, "cathode":6}); led0103 = obniz01.wired("LED",{"anode":9, "cathode":6}); spk01 = obniz01.wired("Speaker",{"signal":11, "gnd":10}); } /** * この関数の説明… */ async function f_led01_all_on() { led0101.on(); led0102.on(); led0103.on(); } /** * この関数の説明… */ async function f_countdown01() { led0101.on(); spk01.play(262);await ObnizUI.Util.wait(1*500);spk01.stop();; spk01.stop(); await obniz01.wait(500); led0101.off(); spk01.play(262);await ObnizUI.Util.wait(1*500);spk01.stop();; spk01.stop(); await obniz01.wait(500); led0102.off(); spk01.play(262);await ObnizUI.Util.wait(1*500);spk01.stop();; spk01.stop(); await obniz01.wait(500); led0103.off(); spk01.play(523);await ObnizUI.Util.wait(1*500);spk01.stop();; spk01.stop(); } /** * この関数の説明… */ async function f_led01_all_off() { led0101.off(); led0102.off(); led0103.off(); } /** * この関数の説明… */ async function f_init_obniz02() { detector02 = obniz02.wired("LED",{"anode":0, "cathode":1}); led0201 = obniz02.wired("LED",{"anode":7, "cathode":6}); led0202 = obniz02.wired("LED",{"anode":8, "cathode":6}); led0203 = obniz02.wired("LED",{"anode":9, "cathode":6}); spk02 = obniz02.wired("Speaker",{"signal":11, "gnd":10}); } /** * この関数の説明… */ async function f_led02_all_on() { led0201.on(); led0202.on(); led0203.on(); } /** * この関数の説明… */ async function f_countdown02() { led0102.on(); spk02.play(262);await ObnizUI.Util.wait(1*500);spk02.stop();; spk02.stop(); await obniz02.wait(500); led0201.off(); spk02.play(262);await ObnizUI.Util.wait(1*500);spk02.stop();; spk02.stop(); await obniz02.wait(500); led0202.off(); spk02.play(262);await ObnizUI.Util.wait(1*500);spk02.stop();; spk02.stop(); await obniz02.wait(500); led0203.off(); spk02.play(523);await ObnizUI.Util.wait(1*500);spk02.stop();; spk02.stop(); } /** * この関数の説明… */ async function f_led02_all_off() { led0201.off(); led0202.off(); led0203.off(); } obniz01 = new Obniz('OBNIZ_ID_HERE'); await obniz01.connectWait(); await f_def_obniz(); obniz01 = new Obniz(vchar_obniz01); await obniz01.connectWait(); obniz02 = new Obniz(vchar_obniz02); await obniz02.connectWait(); await f_init_obniz01(); await f_init_obniz02(); await f_broadcast_off(); label0101 = new ObnizUI.Label('label'); vchar_status = 'ホストまたはクライアントを選択してください'; await f_status(); btn_host01 = new ObnizUI.Button('ホスト'); btn_client01 = new ObnizUI.Button('クライアント'); vnum_count_max = 5; vnum_btn_flag = 'false'; while (vnum_btn_flag == 'false') { await ObnizUI.Util.wait(0); if (btn_host01.isClicked()) { vchar_status = 'ホストが選択されました'; await f_status(); await f_host01(); vnum_btn_flag = 'true'; } else if (btn_client01.isClicked()) { vchar_status = 'クライアントが選択されました'; await f_status(); await f_client01(); vnum_btn_flag = 'true'; } } if (vnum_count01 > vnum_count02) { vchar_status = 'ホストが勝ちました'; await f_status(); } else if (vnum_count01 < vnum_count02) { vchar_status = 'クライアントが勝ちました'; await f_status(); } else if (vnum_count01 == vnum_count02) { vchar_status = '同着です'; await f_status(); } await obniz.wait(5000); vchar_status = 'レース終了'; await f_status(); '-'; })(); </script> 8.参考資料 [*1 obniz複数プログラムからの接続](https://obniz.com/ja/doc/reference/common/connection/multi-connection) [*2 obnizローカルコネクト](https://obniz.com/ja/doc/reference/common/connection/localconnect) [*3 obniz Forum io.outputのpinの状態取得](https://forum.obniz.com/topic/185/io-output%E3%81%AEpin%E3%81%AE%E7%8A%B6%E6%85%8B%E5%8F%96%E5%BE%97)