« 2025年2月 | トップページ

2025年3月

2025/03/16

Wi-Fi・BLEハイブリッドリモコンへのスリープモード導入

まずはお詫びから。一昨日の記事の電流測定時に校正方法を間違えており、電流値が約10%大きくなっていました。記事は修正済みです。

さて、
Wi-Fiを切っても(WiFi.disconnect(true);しても)消費電流が44mA39mAも残ってしまうことからスリープを入れることを検討する方が良さそうだと書いていました。今回使っているESP32にはスリープモードがライトとディープの2つあり、再起動のトリガーも複数用意されていて細かく設定できます。私の大雑把な理解では、ディープスリープからの再起動は電源投入に相当し(Arduinoでいうとグローバルパラメータを読み込んでsetup()からスタートする)、ライトスリープからの再起動はメモリ内容などを保持したままスリープに入った位置から動き出します。
今回の場合、スリープから再起動する時にジョイスティックの校正などを飛ばして素早く動かしたいので、ライトスリープを使ってみました。
ユースケースを考えると、スリープに落ちるときはリモコンを置きっぱなしにしているはずです。また、スリープに落ちているかどうかを意識して、特定のスイッチを押して再起動するのは煩わしい。そこで、ESP32に備わっているタッチセンサー機能を使ってみました。
ブレッドボードでタッチセンサー対応ポートにリード線を繋ぎ、プラ板に貼った銅箔テープと接合して銅箔の裏側からタッチして値を読んでみると、触らない時の値は大体40台後半で、触ると値が3〜8ぐらい小さくなることが分かりました。また、この値が銅箔テープの長さなどによって変わることも分かりました。この感じだと、あらかじめ閾値を決め打ちしない方が良さそうだと思い、スリープに入る前に10回測定して平均値を求め、それよりも2だけ小さい値を閾値にすれば安定して動作しそうだと見当を付けました。

次の写真が、ケース内壁の手前側(ジョイスティックのある側)へ銅箔テープを貼っているところです:
Jst09
銅箔テープの端の方、あとでESP32のタッチセンサー対応ポート(今回はT2 = GPIO2)に接続しやすいところへリード線をはんだ付けしています。リード線の反対側にはピンヘッダーを付けるので、先にピンの絶縁用に熱収縮チューブを通してあります。
銅箔が剥き出しのままだとショートの危険があるので、上から絶縁用の紙シールを貼りました:
Jst10
そしてケースに基板を収めて、あらかじめタッチセンサー対応ポートに取り付けたソケットと、リード線に付けたピンヘッダーを嵌合します:
Jst11
これでハード面の改造は終了です。ソフトの方は、Wi-FiとBLEそれぞれにタイマーを設けてタイムアウトしたら切断するようにしていた(BLEは切断ができないので再起動をかけていた)ところをまとめて、ひとつのタイムアウトでスリープするようにしました。具体的には、Wi-Fiのタイムアウトを1分、BLEのタイムアウトを2分にしていたところ、2分でスリープするように設定しました。

あと、使い勝手を良くするためにFirefoxの再読み込み(F5)を、空いていたOption+Pauseに仕込みました。これらを行ったあとの回路図がこちらです:
Jst12
…我ながら、ほとんど間違い探しですね。IO2にTOUCHが付いているところと、Option+PauseがF5になったことが差分です。修正したコードはGitHubに置いておきました

今回の改造前後の電流値比較がこちらです:
Jst13
前はBLEのタイムアウト後に再起動がかかって定常的なアイドリング電流が39mAあったところ、ライトスリープ導入によって4.3mAになっていて、電池の負荷は格段に少なくなりました。肝心のスリープからの再起動はとても安定しています。また、スリープから起きると直ちにBLEが繋がっているのが便利です。

今後も使い勝手が良くなるように修正していくかも知れませんが、これで開発は一通り完了です。
以上、何かの参考になれば幸いです。

パドラッパ from MacBook Air (M2)

| | | コメント (0)

