M5-StickC(ESP32)をBLE MIDI Centralにして電子ピアノと繋ぐ

M5 Stick-CとRoland HP603をBLE MIDIで接続してデータ送受信するまで

経緯

Grove端子でつなげるMIDIシールド(necobit電子)を買ってみた。これで家の電子ピアノと繋いで子供に自慢しようとしたところ、どうやら有線のMIDI端子はないことに気づいた。とりあえずBluetooth MIDIとしては使えるようだ。マニュアル見るとAppleのみ接続を保証とかいてあるが、そんなことはないはず?

Arduinoのライブラリとかは一通りそろっていそうなので、簡単に接続できると思ったのだけど、そうでもなかったので記録しておく。

設定~接続まで

ここは特にサンプルコードどおりに勧めて苦労せず。スキャンしてMIDIのサービス持っているデバイスを探して接続して……

送信

その後、Note Onとか送ってみたら全然認識しない。色々調べたらとりあえず暗号化しないとダメとの事。以下を適切に追加すればOKだった。

BLEDevice::setEncryptionLevel(ESP_BLE_SEC_ENCRYPT);

M5-StickCのボタン押せば音が鳴るところまではできた。

受信

これがどうもうまくいかない。よく追加されている以下のコードを追加したけどだめ。

        const uint8_t notifyOn[] = {0x1, 0x0};
        pRemoteCharacteristic->getDescriptor(BLEUUID((uint16_t)0x2902))->writeValue((uint8_t*)notifyOn, 2, true);     

比較のためにnRF connect をAndroid端末に入れてみる。

connectして、MIDI serviceのIDをひらいてNotificationをenable. ちゃんと鍵盤ひいたらNotification経由でMIDIメッセージが読み込めている。

ここでようやく、電子ピアノ側の表示が、自分のM5 StickCで接続したときと違っていることに気づく。うまく拾えているnRF connectで接続したときは、こう。

M5Stickで接続しているときはこう。

と、M5 Stickの時には液晶のbluetoothマークの横にP+MIDIが出ていない。

差分がないかと、bluetooth snifferを作ってしらべようとSeeed Studio XIAO nRF52840 を買ってきた。いろいろ苦労はしたが、無事sniffer化できたので比較。比較前にM5 StickCのほうは暗号化を一時停止。

M5 StickC(自前)とnRF connectとの違いは、下の赤枠部分の有無。nRF connectで接続したあとは、IntervalのネゴシエーションがMasterとSlaveとの間でやりとりされている。

どうやったらこのシーケンスが走るかよくわからなかったが、ライブラリの中に、esp_err_t esp_ble_gap_update_conn_params(esp_ble_conn_update_params_t *params)というのを見つけた。

パラメータを見ると、

/// Connection update parameters
typedef struct {
    esp_bd_addr_t bda;                              /*!< Bluetooth device address */
    uint16_t min_int;                               /*!< Min connection interval */
    uint16_t max_int;                               /*!< Max connection interval */
    uint16_t latency;                               /*!< Slave latency for the connection in number of connection events. Range: 0x0000 to 0x01F3 */
    uint16_t timeout;                               /*!< Supervision timeout for the LE Link. Range: 0x000A to 0x0C80.
                                                      Mandatory Range: 0x000A to 0x0C80 Time = N * 10 msec
                                                      Time Range: 100 msec to 32 seconds */
} esp_ble_conn_update_params_t;

となっており、ここのmin/max intervalを設定して呼び出せば何かやってくれそう。適当に、以下のコードをconnect処理の後、notify handlerを登録した後辺りに追加。

    esp_ble_conn_update_params_t conn_params;
    memcpy(conn_params.bda, (device->getAddress()).getNative(), sizeof(esp_bd_addr_t));
    conn_params.timeout = 400;
    conn_params.latency = 0;
    conn_params.min_int = 30;
    conn_params.max_int = 36;
    Serial.println("try to update param");
    if(::esp_ble_gap_update_conn_params(&amp;conn_params)==ESP_OK){
        Serial.println("update param completed");
    }

今度は無事 nRFの時と同じように液晶にp+MIDIの表示が出るようになり、NotificationをがHP603から出て、M5 Stickで読み出せるようになった。snifferで見てみても、

と、なんとなくinrtervalをネゴって決めるような動作が見られた。

まとめ

  • 送信は暗号化
  • 受信はInterval parameterの更新

をそれぞれ追加すれば送受信は大丈夫そう。とりあえずGrove MIDIシールド+M5 stickCで有線MIDIとBLE MIDIの変換器を作るところまではがんばろう。

