佐藤さとる

佐藤さとる

梶研 [お料理やってない, BLE微妙..., NFC最高!]

2024年03月12日

お料理やってない, BLE微妙..., NFC最高!

出席率

スケジュール

短期的な予定

長期的な予定

進捗報告

お料理でどんな動作があるかを知る

前回) 精度は置いといて、機械学習は一旦できたぽい

お料理についてどんな動作があるか fuma さんと話す

→ 気づいたら金曜日にだったので今週やる

BLEビーコンのuuidを書き換えたい

Python で GATT プロトコルを扱いたい

どうやら Python で GATT 通信できるものがあるらしい

https://pypi.org/project/BLE-GATT/

https://micropython-docs-ja.readthedocs.io/ja/latest/library/bluetooth.html

HTTP ではなく、より低レイヤーの TCP を扱うイメージ

なんやかんや調べた結果、一旦ペアリングする必要があるとか?

Android端末 と ビーコンはそんなことしていないので違うはず?

よく分からないので一旦手を動かしてみる

シェルコマンドで BLE(GATT)通信してみる

BLEデバイスをスキャンする

$ sudo hcitool lescan

選択

$ gatttool -I -b [address]
スクリーンショット 2024-03-12 2.09.36.png (435.5 kB)

接続

[address][LE] > connect

エラー: Attempting to connect

スクリーンショット 2024-03-12 2.11.12.png (459.5 kB)

<details>

<summary>gatttool 使用法(日本語)</summary>

使用法:
   ガットツール [オプション?]

ヘルプオプション:
   -h, --help ヘルプ オプションを表示します
   --help-all すべてのヘルプ オプションを表示します
   --help-gatt すべての GATT コマンドを表示します
   --help-params すべてのプライマリ サービス/特性引数を表示します
   --help-char-read-write すべての特性を表示 値/記述子 読み取り/書き込み引数

GATTコマンド
   --primary プライマリ サービスの検出
   --characteristics 特性の発見
   --char-read 特性値/記述子の読み取り
   --char-write 特性値 応答なしの書き込み (書き込みコマンド)
   --char-write-req 特性値書き込み (書き込み要求)
   --char-desc 特性記述子の検出
   --listen 通知と指示をリッスンします

主なサービス/特性の引数
   -s, --start=0x0001 開始ハンドル(オプション)
   -e, --end=0xffff 終了ハンドル(オプション)
   -u、--uuid=0x1801 UUID16 または UUID128 (オプション)

特性 値/記述子 読み取り/書き込み引数
   -a, --handle=0x0001 ハンドルによる読み取り/書き込み特性 (必須)
   -n, --value=0x0001 書き込み特性値 (書き込み操作に必要)