2025/03/14

ラズパイ5とテレビでラグビーを観るための、Wi-FiとBLEのハイブリッドリモコン【2025/03/16追記・修正】

ネット動画(私の場合はほとんどラグビー)を観るために買ったRaspberry Pi 5(ラズパイ5)の電源スイッチをリモート操作する方法が分かったことに気をよくして、おうちサーバーからラズパイ5+関係AV機器を制御する仕組みを作りました。さらに、動画再生で頻繁に使う一部の機能を補助するデバイスも作りました。
これで様々なコントロールができるようになったものの、webアプリ用スマホとラズパイ5用のマウス、それに補助デバイスの3つが絡んできて、少々煩雑な感じになってしまいました。

やはりここまできたら専用マウスを自分で作った方がいいけれど機構をどうしよう、と思いながら秋月電子さんのサイトを見ていたところ、アルプスさんのジョイスティックをユニバーサル基板に繋ぐキットを売っていることに気が付きました(他にもいくつかありますが、これと目が合った)。そこでwebアプリの操作をWi-Fiで行い、ラズパイ起動後の操作をジョイスティックとスイッチで行うBLEマウス&キーボードを作ろうと思い立ちました。少々の紆余曲折を経てできたものは、こちらです:
Jst01

さて、こんな紆余曲折がありました。
まずはBLE機能だけで「いつもの」Seeed XIAO BLE Sense (nRF52840) を使った回路とレイアウトを考えたところ、ジョイスティックのADC2系統とスイッチ9個でXIAOのI/O数はピッタリで、「いつもの」ミンティアブリーズのケースに収まるメドは立ったのですが、なんだか面白くありません。どうせならWi-Fi経由でのラズパイ5電源&周辺AV機器の操作も1デバイスでやりたいと考えていたところ、Raspberry Pi Pico Wがちょうど合いそうだと思って買って検討してみたところ、MicroPythonではWi-Fiが不安定だったのとBLE HIDが難しそうだったので早々に諦めて、CircuitPythonにスイッチ。まずはWi-Fi動作を確かめてからBLEに移ったのですが、コードが見事に動かない。なんでかなと思ったら、現時点でのCircuitPythonはPico WのBLEをサポートしていないのでした
Jst02
続いてESP32でもCircuitPythonが使えるという情報があって試してみました。素の(Sが付いていない系統の)ESP32はプログラム領域をUSBメモリとして動作させることができないためシリアル経由で操作するのですが、これがどうにも不安定かつ煩雑で、ちょっとやっていられない感じでした。
以上の紆余曲折を経て、今回はESP32-WROOM-32EをArduinoで動かすという古典的な方法にしました。

先日の動画再生補助デバイスを作ったとき昔のコードではコンパイルエラーが出ていたことから、先にライブラリのバージョン等を確認しました。BLEについては3年前に公開されていたマウスとキーボードのコンボライブラリを使うことにしてサンプルプログラムをコンパイルしたところ、Arduinoのesp32ボードライブラリ(by Espressif Systems)のメジャーバージョンが3になるとエラーで弾かれ(現行最新は3.1.3)、バージョン2系最終の2.0.17であれば動きました。そこで、以後の作業は2.0.17を用いることにしました(公式の移行ガイドがあるものの、私の技量では手に余るので)。
すっかりPython慣れしているせいでカッコや変数型などに悩まされながらも、BLEによるジョイスティック周り、同じくBLEによるキー入力周り、Wi-Fi周りとブロックごとに作っていきました。ここで、BLE関連だけでメモリ使用量が85%に達していたのでWi-Fiを合体したらオーバーするのではないかと思っていたところ、案の定130%になってしまいました。どうしようか途方に暮れながら"Sketch too big"というエラーメッセージで検索したところ、同様のトラブルはままあることのようで(一例)、Arduino IDEのToolsにあるPartition SchemeからAPPに割り当てるメモリを初期値1.2MBから最大3MBまで拡張できる仕組みがありました。今回の場合ログなどを蓄積する用途でないためSPIFFSが小さくなるのは問題無く、無事にコンパイル・実行できるようになりました(最終的に2MB割当てて81%)。