Raspberry Pi 3 + PS3 Eyemotion

rpi-updateでraspberry Pi3 の firmware アップデートが必要。

Fluiddの導入でwebカメラとして家に沢山あるPS3 Eyemotionをつなげようとした。サポートしているはずなのに中々認識されない。

いろいろ探していると、以下の情報があって、rpi-updateを実行して再起動したところ何事もなく認識された。

https://forums.raspberrypi.com/viewtopic.php?t=7397#p123185

ちなみにwebcam.txtの設定は、以下の通り。

camera="usb"
camera_usb_options="-f 1 -q 75 -y"

nRF Sniffer with Seeed XIAO BLE (J-Link無し)

Seeed XIAO BLEがJ-Linkとか無しに Snifferとして使えたという記録。

ESP32のBLE-MIDIライブラリをつかって家の電子ピアノを制御しようとしたところ、どうもうまくいかない。Google Playにあるアプリだと一応音が出る。とりあえず差分を見たい。Bluetoothだとお手軽なSnifferが結構あるのではないかと調べてみた。

BLE Sniffer調査

世の中でどういうものがあるかというと、

が無償で使えそうなところ。どちらもそれぞれの提供するチップの開発キットやドングルで動作。nRF52840とかCC2540とかその手のチップ。CC2540使ったドングルのほうがお安め?

nRF SnifferはWiresharkのプラグインとして提供されているが、PACKET-SNIFFERは独自のツール。Wiresharkベースのほうが後々良さそうなので、nRF Snifferにしてみる。

nRF Sniffer導入

HW購入

HWはnRF系のチップの乗ったドングルや開発キット、場合によってはFWを書き込む環境が必要とのこと。一番簡単そうなのは、Adafruit社の以下のドングル。SnifferのFWが書き込まれているとのこと。

ただAmazonで4,000円(2022/9)とちと値がはる。というわけで汎用のドングルを調べると、Seeed社の

が安くて入手性もよさそう。とりあえずこれにしてみる。すぐに欲しかったのでマルツで頼んだ。翌日配送で送料いれると2,400円くらい。

FW/SW導入

「nRF Sniffer for Bluetooth LE でデータ解析」を参考にすすめてみる。

FWやSWはNordicのページからダウンロードすればよいらしい。まずは関連ツール類としてnRF Connect for Desktopとかいうのをインストールした。

とりあえず、立ち上げて上記のようにBluetoothとProgrammerをインストール(必要かどうか不明)。Snifferを書き込むためProgrammerを立ち上げる。

ここで、seeed studioのXIAO nRF52840のwikiページを見てProgramming方法を調べると、boot loader書き換えにはJ-Linkを使えと書いてある。とりあえず持っていないのと、安く手に入るらしいJ-Link EDU miniとかはずっと欠品中。

ただ、先の、「nRF Sniffer for Bluetooth LE でデータ解析」を見ると

DFU モードで起動して書き込む方法と、J-Link Lite に接続してデバッグピンから書き込む方法があります。

とあった。

DFU(UF2)によるFW書き込み

Nordic 系のチップでの、Device Firmware Upgrade(DFU) は、bootloaderのサポート状況にもよるが、OTA/Serial/USB CDC経由でいけるとの事。また、UF2によるFWアップデートというのもあるらしく、これはDFUモードで起動するとFlash driveに見えるようになり、バイナリをドラッグアンドロップでコピーするだけというお手軽さ。

これ使っている人いないかと見たら、Nordicのドングルでやっている人がいた。幸いなことに、Seed XIAOもUF2アップデートに対応しているらしいとのこと。早速PCに接続して、Type-Cコネクタの直近の小さいボタンを素早く二回押す。

pir
https://wiki.seeedstudio.com/XIAO_BLE/ より

すると以下のようにドライブとして認識される。

もともとあるファイルを消したくなるが、そのままここにバイナリをコピーすればOKらしい。バイナリの準備の方法は、uf2のレポジトリから、uf2conf.pyとuf2families.jsonをとってきて(pythonある前提)、hexと同じディレクトリにおいて、

python uf2conv.py sniffer_nrf52840dongle_nrf52840_7cc811f.hex -c -f 0xada52840

などで変換。コピーしてから抜き差しすると、nRF connect等から無事 Snifferとして認識された。

そのあとのWiresharkの設定などはいろいろなページを参考に特に詰まることなく進められて、無事パケットのキャプチャーまで進められた。

