hyousi

  • Home
  • 一覧
  • [自キ]磁気キーボードを作りたい。5週目

    ダイジェスト⑤

    消費電力

     今手元にはmonsgeek fun60proしか磁気キーボード無いのですが、usbテスターみたいなのにつなぐと当然のように200mAを超えているんですよね。たかが文字入力デバイスが?
     高速スキャンのためのマイコン、60個にも及ぶホールセンサ。そういうことです。200mA前半だと何かしら工夫している方だと思いますが、それでも100mA台を目指したいなとなんとなく思います。
     ホールセンサを都度スリープしたりしているメーカーもありますよね。
     ADCが強くスキャンも早いstm32f446reとかだと100mAちょい消費します。+ホールセンサx60個なわけですが、ホールセンサもdrv5055だと2-4mA, 5056だと6-10mAです。それぞれ間を取って60掛けると180mAとか480mAとかになります。(5056は使いたくても使えないですね!)この組み合わせだと300mAは覚悟しなければならないですね。
     その面ではアケコンは文字入力デバイスでないですしスイッチ数も少ないですから、磁気スイッチを採用するのは向いていると思います。

     一個一個の自己発熱はそこまで大きくなさそうなので基板に逃げそうな感じはありますが全体としてみたときの消費電力は1Wを超えてきますからなかなかであります。
     あと動作が不良で電圧が~という人がまちまちにいますが細かいことを言うとで電流です。まあ電力と言ってしまえば間違いがないわけですが200~300mAも食うわけですから磁キはセルフパワーのUSBハブにつなぐべきかなあと思います。ケーブル付きusbハブ改めスプリットケーブルというものが流通していますが、消費電力大きいものを一方に接続すると不足しそうです。古い、安い、マザーボードや電源だとそもそも500mAきっちり出力できませんしね。

     当初はトップアウト付近検出用とボトムアウト付近検出用でホールセンサ2個使うデュアルセンサー磁キとか面白そうでやりたかったのですが、悩みます。試作でウェイって言って終わりかもしれない、

     別にセルフパワーにつなげばよいのだし、問題は何もないのですが私の気持ちとしては消費電力大きなまま完成とするのは非常に葛藤があります。しかし、省電力にするとパーツもやや高いものになってしまうし実装もワンクッション挟んでめんどくさい、、、というところがありますね。

    測定治具

     JLCPCBに磁力測定用の治具を発注しました。アルミで11200円でした。アルミだと軽そうなのですがこの体積あると十分重量感がありその点十分です。
     金をケチってワンピースでデザインしたわけですが、今になると結局基板がたわんでしまい、以前よりはしっかりとれるとはいえ完ぺきではなかったです。基板が押されてたわむというよりは。そもそも反っているわけです。金をケチらず最初から2ピースで発注した方が安く済むし満足度も高いし時間も無駄にならなかったかもしれないです、、、写真はネジとかついてないですが使うときはねじもスペーサも取り付けています。

     この測定で思ったことは、そもそもこれで基板のたわみが問題になるのですから、キーボードの状態での0.01mmとか0.001mmの精度ってどれだけの意味を持つのでしょうかということです。もちろんこれでちゃんと測定できていないのは私のミスなわけですが、実際の使用場面ではもっとめちゃくちゃな状態なわけです。
     人の指は1umの変位を検知できると私は信じていますが、ケースにフォームに基板にプレート、キーキャップと取り付けられたものを押したところで指とホールセンサの関係はいたるところにばねが挿入されめちゃくちゃな気がしています。この磁力測定でも、スイッチ押すんじゃなくてヘッドに磁石張り付けて、基板と接触せずにやるべきですよね。

    再測定①

     基板を固定して実際に近い環境で測定してみました。およそ以前と同じです。
     逆二乗式でフィッティングしたかったのですが、この環境だとbottom付近、押し込んだところで磁力減衰がおきてしまう結果となりました。
     実際は磁力が減衰しているのでなく、基板等々がたわんでしまっていることで発生しています。実際のキーボードの状態に即していると言えばそうなのですが、あまり正しい状態ではないと思います。

     この場合、補正値としてcos(定数項/磁極距離)を割合としてかけることで結構合ってきます。組み立て後の精度を考慮するならばこういうこともありかなと思います。

    再測定②

     基板にスイッチを載せて押すと基板のたわみが邪魔ですから、結局スイッチから磁石を取り出しマイクロメータヘッドに取り付けることにしました。これなら非接触なのでそういった外的要因を無視できます。これはこれで色々あるのですが

     これは一つ測定結果です。

    磁力 – 磁極距離-^2特性です。

    磁力 – 距離特性です。

    マイクロメータ上での距離と近似式から逆算した距離の差です。
    この場合で最大0.025mm程度のズレです。
    読み取り距離の安定度とはまた別なので市販品でいう精度とはまた別ですが、この程度フィッティングできそうです。

    温度特性②

     drv5055の温度補正機能付きのA2に加えて温度補正機能のないZ2も購入し、比較してみました。
     方法としてはホットプレート上に基板、スイッチを載せ磁力を測定します。一般に磁石は0.12%/Kで磁力が下がるそうです。A2のホールセンサはそれを補正するために出力が0.12%上乗せされるそうです。

     加熱し、その後放置し冷却しています。基板はホットプレートに乗っているだけなので、ホットプレートの温度と基板とスイッチ内の磁石の温度は同一ではありませんが、実際のキーボードでも基板の温度とスイッチ内の磁石の温度が同一とは思えないので、これが正しいとは思いませんが、恒温槽で実施するのが実際的であるとも言えません。
     とはいえ恒温槽で試験した方がわかりやすいのでやるべきなのですが借りたりしないといけないしとりあえずホットプレートで、、

    start 常温
    700 40heat
    1100 50heat
    1500 60heat
    1900 70heat
    2300 80heat
    3000 90heat
    3800 100heat
    4300 down

     ADC出力を1secごとに100サンプルの平均を読んでいます。初期値を0としています。
     A2は温度上昇とともに読み取り磁力が強くなっていきます。これはホールセンサの温度が磁石の温度より高いため補正が過度に働いているためと思われます。
     Z2は温度上昇とともに読み取り磁力が弱くなっていきます。これは温度上昇で磁石の磁力が低下しているためと思われます。
     そしてどちらも冷却後、初期値より読み取り磁力が弱い値で安定しています。調べてみるとネオジム磁石は高温に弱く80で以下で使用するべきのようですね。そのせいか。。。?

     温度補償のあるモデルを使用するべきなのか、温度補償をするべきなのか、
     A2モデルもZ2モデルもどちらも温度による変動量は同じぐらいで明確にどちらを使うべきとかはなさそうです。A2を使用し温度補正を行うならば、補正を補正することになるのでなんだかなというところがあります。
     磁石の温度は室温に近いのかなと思うので、暑い時寒い時とでその分補正はした方がいいように思います。
     室温が変わらないのなら起動時に補正できそうな気はします。そもそもいろいろが安定するのかどうかというところ、、

    おわり

     スリープ機能付きのホールセンサ買ってみたりもしたのですが出力が安定しないとか、そもそも動かない原因不明とかなのでsot23タイプでいいかとなっているこの頃。
     mcuのADCピンとfetスイッチとでマトリクスを組むのが60%とかキー数多いものではひとまず考えたい。それは置いといてまずrp2040で簡単に作れるようにしておきたい。ので今までの結果からrp2040zeroを使ったラピトリマクロパッド作る、qmkに対応する、設定ソフト作る、のが次やること
     仕事忙しいし疲れてるしでやる気出ないしちょこちょこ進めたい

    やる気がないのでテキトウ
    いろいろ手は動かしてるのですけどめんどくさいのでこんなんで、、

  • [自キ]磁気キーボードを作りたい。4週目

    進捗ダイジェスト4週目

    磁気キーボード話

     雑談です。
     磁気キーボードを作ろうとちょこちょこ遊んでいるわけですが、作り手目線で素晴らしいキースイッチとはなんでしょうね。いくつか挙げてみます。

    • 磁力が強い→逆2乗則より強いほうがsnがよさそうです。とはいえホールセンサの感度次第なので、強いほうが良いというより一定以上強いほうがいいという感じですかね。私はその一定を知りません。
    • 磁石が近い→逆二乗則より離れるとどんどん減衰していきます。離れるごとに、隣のキーとのアイソレーションが相対的に悪くなる(実害はほぼほぼないレベルだが)。
    • ショートストローク→逆二乗則より保証精度は底打ちに近いほど高くなります。ストロークが長いほど距離が離れますから、最高精度は同じでもストロークが短いほど最低精度が良くなります。
    • 軸ブレが少ない→作り手はスイッチの軸ブレを考慮せず精度を謳うものですが、それでも軸ブレが少ないほど実際の精度が良くなります。

     そんな製品が確かありましたね。ZENAIMさん、シンプルに正しいものを作っておられる。ただユーザー目線だと入手性(高価、スイッチ単品で買えない)やキーキャップの面で不利ではあります。スイッチとキーキャップの販売待ってます。

     その他でも、ユーザー目線で考えると真逆のことも多く、難しいものです。
     市販の磁気スイッチを見ると底が塞がる(→磁石が遠い)方向に進んでいます。打鍵音や底打ち精度のためだそうですが、いい面だけではないということです。

     またワッシャーのようなものをキー底に挿入するショートストロークMODも流行り、使用できる部品情報や、専用部品として販売されたりもしていますね。いろいろユーザーが開拓することは素晴らしいことですが、これはスイッチからの距離が離れる方向に行きますからリリースポイントの精度は悪化します。磁石との距離が遠くならないように天面側に加工を施す方向にするとプレスポイントの精度が向上しよりよくなります。構造的に難しそうですが、そういうmodもなんかできないかなあと考えたりなどします。
     zenaimやmod等ありますが、ショートストロークはそもそも強いのでしょうかと私は疑問に思うところも。ラピトリってストロークを無視して入力する機能なわけで、ストロークという要素とは完全に独立です。
     言い換えれば連打が早くても抜けないための機能なので音ゲーとかだと強そうです。
     インターフェースとしてショートストロークが使用感が良いというのは個人の好みですからどうぞであります。

     その点でいうと私はショートストロークは好みではありません。私の打鍵の仕方として、非入力時にもキートップに指がついていたいのです。なので、打鍵の瞬間のみ指が触れるノパソ等のようなキーボードは苦手です。なのでキーストローク=指の可動範囲となります。ショートストロークでは指の可動範囲が例えば2mm程度となり指が窮屈になります、予備動作が取れないのですよね。
     そもそもショートストロークとロープロファイルをごっちゃにしている人は恥なので滅びてください。ショートストロークのzenaimはそこまで低背でないし、低背スイッチは全然ストローク長いです。

    温度特性

     相変わらず実験などはできるはずもないのですけど、ホールセンサのデータシートなど確認してみました。
     drv5053も温度補償あると思っていたのですけどなかったみたいです。「優れた温度安定性
    – 温度範囲の全体で感度 ±10%」としか書かれていませんでした。そもそも本番で5053を使う予定はないですが、出力電圧固定で電源の揺れをもろ受けたり、あくまで規格ですが感度幅が100%あったり←???、緩い用途でしか使えないもので良く調べもせずに購入したこと自体が間違いでした。なんだこれ
     5053は省き、5056は5055とほぼほぼ同じなので5055を例に表や特性図を抜き出してみます。

     5055は磁気検知範囲が決まっていて、出力電圧と感度は電源電圧に比例します。ADCのrefと同電位であれば電源の揺れは考慮しなくてよく、これをレシオメトリックと言うそうです。以前温度特性を軽く見てみようとしたときの意味不明さは電源の揺れの可能性は高いです。経験上そういう変化の仕方でしたしね。

     磁石ない時の電圧の温度特性です。温度変化はほぼほぼ考慮せず良いみたい

     Aモデルは温度が上がると感度が上がります。これは温度が上がると120ppm/Kで磁石の磁力が下がるのを補償しているそうです。

     Zモデルは温度補償機能がないようです。低温では若干変化していますね。

     規格表も見てみます。あくまで規格なので、実際の仕様の範囲ではどの程度のレンジを取るのかは実験してみないとわかりません。
     Vqdtというのが磁石なしでの出力電圧です。+/-1%と、特性図で見た通り温度による変化はなさそうです。
     Vqを見ると温度関係なく7%程度幅を取って揺れるみたいです。また、sensitivityを見てみると、感度は10%程度の幅を持っています。
     スペック上の最大最小ですが、出力が7%, 感度が10%幅をもってばらつきがあります。この規格には個体差や使用時の揺れやら全部含んでいますから実力値はわからないですね。0.001mmとかの製品がある以上は出力の揺れというのはほぼほぼ無いんだろうなと思ってしまいますがどうなんでしょうね。
     とりあえず磁気キーボードはスイッチだけでなくホールセンサにも出荷時キャリブレーションが必要とか、手動キャリブレーションはホールセンサも含めてキャリブレーションしているということです。

     Stcが温度補償で、Aは磁石のTC0.12%を補償している。Zは補償しない。なので温度補正機能をウリにしているzenaimやらhm66やらはdrv5055でいうところのZのようなホールセンサを使用しているのでしょうね。
     面倒であればAのような勝手に補正してくれるものを使うのがよさそうですが、基板の裏側のスイッチの中の磁石の温度って、ホールセンサの温度とどれくらい一致するんでしょうか。一致せずともオフセットで済むならAで相殺すればいいですが、そこにずれがあるのならばZの方がよさそうな感じがありますね。どうなのでしょう、、

     ついでに消費電力を見てみると、5055は電流が2-4mA, 5056は6-10mAとなっています。5056の方が精度よく見れてよさそうと思っていたのですが、消費電力倍以上となると微妙ですね。60キーとして、ホールセンサだけで5055は120-240mA, 5056は360-600mAとなってしまいます。狂ってますね。
     スリープ機能付きのホールセンサを使用しているメーカーもありますが、順当だと思います。市販品をusbテスターで接続すると当然のように1W消費していますから、磁気キーボードって何なんだと思ってしまいますね。正気ではないと思います。

     データシートちゃんと読んだ方がいいなとなるわけですが、すると中華の安い部品を検討するとき詳細な情報が公開されていなくてどうしたものかとなるのですね。oh49とか半額以下です。

    マルチプレクサ

     16chMUX、CD74HC4067SM96の動作確認は行いましたが、実力がどんな感じなのかオシロで観察してみようと思います。
     マルチプレクサはセレクトピンのhigh/lowでチャンネルを選択します。enableピンはピッチ変換基板作ったときにいらんやろと思っていたらしく使えません

     picoのgpioからセレクトピンを切り替え、分圧した様子を観察しています。
     arduino標準のだと高速で行えないらしく、#include “hardware/adc.h”#include “hardware/gpio.h”#include “pico/stdlib.h”してgpio_putして制御します。

     1usごとに切り替えています。切り替わり部分を拡大すると250ns程度何やら溜めがあり、次のchに切り替わり始めています。この部分でセレクトピンがカチカチしていると思うので、selectピンと合わせてみてみます。

     セレクトピンの切り替えの様子も見てみます。今回セレクトピンは(0000)→(1111)の切り替えを繰り返させています。

     多少バラバラしていますがセレクトピンは80nsぐらいで次のビットを切り替えているでしょうか。もし同時に出来たらだいぶ時間を短縮できそうです。

    s0 vs s1→80ns程度

    s0 vs s1→150ns程度

    s0 vs s3→230ns程度

     muxの出力とセレクトピンとも並べてみます。最初に切り替えるs0 vs dataでは250ns程度差があります。最後に切り替えるs3 vs dataでは50ns程度の差があります。

    s0 vs data

    s3 vs data

     s3が切り替わってからdataが切り替わるまで50ns程度ですが、先ほどは長くてセレクトピンの切り替え間隔が80ns程度ありました。ふと思いますがこの時、50ns時点で切り替わり始めたりはしないものなのでしょうかね。

     0000→1111と4つすべて切り替えていましたが、0000→0001とs0だけの切り替えでも見てみました。この時は先ほどのs3 vs dataと同じように50ns程度で切り替わり始めています。うーん

    s0 vs data

    datasheetを見てみるとセレクトピン→出力の遅延はtypで20数nsなのですが、maxの値は電源電圧が高いほど良くなるようで、3.3Vだとあまりいいところで使えていないんじゃないかなと思ったりします。実際今回は50ns程度な感じでした。(どちらにせよセレクトピンの切り替えに80nsかかっているので足を引っ張ってはいないのですが)CD74HC4067SM96はch数が多いのは素晴らしいのですが、あまり性能的には向いていないかもしれない。

     次はホールセンサをマルチプレクサに接続してみたいと思います。2つのホールセンサを接続し、10us間隔で切り替えています。

     割とノイジーに見えますね。また大分立ち上がりがなまっており最低でも500nsは待たないとならなさそうです。

     マルチプレクサのオン抵抗が大きいようです。テスターで測定してみると150ohm程度ありました。ホールセンサ出力とmuxの間に100nFのコンデンサをバッファーに挟んでみました。だいぶ改善しています。しかしこれだとホールセンサの隣にデカップリングとバッファーとで2こコンデンサ入れないとならないですね、、、

     この状態で、切り替え間隔を2usにしてみました。次の切り替え直前を取得すれば、これぐらいの周波数でスキャンできそうです。

    おわり

     なんかgptに部品案聞いて買ってきて試してみると駄目じゃんを各部品で繰り返している気がする、、、
     デモ用の基板起こしたのだけど部品評価しなおしからの作り直しだなあ。

     マルチプレクサがより速いものに変えたいなと思うのでTMUX1308とかを試してみたいと思います。16chのものはCD74HCT4067しかなく、8chでやる方が良いかなと思い始めました
     ホールセンサは消費電力考えなければ5056使いたいんですが5055が安定な感じです。デュアルセンサーとかやりたかったのですが遊びだけな気がします。左手デバイスだえあれば60%とかと比べて制約は少ないですがどうしたものか。こうなるとやはりメカニカルとのハイブリッドがよさそうな気はしてきます。これはこれで人に寄ったり色々面倒がありますが

     いろいろ考えさせられますね、、、磁気スイッチ採用する理由が非接触と流通性だけなのでまだいいですが、ふつうに60%とかの磁気キーボード開発しようとするとできる出来ない以前に諸々が馬鹿馬鹿しくて萎えそうです。

  • はんだリール台スタンド作った

     はんだって何使ってますか?
     私はhakkoの0.6mmを使用しています。150gといっぱい量があるから購入頻度少なく済むというどうでもいい理由です。自作キーボードキットのはんだづけとかだと0.8の方が使いやすいと思うのですけどsmd部品の実装どか考えると太すぎるので0.6という感じです。
     メーカーによって溶かした時の臭いとか違いますよね。

     最近使い切って新しいのを買ったのですが、重くて引き出しづらい、、、のではんだスタンドを作りました。
     そもそも私はあってもなくても変わらないからはんだリール台要らないだろ派だったのですけど、残量が減っていて引き出しやすいからだったというわけです。
     なるほど重いから台が必要、市販の台ってごつくて500gとかの載せる用ですもんね。逆にこの150gのに使うと場所取るだけで無駄であります。

     ただ台が欲しくなっただけなのでfusionでテキトウに作ります。
     場所は取りたくないのでコンパクトに。
     そんな重い量ではないので、浮かせる必要はありません。むしろ浮かせない方がスムーズかな?箱の中でただ回る感じです。
     引き出し穴は下からの方が使いやすいと思っています。

     これだけでもいいのですが、はんだの巻取り動作がだるく思っています。棒をぶっ刺してぐりぐり回せるようにしました。縮めて突っ込んで蓋をして広げればいいかなと思います。

     A1miniで印刷

     滑り止め張って完成
     スムーズに引き出せ、スムーズに巻き取れていい感じです。

     完成度とか全く考えてない拙速ですがファイル投げておきます。


  • [自キ]磁気キーボードを作りたい。3週目

     進捗ダイジェスト3週目

    温度特性

     zenaimさんとかはサーミスタ積んで温度補償していますとウリにしていますよね。他のキーボードでは都度キャリブレーションを行うからokのような感じもあります。
     とにかく温度特性の取得と補償するかどうかは考えなくてはなりません。雑に想像するに常温~高くても40度はいかないだろうと想像しますがどうなんでしょ。

     冷凍庫に放り込んだりヒーターを当てたりしながら、ホールセンサ及びスイッチのADC読み取り値時間変化を見てみたりしたのですが、、変わったり変わらなかったりなんもわからんとなったのでそのうちリベンジしたいと思います。

     とはいえ恒温槽なんてないし、そもそもどこの温度を見るのか?ホールセンサならまだしもスイッチの中にある磁石に熱電対を当てることはできません。熱電対持ってないし。
     何ともめんどくさそうな気がしているうえに最悪無視してもいいんじゃねという気がしています。
     たとえばcal時のtop値と温度を保存しておいて、毎度top値に対してオフセットなりするだけでも良かったりしないかとか。

     宿題です

    ホールセンサ出力-押下量特性の取得

     マイクロメータヘッドを買いました。使用用途が数式立てるためだけで、これしか使わないのでもったいないのですが必要だったので仕方なし。ところで磁力を測るのに使用するのはマイクロメータヘッドでよいんでしょうか。
     買ったはいいもののマイクロメータ以外が何もないので急ごしらえな感じでいったん雑測定します。手元の範囲でもうちょい道具揃ったら再測定します。

     最押し込みから0.05mm step, 7000点程度ADC値を取得し、平均とばらつきを見ています。ちまちま手動でマイクロメータを回し測っていきます。
     底と天井のところは測定系とか色々適当なので裾引いていると思っていて、基本的には正規分布に沿っているとみてよいかなと思います。そうでなければ困る
     平均を読み取り値として採用し、rangeがばらつき幅、6*stdが上下端切り落としたばらつき幅としました。外れ値らしい外れ値はないですが

     L45測定値の平均値らを取り出し、底からの変位量でプロットしてみました。
     averageを見ると距離に対して反比例のようなグラフをしています。底付近の方が磁力の減衰が少ないので高感度に傾きをとれています。
     rangeとstdはおよそ一定で変化しています。距離、磁力に寄らずばらつきは一定とみてよさそうです。またこの測定環境においては、ADC読み取り値のばらつき幅は平均で36程度あり、電圧にして36/4095*3.3=0.03V程度幅を持っています。この幅分以下の値はふらふらばらつくので設定できないということですね。ぱっと思いつくのはホールセンサ出力にフィルタ入れたり、安定度の高いマイコンボードを使い対策とかでしょうか?

     左軸青はADC読み取り値、右軸燈は0.05mmの変位量でADC読み取り値がどれだけ変化するか(感度)を表しています。ADC値/stepに変換しています
     底からの変位0付近では0.05mmを変位させるとADC読み取り値は35程度変化します。閾値0.05mmを実現しようとしたとき、ばらつきが前後35以内に収まっていれば誤動作が起きなさそうでしょうか。
     底からの変位2mm付近の中央では10程度の感度です。
     天井付近では感度が3程度です。0.05mmを実現するためにはばらつきを3に抑えたいです。この時ばらつき36ですから無理ですね。

     平均ばらつき度36であることから、ADC感度→どれだけ変位距離がぶれるのかをプロットしました。これから、底付近と天付近ではばらつきのインパクトが異なり底の方がばらつきによる必要なマージンは小さいです。
     例えば底から2mmの位置で固定しているにもかかわらず、読み取り値が上下に0.1mm分ふらふらとばらつくことを示しています。そのためラピトリ値はこれより大きくしないと動かしていないのにon, offが勝手に入力されてしまいます。

     このpicoでただ読み取るだけの環境では最悪値である上下0.35のマージンを入れた精度であればラピトリを実装できそうです。それくらいでも実用には問題ない気もします。現在ホールセンサにdrv5053を使用していますが、これをdrv5056にするだけで分解能分で倍はよくなりますから、加えてばらつきを抑えてやれば0.1の精度は特別なことをしなくても実現できそうな気がしてきました。

    モデル式検討

     モデル化というと仰々しいですが、2次の関数と連立方程式だけなので大したことなさそう。磁力⇔変位変換は非常に簡単な話であります。

     先ほどのL45と同様に0.05mmずつボトムアウトから刻みホールセンサ出力を測定、をKOM, ZEN, JadeGamingの4種のスイッチについて行いまいした。この結果からスイッチのオンオフ判定やキャリブレーションに使用するためのモデル式を検討します。
     余談ですが、ZENAIMのスイッチは極性がKS-20と同じN極下なので、プレートにちょっと細工すれば同様に使用できます。ただ磁力がKS20互換らより強いので、モノによってはホールセンサの検知範囲から外れてしまうかもしれません。私はZENスイッチにも対応できるように作りたいと思っています。

     まずはどのような式にするのか決定する必要があります。ホールセンサはデータシートを見るとわかるように、磁束密度Bの変化に対してリニアに電圧値に変換され出力されます。
     またこの比例定数は各ホールセンサの感度がデータシートに乗っていますからそれを参照します。drv5053caであれば[+23mV/mT]と記載があります。スイッチのスペックには基本的にガウス[Gs]で表記されていますが1mT=10Gsなので[+230mV/Gs]です。

    $$ B\mbox(磁力) \propto Vout\mbox(ホールセンサ出力) $$

     磁気スイッチのスペックなど見るとわかりますが磁束密度がそのままある位置における磁力の強さとして扱われているので、磁力と呼んでしまいます。
     この磁力をホールセンサで電圧に変換し、それをマイコンのADCによって読み取った値を処理します。現在picoを使用してますが、ADCでは読み取った電圧を0~3.3Vの範囲を0~4095の12bitに変換し読み取りを行います。例えばADCで2000という値を読み取った場合ホールセンサの出力電圧は以下になります。

    $$ Vout[V] = \frac{2000}{4095} * 3.3[V] = 1.6[V] $$

     ですから当然ADC読み取り値も磁力に比例しています。

    $$ B\mbox(磁力) \propto ADC $$

     マイコンで読み取る値と磁力の関係がわかりましたので、スイッチの変位との関係も見てみます。
     磁力と距離の関係を調べてみると、どうやら磁力は距離の二乗に反比例するようです。ホールセンサは磁力に対してリニアですが、肝心の距離特性はそうでないようです。めんどくさい、、
     磁極のローレンツ力の式というのがあり下記のように表されるようです。磁極からの距離rの二乗に反比例しています。またベクトル量ですから傾くと磁力が変化するようです。スイッチを傾かせずに押し下げ、その直線状にホールセンサが水平に置かれることが理想というわけですね。

    $$ B=\frac{\mu q_m}{4 \pi r^3}\overrightarrow{r} $$

     スイッチの距離を磁力として取り出したいだけなので電磁気学なんて知ったこっちゃないです。とにかく下記のように表せるようです。

    $$ B\mbox(磁力) \propto \frac{1}{r(磁極からの距離)^2} $$

     でも実際としては双極子としての数式を見るべきらしいですがたぶん使用する範囲では2乗で十分だと思います。

     ここで私がキャリブレーション時に使用できる距離という値は、スイッチのストロークだけとなります。磁極からの距離を想定したときに、基板の厚み、基板からスイッチ底までの距離、スイッチ底から磁石までの距離とよくわかりません。

     とりあえず今回測定したように、スイッチ底打ちからの変位量を d [mm] としましょう。ストローク4mmのスイッチとすると、dは0~4の値を取ることになります。0の時ボトムアウトで、4の時トップアウトの状態になります。
     また、モデル式に必要な磁極からの距離rというものを仮定して、そのための補正値を d0 [mm] と置きましょう。磁極からの距離を以下とします。

    $$ \mbox{(磁極距離)} r = \mbox{(変位量)} d + \mbox{(補正値)}d_0 $$

     実際に計算に使用したいのはADC読み取り値と変位量dですから、上の式にそれぞれ代入してみます。

    $$ (B \propto ) ADC \propto \frac{1}{( d + d_0 )^2} ( =\frac{1}{r^2}) $$

     多項式となると面倒ですが、この式を使えればとても簡単です。きっとそうに違いない。
     比例定数a, 切片bとして、以下の式をモデルとして想定してみます。シンプルな一次式です。

    $$ y=ax+b, (y=ADC, x=\frac{1}{( d + d_0 )^2} ) $$

     また定数a, bについて考えると、傾きが大きいほど磁力が強くなるということですからaは磁石の磁力の強さを表していそうです。
     bはx=0つまり磁極距離が無限大、スイッチが装着されていない何も検知していない状態ですから磁力0をホールセンサで読み取った値となりそうです。

    実測から近似式

     実際に実測値から近似式を作成し、モデル化を試みます。d0という便利な謎の補正値が吸収してくれるので、この時の変位量(0.005, 0.01, …)刻み幅がちゃんとしてればなんでもよいです。
     今回初めて知りましたがエクセルは線形近似式をセルに打ち出せるのですね。[SLOPE()][INTERCEPT()]という関数を使用しa, bが求まります。
     最小二乗法で線形近似式に実測をフィッティングしd0の値を得ます。グラフを見ると、いい感じにモデルに合っていそうです。

    $$ y=a\frac{1}{( d + d_0 )^2}+b=\frac{10847}{( d + 2.88 )^2}+1221 $$

     L45同様にKOM, ZEN, JGにも実施し近似式を求めました。近似式を求め使用することで、それぞれ異なるストロークと謎の磁極距離という問題が解消されます。任意のr=d+d0を代入すればよいですからね。

     KS-20互換と呼ばれるスイッチは互換とはいうもののストロークも磁極距離も磁力もそれぞれ違うんだよなあと思いますが、こう見ると比較的似たような位置にいますね。ZENAIMスイッチは2倍ほど磁石自体の磁力強いことがわかります。これは実測だけでは磁極距離が含まれていないため正確にはわからないところです。ざっくりはわかりますけども。

     余談ですがそれがユーザーにとり最適化はわかりませんが、ZENスイッチは非常に都合が良く素晴らしいと思います。磁力が強くSNが高い、ショートストロークで感度の高い場所のみを使える、種類がないため単純なキャリブレーションでよい。実のところZENスイッチであれば二乗に反比例などといわず、細かい変位におけるズレを妥協し線形近似してしまっても使う分には困らないし気づかないと思うのですよ。
     以下はZENスイッチのADC / d特性ですが、距離二乗反比例だとしても、ほぼほぼ真っすぐじゃないですか?リニアですと言っても困らないと思う。

     予定ですが、ロングストロークによる感度の悪化をデュアルセンサー化して解決しようかなと空想の中では思っていたりします。市販されている中ではまだないので他人から見て少し面白いかなと思ったり。

    近似式からモデル式

     得られた近似式では各スイッチについてのプロファイルにしかなりませんのでどのスイッチでもキャリブレーションできるように仮定したモデル式に一般化しましょう。

     近似式の結果を踏まえてモデル式を少し整えます。切片bは4つのスイッチで似たような数値を取り、これはおよそ磁力0の時のADC値1V/3.3V*4095=1240に近い値を取っています。ほぼほぼそうだろうということでこれをbとします。また切片のあるグラフでは見づらいので左辺に移項しておきます。またb→y0と呼び名を変更します。

    $$ Y=y-y_0=\frac{a}{( d + d_0 )^2}=aX $$

     変数定数について整理しておきます。

    d底からのスイッチストローク量[mm]
    d0磁極距離rの補正値[mm]
    rd+d0磁極距離(理論式の磁石-ホールセンサ距離)[mm]
    X(1/r)^2モデル式の横軸[mm^-2]
    yADC0~4095のADC読み取り値
    y0磁力0の時のADC読み取り値
    Yy-y0モデル式の縦軸ADC
    aモデル式の傾き、磁力の強さ

     キャリブレーションを実施することでモデル式から定数を決定し、y⇔dの相互変換を可能にする必要があります。

    • スイッチを押したり離したりすることでボトムアウトおよびトップアウトでのADC値、y1, y2を得ることができます。

    $$ y1=ADC_{bottom} $$

    $$ y2=ADC_{top} $$

    • スイッチのストロークを入力することでボトムアウトおよびトップアウトでの変位量、d1, d2を得ることができます。d1は底ですから0mm, d2はトップなのでストローク値になります。

    $$ d1=0 $$

    $$ d2=Stroke $$

     これを代入し連立方程式を立てます。

    \[ \begin{cases} y_1-y_0=\frac{a}{( d1 + d_0 )^2}=\frac{a}{( d_0 )^2}・・・① \\ y_2-y_0=\frac{a}{( d2 + d_0 )^2}・・・② \end{cases} \]

     ②/①よりd0が求まります

    $$ \frac{y_2-y_0}{y_1-y_0}= (\frac{d_0}{d_2+d_0})^2= (\frac{1}{d_2/d_0+1})^2 $$

    $$ d_0=\frac{d_2}{\sqrt{(y_1-y_0)/(y_2-y_0)}-1} $$

     ①-②よりaが求まります。

    $$ y_1-y_2=a((\frac{1}{d_0})^2-(\frac{1}{d_2-d_0})^2) $$

    $$ a=\frac{y_1-y_2}{((\frac{1}{d_0})^2-(\frac{1}{d_2-d_0})^2)} $$

     よってキャリブレーションを実施し、y1, y2, d2を入力することでモデル式を使用できるようになります。

     実際にラピトリ制御する際は、単純に考えるとまずADC値を読み取り初期位置を算出、そこからラピトリ設定値をoff状態なら-、on状態なら+し、そこからトリガーとなるADC値を算出する感じでしょうか。
     初期値をD, Y、ラピトリ設定距離をRとします。

    $$ d(初期値)=D $$

    $$ y(初期値)=Y $$

    $$ R(ラピトリ設定値) $$

     ADC初期値を入力し初期位置を取り出します

    $$ Y-y_0=\frac{a}{(D-d_0)^2} $$

    $$ D=\sqrt{\frac{a}{Y-y_0}}-d_0 $$

     次のトリガーとなる判定位置をD’とすると

    $$ D’=D±R $$

     d=D’が次のトリガーとなるADC読み取り値となる。

    $$ Y=\frac{a}{(D’-d_0)^2}+y_0=\frac{a}{(D±R-d_0)^2}+y_0 $$

    宿題

     とりあえず磁力⇔ストローク量変換ができるようになったと思う。あとは部材とどいたら実測詰めていい感じにしていきたい。
     温特をどうにかする。
     ADC値のばらつき問題。フィルター入れたりマイコン変えたりしてみる。
     したっけ実装に入っていく。


  • [自キ]磁気キーボードを作りたい。2週目

     進捗ダイジェスト2週目

    磁力と距離

     picoにつないだだけの同じもので距離特性をざっくり測ってみます。
     前回は感度45V/Tのdrv5053eaを使用しましたが、今回は感度が半分の23V/Tのcaホールセンサを使用します。なおこれも範囲をカバーできていないのでもっと感度低いものが必要です。
     通常基板からプレートトップの距離が5mmなので、1.6mm基板+3.5mmスペーサのところですが、磁力範囲をカバーするため4mmスペーサを使用しています。

     距離を測る機器がないため、スイッチを押していないニュートラルな状態と押し込んだ、ニュートラルな状態から-4mmの状態での平均ADC読み取り値を記録します。
     またスイッチ下に1.6mm基板をスペーサとして敷いていき、4回繰り返しました。4mmスペーサで押し込んだ状態を0としています。

     この0mmの状態で、およそホールセンサから距離が2mm開いているのでオフセット値を加えグラフにしてみます。雑計測なのであまりなめらかでないですね。

     ググってみると磁力は距離の二乗に反比例するそうです。ぱっと見反比例のグラフなのでそんな感じがします。ホールセンサは磁力に対してリニアに電圧が変化し出力されますが、肝心の磁力が距離に対してリニアではないのですね。
     押していない付近と押し込んだ付近とで感度が違います。同じ1.6mmの移動でも、2 – 3.6mmの移動量でADCは350変動していますが、3.2 – 4.8mmでは95しか変動しません。
     SOCD機能がある以上、fpsでの挙動においてニュートラルから押し込む動作の精度が重要に思いますが、磁力の強い押し込んだ付近の方が高精度にとれるのですね。

     磁力は距離の二乗に反比例するということなのでどうなのか見てみます。

     それっぽさがあります。そもそもここで採用している距離というのがデタラメ(センサと磁石の距離こんな感じだよね)なので、補正値を二乗平均平方根誤差最小になるやつで求めてみます。

     それっぽい感じがします。この近似式にホールセンサ読み取り値を入れれば押し込み量が求めて、press releaseの判定を処理できそうです。
     何も考えていないので、もう少し正確に計測出来るようになったらモデルを検討したいですが、なんとなく押下量min, maxでの磁力を測定し、スイッチのストロークを入力すれば各スイッチに対応したキャリブレーションができそうな感じがしています。どうなんでしょう。その場合精度は筐体やスイッチの工作精度や軸ブレ量次第にはなりそうです。

     またこの近似式から各距離での検出磁力もホールセンサの感度を入れることで推定できますね。L45はスペックが良くわからないので何も答え合わせできませんですけど

    picoのスキャン速度

     とりあえずpicoで1000回ADC読んでその時間と平均値を出してみました。picoのクロックを設定できるようなのでいくつか試してみました。

    const int numSamples = 1000;
    long sumA0 = 0;
    int sampleCount = 0;
    
    void setup() {
      Serial.begin(2000000);  // 高速シリアル通信
      analogReadResolution(12);  // 12ビットADC
    }
    
    void loop() {
      // 1回A0を読む
      int value = analogRead(A0);
      sumA0 += value;
      sampleCount++;
    
      // 1000回読み取ったら出力
      if (sampleCount >= numSamples) {
        int averageA0 = sumA0 / numSamples;
    
        Serial.print("time,");
        Serial.print(micros());
        Serial.print(",A0,");
        Serial.println(averageA0);
    
        // リセットして次の1000サンプルへ
        sumA0 = 0;
        sampleCount = 0;
      }
    }
    

     クロック250MHzに設定した1ms間に250回ほど読み取れるようです。単純に50キーのキーがついてるとして1msに50回です。物足りなさは感じます。

     A0ピンだけでなくA1ピンも加えて、2つのピンから読み取るようにして同じように計算してみました。

     A0とA1の分があるので読み取っているキー数はこれの2倍となります。A0のみから読み取るのよりも遅くなってしまっていますね。

     picoのデータシートp.557にADCのサンプルレートは500kHzで1基搭載し4つのADC入力とマルチプレクサで接続されていることが書かれています。

     ADCは1基しか搭載していないので2ピン読み取らせるとむしろMUXの切り替え時間とかで遅くなってしまっている感じでしょうか。もし仮に1ピンあたり500kHz出たとしても50キーあると10kHzですからpicoではADCの搭載数、サンプルレートともに磁気キーボードを作るうえでは足らないのかなと思ったり。プロトタイプなら全然よさそうですが

    マルチプレクサ

     16チャネルのマルチプレクサ CD74HC4067SM96 の動作を確認します。
     市販の磁気キーボードには大抵MUXが乗っておりADCピン数を拡張しています。マイコンにADCピンが60個とかついてないですものね。CD74HC4067SM96は一つで16個のADCピンを拡張できます。

     S0~S3でP0~P15のどのピンから読み取るか指定し、dataピンからマイコンに指定したピンのADC出力が読み取れる感じの部品です。今回は抵抗で分圧して電圧値読み取れるか試してみました。

    // セレクトピンの定義
    const int S0 = 0;
    const int S1 = 1;
    const int S2 = 2;
    const int S3 = 3;
    
    // ADCピン
    const int adcPin = A0; // GP26 = ADC0
    
    // 読み取るチャンネル(P0〜P3)
    const int channels[] = {0, 1, 2, 3};
    const int numChannels = sizeof(channels) / sizeof(channels[0]);
    //int型は4バイトchannnel配列は4要素計16バイト、channnell0は1要素4バイト、16/4=4要素らしい
    
    void setup() {
      Serial.begin(200000);
    
      // セレクトピンを出力として設定
      pinMode(S0, OUTPUT);
      pinMode(S1, OUTPUT);
      pinMode(S2, OUTPUT);
      pinMode(S3, OUTPUT);
    
      // ADCピンの初期化(Arduino環境では特に不要なこともあります)
      analogReadResolution(12); // Picoでは12bit ADC(0〜4095)
    }
    
    void loop() {
      for (int i = 0; i < numChannels; i++) {
        setMuxChannel(channels[i]);          // MUXのチャンネルを設定
        delay(10);                            // セットアップ時間待ち
        int adcValue = analogRead(adcPin);   // ADCから読み取る
        Serial.print("P");
        Serial.print(channels[i]);
        Serial.print(", ");
        Serial.println(adcValue);
        delay(500); // 待機
      }
    }
    
    // マルチプレクサのチャンネルを選択する関数
    void setMuxChannel(int channel) {
      digitalWrite(S0, bitRead(channel, 0));
      digitalWrite(S1, bitRead(channel, 1));
      digitalWrite(S2, bitRead(channel, 2));
      digitalWrite(S3, bitRead(channel, 3));
    }
    //bitreadでchannnelという引数に渡された値の、何ビット目の値を出すらしい

     問題無く読みとれていそうです。使う分には sピンで指定→読み取り だけで難しいことはなさそうです。またenableピンもついているので、mux個数分のioピンを用意すればこんかいのpicoのようにADCが1基のみの搭載でも同じADCピンに複数のMUXを接続することができるようです。

     速度とか切り替えとかノイズとかも次にpicoやオシロで確認したいです。

    部品調達

     何も知らない何も考えてないで始めているので、どれも性能が足りていないことがわかりました。
     使える部品を買い足したいところです。

     まずスイッチがL45が数個あるだけ状態なので、定番品を入手しておきたいところです。磁気キーボード関連何も知らないので何買えばいいのかもわからない、、
     少し調べてみると、ストロークだけでなく磁力も公開されているものが多いのですね。例komとjadepro

     gateronなどはデータシート自体公開しているようでしたが、あまり欲しい情報は得られませんでした。基本的にはストロークと1.2mm pcbでのtop, bottomでの磁力だけのようです。
     本当に何も知らないのでks-20互換というのは本当に互換なのだと思っていましたが、磁力、磁石との距離、ストローク、どれもまちまちなのですね。まあ互換といっているのも名目上はユーザーなのでしょうけど。ks20互換が意味するのは極性とMXタイプであることぐらいなのですね。

     磁気スイッチの種類というのもめちゃくちゃ多いそうで、わけわからん状態なのですが1年後も使用され続けていそうなものを何種類か見繕いたいところです。

     drv5053caの23mV/mTより感度の低いホールセンサを調達したい。また5053は出力が0-2v固定なのでもっと広く見れるものが良いかなと思いました。その分細かく見れますものね。↑のように磁気スイッチは1.2mmpcbとして700Gs=70mTは最低でも見れなくてはならないですね。適当に調べてみた感じ候補はこんな感じでしょうか。基本的にはよく見る3端子のもので、スリープ機能付きのものは6端子です。

     drv5053caは350Gsまでしか見れないのですが、今回L45を0.4mm程度浮かせると振り切ることなく計測できていました。L45のスペックがどんなものかはわからないですが、距離^-2というのは感度が極端に変わりすぎてめんどくさいなあと思います、
     5053他は与えた電源と同じレンジで出力が見れるものと思います。また5056は片方の極性しか見ないため、倍細かく見れそうです。
     スリープ機能付きのものは、ioピンこそたくさん必要ですが、MUXなしでオンオフ制御できそうです。どちらがいいのかは何んともわかりませんが、売っているので検討はしたいなと思います。計測範囲ちょっと狭いのですけどね。その話で行くともっといろいろホールセンサもラインナップはあるはずで、個人だとまず部品の選択肢から狭いのはきついなと感じます。

     マイコンボードももっと高性能なものを使用したいところです。実際に使うにあたりどの程度のADC基数、sps、クロックが必要なのかは見ておく必要があります。ai君に調べてもらうとstm32がよさそうです。

     市販品は8k当然な感じですがnucleoボードはUSB2.0対応のものはないそうです。でもteensy4とか高いのでnucleoボードでいったん試してみようかという感じ。そもそも8kHz必要なのかという話でもあります。

     正確に押下量も取りたいのでマイクロメータもあったほうがよさそうです。mitutoyoのmhn2-25mxとかこういう感じでしょうか。どこまで正確にできるのやらとは思いますがたかがスイッチを押すだけに仰々しい設備導入とかとも思うのでこれくらいがちょうどよいとは思うけれどどうしたもんか

     なんもわからなくても何もしないでもai君がarduinoコード出してくれるので楽なものですね。
     もうちょいい環境整えて、具体的な話をしていきたい。