ブレッドボードでの作業はここまでとして、回路図を整理し、部品配置をあれこれ考えて、ジョイスティックやスイッチ(キー)を上側の基板に、ESP32と電源系を下側の基板に置いて、ロープロファイルのピンヘッダーピンソケットでスタックすることにしました。これで組むと、ケース内の部品高さはジョイスティック部分で約16mm、他は約15mmになりました:
Jst03
高さが不揃いになるとスイッチのキーが寸足らずになってしまうので、ジョイスティック部分のケースを刳り抜き、これでケース内は約15mmで揃います(今度はジョイスティックが低くなるので厚紙を切ったスペーサーで調える)。前にキッチンタイマーを作ったときに使ったのと同じダイソーで2個110円のばんそうこうケース(ケース内高さ16mm)に入れようと考えていたのですが、その通りにできました。ちなみにケース内寸の短辺は約33mmで、いまは亡きプラケースのフリスク用に作られた基板(例:秋月電子さんスイッチサイエンスさん)がちょうど入ります。

スタックを開いた部品面が次の写真です:
Jst04
上側の基板にスイッチ類が並んでいます。下側の基板にESP32とLiPo充電モジュール、電源系切替ジャンパを置いています。ここで充電モジュールはTP4056Aを使ったもの(Aと無印はほとんど同じ)で、2000mAh級の18650バッテリーを充電するために1A給電するように設計されているのですが、使おうとしているバッテリーは160mAhなので充電電流を1C=160mA以下にしなくてはいけません。そこで電流制御抵抗を1.2kΩから10kΩに付けかえました。仕様書の上では130mAになる設定ですが、実測値は120mAでした。


次の写真は配線面。下側の基板にシリパラ変換器とレギュレータを入れました:
Jst05
ここではLiPoバッテリーに配線やバリが直接触れて傷やショートを招かないようにマスキングテープを貼っています。また、シリパラ変換器のVBUS(5V)ラインに付いている300mA程度のポリスイッチがESP32の突入電流で動作してしまい自動リセットを繰り返すのでバイパスしました(回路側のショートに注意)。

マスキングテープを剥がすと配線です:
Jst06
LiPoバッテリーの高さマージンがあまりないので(ロープロファイルのヘッダ&ソケットで6.14mm、バッテリーの厚さが4.0mm)、電池の入るところをできるだけ避けています。

さぁできた、というところでラベルも作って組み上げて試運転を始めました:
Jst07
すると、ブレッドボードの時と違ってBLEがとても不安定でした。色々と確認したところ、縦持ちの設計で写真の左側を手で持って操作するときにBLEが切れ切れになることが分かりました。実はこちら側にESP32のアンテナが入っているので、手で電波の放射が妨げられるという初歩的なミス。Wi-FiでRSSIを見ると、手で持つことで15dBぐらい落ちていました。それでもWi-Fiは繋がっていたのですが、BLEの方が弱いようです。元々Pico Wで同じケースに収める検討をしていた時にはアンテナが中央付近に来るのでちょうど良かったのですが、ESP32に路線変更したときに見落としていました。

これは作り直しかと思っていたところで横向きに持てば大丈夫だと分かり、スイッチの機能割り当てとラベルを見直しました。さらにベータテストで機能の見直しなどをして、最終的にできたものが冒頭の写真です(再掲):
Jst01
回路図はこうなりました:
Joysticktermsch