カシオ小学生用 電子辞書比較

新小学4年生むけに電子辞書を探す

塾など通い出す時期となり、いろいろ調べさせるために電子辞書を物色しだした。上の子供の時は無理やり中学生モデルを使っていたが、小学生モデルというのもいいかも?と探し出す。

過去に発売されたモデルの違い

基本的に型番数字の2800が小学校(2000は低学年)。ちなみに3800が中学で、4800が高校。最新のSX3800は小・中学生両対応モデルだけどかいうのもあるけどまだ高い。3年後に中学モデルを買うかな。中古価格を見ると、多分タマ数の多い順、高校、中学、小学の順に安くなっているようだ。

現行品のSX2800は、新品で3万近くとかさすがにつらいので(辞書の値段全部足すとまぁそんなもんかも?)、オークションやメルカリで探すも、どういう違いがあるのか今いちわからない。調べてみると以下のような感じ。

モデル発売年度液晶サブ液晶コンテンツ数
XD-D280020125.3インチ50
XD-N280020135.3インチ60
XD-U280020145.3インチ70
XD-SU280020145.3インチ70
XD-SK280020155.3インチ100
XD-SX280020215.7インチ130
過去に発売されている小学生モデル(低学年のぞく)

SKまでは毎年出ていたのに一体SXまで間が空いたのはなぜ?ちなみにXD-U2800等、S無しのがキーボードの下にサブ液晶がついているやつ。それ以降はサブ液晶が無くてキーボード大き目。まだまだ高いけどSXの大型モニタは気になる。

詳しい比較表はこちら

とりあえずの結論

UとSUってサブ液晶が無くなっただけ?SU->SK->SXは順当にコンテンツが改良されているかんじ?今時っぽく英語が強化?

うちにある古い中学生モデル、D3800を見た感じは、5.3インチ画面でもそこそ大きく十分な感じ。サブ液晶モデル最後のD-U2800あたりの安いところをねらいつつ、SKとかがちょい高めくらいであればそっちかなー。

XBOX series Xのdev mode

Xboxを購入

PS5が当たらない。MSFSついでにGAMEPASS の Ultimate 3年分追加してあったので、Xboxを買ってみた。ヘルプやメニューなどもところどころXbox ONEの物がそのまま残っている感じ。

Developerになってみる

$19とかで普通に自作プログラムが動かせる環境があるとか

UnityアプリをXbox Oneで動かす方法

Xbox Series X でも同じとのことなので、とりあえず登録してみる。

とりあえずDev Mode へのスイッチアプリを本体でdownloadして手順を進めるが、最後のほうでなぜか本体のアップデートを要求される。最新版なのに。

結局隠し設定から有効化

検索してみると、MSのフォーラムでも同じ悩みの人が。設定の本体情報でLT+LB+RT+RBを押せば、開発者向けメニューにアクセスできてそこで有効化、との事。元投稿は Xbox One 向けらしいけどとりあえずXSXでもいけた。

almost there trying activate dev console

とりあえず何かサンプルを転送してみようか。

インターホンの修理

こちらから外に声が伝わらない

インターホンの調子が悪い。具体的にはこちらの声が外に聞こえない。

うちのインターホンは、アイホンのこれ↓

ご家庭のセキュリティがもっと身近になるワイヤレステレビドアホンROCOポータブル新発売

システム
https://www.aiphone.co.jp/docs/newproduct/20071022188.html より参照

上記のような構成で、カメラ付。外からの映像音声は聞こえるので、とりあえず外→室内の通信路は大丈夫。次に、ずっと使っていなかったワイヤレス増設子機を引っ張り出してきて、モニター付き親機とつなげたところ問題なし。親機のマイクは生きていそう。

後は外のスピーカーか、室内→外の通信がこけているか。

故障例の調査

とりあえず、他に壊れている人いないか検索してみると、意外とメジャーな故障のようだった。

アイホン DIYでインターホンスピーカー交換

ドアホンが故障!?外部スピーカーを交換したら約1,000円で修理できたでござる

パナソニックも結構つらつらと故障例が見つかる。防水フィルムが劣化して、スピーカーがダメになる例が多いみたい。とりあえずばらしてみる。

とりはずし

インターホン、うちの取り付けは以下の物

ファンクションユニットアクシィ:アクシィ2型

フラット横型ポスト
https://www.lixil.co.jp/lineup/gate_fence/acssy/variation/2/ より

うちはデザイナーズパーツとかいう柱の間についているので、説明書でいうと下の例のつき方。