アプリケーションオプション:
   -i, --adapter=hciX ローカルアダプターインターフェースを指定します
   -b, --device=MAC リモート Bluetooth アドレスを指定します
   -t、--addr-type=[パブリック | [ランダム] LE アドレスの種類を設定します。 デフォルト: パブリック
   -m, --mtu=MTU MTU サイズを指定します
   -p, --psm=PSM BR/EDR 上の GATT/ATT の PSM を指定します
   -l, --sec-level=[低 | 中 | 高] セキュリティレベルを設定します。 デフォルト: 低
   -I, --interactive 対話モードを使用する

</details>

bluetoothctl というコマンドもあるらしい.

デバイス一覧を出す

$ bluetoothctl
[bluetooth]# devices
スクリーンショット 2024-03-12 2.17.27.png (423.6 kB)

でてこない.

スキャンしたものの中から接続可能なものが出てくるらしい

[bluetooth]# scan on
スクリーンショット 2024-03-12 2.19.06.png (576.8 kB)

デバイス一覧が取れた

スクリーンショット 2024-03-12 2.19.44.png (839.7 kB)

gatt というコマンドもあるのでそれを使えばできる?

[bluetooth]# menu gatt
スクリーンショット 2024-03-12 2.23.12.png (796.5 kB)

ねむい.つかれた.また今度やる

BookWorm デスクトップアプリ側 で Pasori を扱う

疲れたので楽なBookWromをやった

Pasori を使う方法として

技術検証

Rust で Pasori を扱う

→ 良いパッケージがなかった

重いので Rust は諦める.

WebUSB を使って JavaScript から Pasori を扱う

USBデバイス全てに対応するAPIなのでとても低レイヤーを触っています

コード一部抜粋

    await send(device, [0x00, 0x00, 0xff, 0x00, 0xff, 0x00]);
    await send(device, [0x00, 0x00, 0xff, 0xff, 0xff, 0x03, 0x00, 0xfd, 0xd6, 0x2a, 0x01, 0xff, 0x00]);
    await receive(device, 6);
    await receive(device, 13);

    await send(device, [0x00, 0x00, 0xff, 0xff, 0xff, 0x03, 0x00, 0xfd, 0xd6, 0x06, 0x00, 0x24, 0x00]);
    await receive(device, 6);
    await receive(device, 13);

    await send(device, [0x00, 0x00, 0xff, 0xff, 0xff, 0x03, 0x00, 0xfd, 0xd6, 0x06, 0x00, 0x24, 0x00]);
    await receive(device, 6);
    await receive(device, 13);

カスタムイベントというやつを使ってみた

イベント: ウェブページ上で発生するあらゆるアクションの総称 SAMURAI ENGINEER

idm を読み取ったら発火するイベントを作成した

// イベントを定義
const readIdmEvent = new CustomEvent('readIdm', { detail: { idm } });
// イベントを発火
window.dispatchEvent(readIdmEvent);

// イベントリスナーを登録 (idm が呼ばれる度にonReadIdmが実行される)
window.addEventListener('readIdm', onReadIdm);

カスタムフックにして扱いやすくなった

const LendingPage = (props: LendingPageProps): ReactElement => {
  const subscribeIdm = useCallback(handleReadIdm, []); // カスタムフック
  const { start, stop } = usePasoriEvent(subscribeIdm);
  
  function handleReadIdm(idm: string) {
    console.log({ idm });
    handleNext();
  }

  ...
}

mizutani 先輩とのReactドキュメント輪読会が役に立ちました

イベントリスナーを削除するには同じ関数を与える必要がある

→ useCallback でいい感じに

もう少しいい感じにしたい (strictモードでは webUSBの動作が不安定)

せっかく JS だけで出来たので仮デプロイしました

https://bookworm-nfc.satooru.dev/

<iframe width="1002" height="573" src="https://www.youtube.com/embed/YtSkD-Lcao8" title="[BookWorm] Pasori x WebUSB 画面録画" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>

<iframe width="493" height="876" src="https://www.youtube.com/embed/BpsWhBDGYYU" title="[BookWorm] Pasori x WebUSB" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>

ほとんど完成してしまったのでAPIができ次第、続きをやります

進路関係

余談

neovim 始めました

windows の VScode があまりにも触りづらかったので vim に慣れようと思います.

ぼくのかんがえたさいきょうのIDEを構築しています

スクリーンショット 2024-03-12 1.46.58.png (1.4 MB)

広見城に訪れた

八草駅から5分程度の位置にある城

雨上がりで危なそうだったので攻城は諦めた

IMG_6133.JPG (5.7 MB)

牧野先輩の家に帰った @豊橋

行き

帰り道に竹島に寄るのが恒例と聞いたので寄った

IMG_6147.JPG (1.5 MB)

楽しくなって浜名湖にも寄った

IMG_6148.JPG (2.6 MB)

帰り

吉田城に行った

続日本百名城の一つで気になってた

IMG_6164.JPG (4.9 MB)

のんほいパークに行った

IMG_6218.JPG (2.6 MB)

メモ

DC:0D:30:0D:FF:CC

https://www.mikan-tech.net/entry/ble-gatt-study

https://www.mikan-tech.net/entry/raspi-sensortag-gatttool

https://jitaku.work/it/category/bluetooth/gatttool/