さて、ESP32-WROOM-32Eで気になる消費電流を測りました。以前XIAO BLEの消費電流を測るために作ったハイサイドI/Vコンバータは約50mAまでしか測れず、あっさりとクリップしてしまいます。そこで1Ωセンス抵抗と並列に0.1Ωを入れて、測定倍率を(1.0*0.1)/(1.0+0.1) = 1/11 (~0.091) としてみました。
【2025/03/16 次の一節を修正しました】
この状態で消費電流を測った結果がこちらです:
Jst08a
ブート時に44mA、
無線なしでのADCを含む定常動作が33mA、
Wi-Fi起動時にピークで210mA、
Wi-Fiのスキャンで88mA流れます。
Wi-Fiを切っても6mAぐらい増えた39mAが定常的に流れ、
Wi-Fi接続するとピークで210mA・ビーコン時に88mA・ボトムが39mAを推移します。
ここにBLEが重なるとアドバタイズ時に110mA流れ、Wi-FiとBLE両接続ではビーコン時に88mA・ボトムが39mAを推移します。 今回、Wi-Fiのタイムアウトを1分、BLEのタイムアウトを2分として、BLEがタイムアウトしたらソフトリセットを掛けるようにしているので、実質的なアイドリング電流は39mA強。バッテリーが160mAhなので4時間しかもたない計算です。これは、スリープを入れることを検討する方が良さそうです。
【修正はここまで】

コードはGitHubにリポジトリを作って置いておきました。
BOMは次の通りで、合計2547円でした。なお、電線・ハンダ・ロープロファイル以外のピン・ラベル等の副材はカウントしていません:
itemdetailpricepcssubtotal
MPUESP32-WROOM-32E3601360
JoystickAE-RKJXY10000066001600
S/PCH340E module60.8160.8
ChargerTP4056A module25.4125.4
R10k 0.1% 160820120
Reg.NJM2845DL1-3350150
Sub.ESP32 to Frisk3461346
Sub.universal for Frisk1202240
Sub.D-type Non-th40140
LiPo401430 160mAh230.41230.4
casefor adhesive plaster55155
Pin socketlow profile 1x20802160
Pin headerlow profile 1x4040140
SWDTS-63 and so on1012120
SWTS8855SG-P222122
SWTVBP0620120
SWSS-12D00-G520120
C10uF60160
C1uF13452
LEDOSG8HA3Z74A Green10110
LEDOSR5JA3Z74A Red10110
R1/6W 3x100k, 2x10k155

まとめたことで課題が出て良かったと思っています。改善検討をぼちぼちやりつつ、後半に入ったラグビーシーズンを楽しもうと思います。

以上、何かの参考になれば幸いです。

パドラッパ from MacBook Air (2017 → M2, 2022)

【2025/03/16追記・修正】
初出時の電流測定で校正を誤っており、約10%大きい値となっていたことに気が付いたので再測定し、記事中のグラフおよび値を修正しました。
修正前の内容を記録のため残しておきます:
この状態で消費電流を測った結果がこちらです:
Jst08
ブート時に44mA、
無線なしでのADCを含む定常動作が33mA、
Wi-Fi起動時にピークで230mA、
Wi-Fiのスキャンで99mA流れます。
Wi-Fiを切っても10mAぐらい増えた44mAが定常的に流れ、
Wi-Fi接続するとピークで230mA・ビーコン時に102mA・ボトムが44mAを推移し、
切れる前に200mAぐらい瞬間的に流れます。
BLEはアドバタイズ時に110mA程度流れ、
接続するとピークで120mA・ビーコン時に100mA・ボトムは44mAを推移します(Wi-Fiより若干少ない程度)。
あと、Wi-Fi接続中にBLEアドバタイズすると120mA流れます。
今回、Wi-Fiのタイムアウトを1分、BLEのタイムアウトを2分として、BLEがタイムアウトしたらソフトリセットを掛けるようにしているので、実質的なアイドリング電流は44mA程度。バッテリーが160mAhなので4時間はもたない感じです。これは、スリープを入れることを検討する方が良さそうです。
【ここまで修正前】

| | | コメント (0)

2025/03/12

MacBook Air(Mid 2017, Intel i5)故障、MacBook Air(2022, M2)への乗り換え【2025/03/13追記】