アクシィ2型取付説明書 http://www2.toex.co.jp/rp/dfw/exsas4/torisetu/files/A59502A.pdf

なんとなく構造はわかったのだが、このセンターブロック上キャップは抜け止めがあるので、どうやってとったらよいものか。と思っていたら同じ抜け止め金具でセンターキャップを取り付けている、ウィルモダンシリーズの取説が見つかった。

http://www2.toex.co.jp/rp/dfw/exsas4/torisetu/files/UA16502A.pdf

普通にマイナスドライバーでこじればよかったらしい。

取り外すとこんな感じ、電源も通信もこの細い2本線でやっているようだ。

本体分解

無事門柱からとれたのでばらしてみる。

元のスピーカー

これが問題のスピーカー。

裏っ返してみる。よくこの防水シートがぼろぼろの物があるが、キレイに残っているので一見問題なさそう。

適当なスピーカー

aintendoで買ったやつかな?手元にあったスピーカーつけてみたら、無事音が出るようになった。

部品購入と交換

型番からするに、以下の表にあるモノっぽい。

http://www.kdkk.co.jp/wp-kdkk/wp-content/uploads/2014catalog_sk.pdf

ただ、川崎電線の最近のカタログでは載っていないので生産終了か?

というわけで、Amazonで似たようなものを購入。もとのが20Ωにくらべて16Ωだが、まぁなんとかなった。

最後に

しかし、今のインターホンがもうディスコンになっているとのこと。互換表見ると、今の親機 WF-2MEDに対応した子機が現行製品ではないようだ。下手すると一式交換コースだったかと思うと、なんか儲かった気がしたのでアピールしておいた。

m5 Stick-C で Pulse Oximeter

きっかけ

最近家族の発熱があったりするのと、コロナ軽症者は血中酸素濃度をモニタして症状を判断するとのことなので、2 月くらいに買ってほったらかしにしていたセンサー、MAX30102 をつかってパルスオキシメーターを作ってみた。

ちなみにセンサーは、Aliexpress で 200 円くらいの、これを買った→MAX30102 Heart Rate Pulse Breakout / Blood Oxygen Sensor Module

調査

手元に M5 Stick-C は余っているので、とりあえず Arduino のライブラリがあればそれっぽくなりそうとのことで調べてみると、京セラコミュニケーションシステムズのサイトで、作成例を紹介している記事があった。→M5Stack Basicで通信機能付き心拍・血中酸素モニタを作る

上記の記事は実際には MAX30102 を接続しているようなので、ほぼいけそう。元ネタはMAXIMのサイトSparkfunのExampleかな。測定原理とかは、このへん →GUIDELINES FOR SPO2 MEASUREMENT USING THE MAXIM® MAX32664 SENSOR HUB

モジュールとは、I2C 通信でいけそうなので、Grove端子からの接続で OK そう。接続は、このケーブルを使おう→ GROVE – 4ピン-ジャンパメスケーブル (5本セット)

モジュールの電源や信号レベルはどうなっているか、このモジュールの回路図はないか見てみると、回路図付きで以下のサイトがひっかかった。

Pulse Oximeter MAX30100/MAX30102 – how to fix wrong board

タイトルからしてどきっとするが、一応電源は M5 系の Grove 5 V で問題なさそう。ただ、I2C の信号線が 1.8 V でプルアップされているようで、記事にもあるように 3.3 V 系 だと不安定だと何とかなるんじゃないかな(事実なんとかなった)、とそのまま接続する事に。それより気になったのは、1.8 V を生成しているはずのレギュレータが、2.8V 品が乗っているものがあるとかいう指摘。テスタで測ったところ問題なく 1.8 V が出力されていたので、これは杞憂に終わった。

接続、コーディング、測定

とりあえず接続はこんな感じで、G32 -> SDA, G33 -> SCL。ソフト的にはI2C周りはデフォルト設定でいけそう。

M5STICK-CとMAX30102の接続

VSCODE 上 の PlatformIO で、同じようにライブラリを導入。ソースはほぼそのままで、とりあえず適当に画面周りだけ修正。IRと赤色それぞれの測定値を、50個ためるバッファがあって、半分の25個更新しては、ライブラリの関数を呼び出す構造。関数内では、波形のピーク検出に基づいて脈拍の計算と、両センサーの変化率の比から酸素濃度の計算、という感じ。センサーに指を置いて測定すると以下のように表示される。指汚い。

なんか指を押し付ける力で結構ばらつくなぁ、と思ってたんだけど、本家の動画見てもそんなもん?という感じ。