2019年3月からストレージを増量しつつ使ってきたMacBook Air(2017, Intel)が、3/9の夜に突然充電が遅くなり、そのまま一晩ACを繋いでおいても60%までしか充電できていませんでした。以前バッテリーがお亡くなりになったときはあっという間に満充電、あっという間にすっからかん、という症状だったので、今回はどうやらロジックボード(マザーボード)が壊れかけていると判断して、新しいMacを買うことにしました。私の使い方、即ち日常使いに若干のプログラミング程度であればAppleシリコンのMacBook Airで十分なのはハッキリしているのでリファービッシュ品を真っ先にチェックしたところ、2022年モデル・13インチM2のメモリ16GB SSD1TB品が(M3-16GB-256GBと同等の)166,800円で出ていました(いま見ると、もうありません)。また、ちょうど3/12(今日)にM4モデルが発売されることから新品は即納できないようで、逆に都合よく迷わず3/10の午前に注文しました。すると文字通りすぐに出荷されて、3/11の昼前に到着しました。選んだ色はミッドナイト、つまり夜空のような黒に近い紺色、すなわち「 本好きの下剋上」の主人公マインの髪色に近いものです:
M2_mba13
(前々から買うならこの色だと決めていました)

さて、
到着日3/11の朝からTimeMachineにバックアップを取って備えます。但しIntel Macからの移行ではバイナリの互換性が無いため「移行アシスタント」任せにするのは止めた方がいいという話を多く見ていた(一例)ので、私も最初はアプリケーション以外を移行アシスタントで移し、後からアプリをインストールする方針で始めたのですが、細々した開発ツール類(例えばESP32用のesptool.py)や自作プログラムのいくつかが動かなくなってしまったのと、そうまでしてもRosetta 2のインストールは避けられなかったのとで、3/11の作業は挫折してしまいました。それで今日は朝から工場出荷状態に戻して移行アシスタントで全て移行し、その後、実際に動かなくなったアプリを中心にインストールすることにしました。結局、動かなかったのはAndroid StudioLibreOffice、それにPythonぐらいでした(この機会にPython3はEOLを迎えてインストールパッケージも削除されたPython3.8をやめてPython3.11へ移行しました)。
もっともAppleシリコン対応アプリがあればより良いことは確かで、例えばArduino IDEのコンパイル時間を測ってみるとIntel用で51秒かかっていたのがAppleシリコン用だと25秒と2倍速いです(このプロジェクトは近日中に記事にします;実は記事を書いている最中におかしくなった)。
あと、esptool.pyは移行アシスタントを使用しても動かなかったのですが、これはシバンに書かれているパスが違っていただけのようでした(前は"/System"が頭に入っていた):
旧:#!/System/Library/Frameworks/Python.framework/Versions/2.7/Resources/Python.app/Contents/MacOS/Python
新:#!/Library/Frameworks/Python.framework/Versions/2.7/Resources/Python.app/Contents/MacOS/Python
(esptool.pyのためだけにEOLを5年前に迎えたPython 2.7.18をインストールするはめになりました)。

移行してみての感想ですが、やっぱりサクサク動くのは気持ちいい。また、キーボードのタッチが浅い割にフィードバックがしっかりしていて気持ちいいです。2代続けて「くさび形」のMacBook Airだったのでフラットな筐体が合うか心配していたのは杞憂でした。ただ、トラックパッドのクリック具合が前のと違っていてドラッグ&ドロップがうまくできず、早く慣れるようにコツを掴もうとしているところです。
ちなみに前のも完全に壊れたわけではないので、32bitアプリが走る環境を作っておくことなどを考えています。

以上、何かの参考になれば幸いです。

パドラッパ from MacBook Air (M2)

【2025/03/13追記】
ドラッグ&ドロップがうまくできないと書いていた件は、トラックパッド設定の「強めのクリックと触覚フィードバック」を切って解決しました。というか、このクリック感はハプティックスだったんですね。
M2_mba1302

| | | コメント (0)

« 2025年2月 | トップページ