これだと測定中不安になるので、serial plotter用に片方のセンサー値だけ出力するように変更して、リアルタイムにグラフをみながらやろう、という事に。

グラフ見ながらやれば、どうやれば安定できるか、コツがつかめるような気がする。

電源入れて測定開始までは LED 光らないようにしたりして、最終的なものは、以下においた。

https://github.com/Keitark/pulseoxi.git

さいごに

やはり、ここ最近作っている人が多いかんじ。今回はライブラリはそのまま使ってみたが、いろいろ手を加えたり、自分で計算している人もいるようなので、そのうち調べてみる。

参考になるサイト

その後、いろいろなサイトを見てみると、いろいろ情報のまとまっているサイトがあったので、紹介。

脈拍センサーMAX30102を試す(1) Githubのレポジトリの不具合などの情報もあり、2017年なのでもう直っているのかも。

[ESP8266][MAX30102] MAX30102でパルスオキシメーターを作る Datasheetなどにある計算原理などについての確認など、Sparkfunのモジュールの不具合情報みたいなものもあり。

dovecot error on Serversman@VPS

POPでメールが取得できなくなっていた

このサーバーでは dovecot 経由で POPサーバーを立ち上げ、普段は Gmail 経由で取り込んでいた。めったにメールが届くものでもないので、しばらく気づかなったが、5月のはじめあたりから接続できてないようだ。ちょうど Serversman@vps の Cent OS 7 で yum update かけていろいろ設定など見直したあたり。原因を見ると、Connection refused とからしい。

dovecot まわりの確認

systemctl で状態を見ると、failed になっている。とりあえず手動で startかけたら、time out とのこと。status を見てみろとのことなので、systemctrl status dovecot.service でログを見ると、

Can't open PID file /var/run/dovecot/master.pid (yet?) after start: Too many levels of symbolic links

との事、なんだろう。同じような悩みの人いないか検索してみると、[SOLVED]Dovecot issues on new ispconfig installation on vps Centos7 などが引っかかる。vps で CentOS 7 なところも同じような…… 解決策を見ると、/etc/systemd/system/multi-user.target.wants/dovecot.service 内の記述、

PIDFile=/var/run/dovecot/master.pid

を、

PIDFile=/run/dovecot/master.pid

にしろとの事。ls で確認しても、/var/run -> ../run なので、同じモノっぽいけれど、こうするといいらしい。本当か、と試したら直った。

何が原因なのか

既に調べた人がいた。Can’t open PID file /var/run/nginx.pid (yet?) after start: Too many levels of symbolic links(タイトルは英語だが)に同じように悩んでいる人がいて、Systemctl fails to start service: Too many levels of symbolic links が紹介されていた。

The recent CentOS 7.7 update includes an update to systemd-219-67, which changed how systemd opens symbolic links and causes incompatibility issues with old kernels.

が原因らしい。確かに 今の systemd は、219-73.el7_8.5 となっているので該当していそう。systemdを更新したらエラーも同様の話。とりあえず暇があったらもう少し。

ラジオを買った

子どもがラジオに興味を持った風なので、病院がえりに Shigezoneでラジオを買った。

電動精密ドライバーとかいうものも売っていた。あると便利そうだが、自分的にはそんなに使う事あるかなぁ、という感じだったので、とりあえず見送り。

家に帰って、周波数帯変更用のチップ部品を取り付けようとして裏を向けたところ……

ラジオ裏面

あ、こういう時使うなと気付いた。せっかく使う機会があるので、明日の外出帰りに電動ドライバー買って帰ることにして今日はこれまで。

(追記) その後買ってきて試したところ穴が深いせいで、付属ビットだと届かない。一緒についてた先端の細い部分が長いビット(持ってない人にはわかりにくい)だと届くが、サイズがちょっと大きい。

いろいろなビッドが使えますよ、という事で確かに手持ちの精密ドライバのものが使えた。ちなみにメーカーのページはここ。製品としてのページは、これが近い。微妙にセットされているビットの種類が違うが誤差の範囲だと思う。それを見ると、ビットのサイズはH4 x 28 とのこと。確かにノギスで測ると4㎜。ビットはそれなりなので気になる方は違うもの推奨という事らしいので、4㎜サイズのよさげなものを探してみよう。

とりあえず、同梱のチップ抵抗つけて組み上げ。ちゃんと日本対応になる。1314 OBCとかたまに入る。ちなみに子どもからは、「これなら普通にRadikoでいい」という反応。