TMC2209を一晩、UARTだけで鳴らして測った ── ドライバICは実際どんな奴か

6軸ステッピング制御基板がJLCから届くまでの予習に、TMC2209ブレークアウトを1軸だけ触った記録。UART一本でモータを回し、内蔵クロックを音叉で実測し、StallGuardの共振帯を見つけ、2台の独立クロックのズレを耳で捉え、最後は2台で演奏まで。データシートの数字が実機でどう見えるか、うまくいったことと「効かせられなかった」ことを、グラフ付きで正直に。


AIエージェントに基板設計をやらせる話は前に書いた。その流れで、6軸のステッピングモータ制御基板(ドライバは TMC5240)を設計して、JLCPCBの発注ボタンまで運んだ。基板が届くのは数週間先だ。

その待ち時間に、TMC5240の血の繋がった弟分にあたる TMC2209 のブレークアウトを1軸ぶんだけ買って、実機で触ってみた。予習だ。データシートに書いてある数字が、実物に触れるとどう見えるのかを、指で確かめておきたかった。

結果として、一晩でずいぶん遠くまで行ってしまった。UART一本でモータを回すところから始めて、内蔵クロックを音叉で実測し、共振帯を見つけ、2台の独立したクロックのズレを耳で捉え、最後は2台のモータで和音を鳴らして演奏までした。この記事は、その観測ノートを起こしたものだ。

実験に使ったデルタ型3Dプリンタの1軸と、背後の計測器棚。アナログメータ、ファンクションジェネレータ、拡大鏡ランプ、ヘッドフォン

これが現場だ。デルタ機のフレームにドライバとモータを繋いで、Picoから喋りかける。可動域が限られているので、連続回転はできず、短い往復と自己中心復帰でやりくりしている。

先に但し書きを一つ。ここで測った数字の一部は、私が繋いだ特定のモータ(デルタ型3Dプリンタの1軸)に依存する。共振帯の位置、正逆の非対称、クロックの個体値——これらは「TMC2209というICの普遍的性質」ではなく「このIC+このモータ+この電源」の組み合わせが見せた顔だ。どこがICの性質でどこが個体差か、できるだけ切り分けて書くけれど、鵜呑みにはしないでほしい。実機の真実は、いつも「あなたの手元の組み合わせ」で測り直すものだから。

配線 ── UART一本で回す

TMC2209はSTEP/DIRパルスを撒かなくても、UARTでレジスタに速度を書き込むだけで回せる(VACTUALというレジスタに値を入れると、その速度で回り続ける)。今回はこのUART専用駆動でいく。

厄介なのはTMC2209のUARTが単線(PDN_UART 1本で送受兼用)なこと。マイコン(Raspberry Pi Pico 2)の2線UARTと繋ぐには、TXに1kΩを直列に入れて、RXは同じ点に直結する——送信が自分のRXにも回り込む(エコーする)ので、応答はエコー4バイトの後ろの8バイトを見る。

そして最初に踏んだ罠がこれ:

TMC2209のデジタルコアは、モータ電源(VM)から作られている。

「安全のためモータ電源だけ切って、まずUART通信だけ確認しよう」——これが通らない。ロジック電源(3.3V)が生きていても、VMが無いとICは一言も喋らない(自分のエコーだけ返ってくる)。内部レギュレータがVMから内部電源を作る設計だからだ。

症状は「エコーは見えるのに応答8バイトが返ってこない」。この晩、私はこの罠を3回踏んだ(2軸目を足すたび、電源の配線が甘くて)。だから覚え書きとして大きく書いておく——喋らない時は、まずVMを疑え

発見その1 ── StallGuardは速度に対して単調じゃない(共振帯がある)

TMC2209はコイルの逆起電力から負荷を推定する StallGuard という機能を持っていて、SG_RESULT(0〜510、大きいほど軽負荷)というレジスタで読める。これがセンサレス原点出しの心臓部だ——端に当たって負荷が上がればSGが落ちるので、それを検出すれば原点が取れる。

で、速度を変えながらSGを測ってみたら、こうなった。

StallGuardのSG_RESULTを速度(VACTUAL)に対してプロットしたグラフ。低速端と高速端ではSGが高く安定しているが、中速(8000〜18000)ではSGが0から470まで激しくばらつく共振帯がある

SGは速度に対して単調じゃない。低速端(2k〜6k)と高速端(22k〜30k)では安定して高いのに、中速(8k〜18k)で0から470まで激しく暴れる。これはモータの機械共振と、StealthChop(後述の静音モード)のざらつきが重なった共振帯だ。

これは実用上とても大事で、最初 VACTUAL=16000 あたりで「SGが綺麗だ」と早合点したのが間違いだった。16000はまさに共振帯のど真ん中で、たまたま帯の縁の安定窓を引いただけ。正しくは「両端が綺麗、中央の共振帯を避ける」。センサレス原点出しは、低速端(〜5000)か高速端(〜26000)で端に当てるべきだ——自分の早合点を、スイープ1枚が正してくれた。

実際にやると、こう動く。まず−方向を探して6秒回っても当たらず(この向きは217mmぶん開いていた)、+方向に当て直すとSGが急落した瞬間に原点を確定して止まり、そこから可動域の中へ前進する。配線の極性を知らなくても、両方向を試せば原点が出せる:

発見その2 ── 内蔵クロックを音叉で測る、そして2台のズレを聴く

VACTUAL から実際のステップ周波数への変換は、内蔵発振器の周波数 fCLK(公称12MHz)で決まる:

ステップ周波数[Hz] = VACTUAL × fCLK / 2²⁴

面白いのは、ステッピングモータはステップ周波数でそのまま鳴くこと。コイル電流の切替音が、そのまま音の高さになる。ということは——モータを発振器に、マイクを周波数計にすれば、内蔵クロックを外から実測できる。

やってみた。狙いの音(440/660/880Hz相当のVACTUAL)を鳴らして、C920のマイクで録って、FFTでピークを読む:

VACTUAL期待 [Hz]実測 [Hz]fCLK [MHz]
615439.88445.0812.142
923660.18666.4112.113
1230879.76889.3112.130

fCLK ≒ 12.13 MHz(公称より約+1%)。 この個体の発振器は公称より1%ちょっと速い。

ただ、この「+1%」を主張していいのか? 上の3点は同じ録音の中の3音であって、独立した再現ではない。マイクとFFTがそんな精度を持っているのか、ただの測定誤差ではないのか——当然の疑問だ。なので確かめた。同じ音を10回、独立に鳴らして測り直したら、標準偏差はわずか 0.001%(444.46Hzに対して0.03Hz)。測定そのものは、必要な精度の千倍くらい安定していた。マイク+FFTは、この用途には過剰なほど精密だ。だから+1%は測定誤差ではなく、実在するオフセットだと言える。TMC2209の内蔵クロックは水晶ではなく内蔵RC発振器なので、数%のばらつきはむしろ設計上の想定内だ。

ここで大事な教訓。内部には TSTEP × VACTUAL = 一定 のような綺麗な恒等式もあって、それは確かに成り立つ(内部のステップ生成器は完全に線形だった)。でもそれは内部の量どうしの関係だから、発振器そのものの狂いは絶対に見えない。外の基準(ここではマイク)を一つ持ち込んで初めて、クロックの絶対値が測れる。ブラックボックスを開けるには、中の整合性だけ見ていてはダメで、外から一本、独立した物差しを当てる必要がある。

2台のクロックは違う ── だから「同じ指令」でもうなる

夜が進んで、2軸目のドライバを足した。同じ音叉実験を2台でやると、こうなった:

  • axis0 = 12.138 MHz(+1.15%)
  • axis1 = 12.183 MHz(+1.52%)
  • 差 0.37%

2台のTMC2209は、それぞれ自前の内蔵発振器で回っている。だから両方にまったく同じVACTUALを命じても、実際の周波数がわずかに違って——445Hzで約1.6Hzのうなりが生まれる。同じ音を命じたのに、二つの声が微妙にずれて、ゆっくり干渉する。

この差も「測定誤差では?」と疑うべきだ。だから、さっきと同じ再現性の枠組みで確かめた。axis0とaxis1を交互に、同じ指令で何度も測り直す。結果がこれ:

axis0の測定10回とaxis1の測定4回を実測周波数の数直線上にプロットした図。axis0は444.46Hzに標準偏差0.03Hzで密集し、axis1は446.08Hzに密集する。両者の差1.61Hz(0.363%)は測定ばらつきの75倍で、繰り返し測っても分離したまま

axis0の測定は444.46Hzにぴたりと固まり、axis1は446.08Hzに固まる。差は0.362% ± 0.005%——測定ばらつきの75倍。何度測り直しても、二つの帯は決して重ならない。だからこの差は本物だ。

さらに突き詰めて、各軸を15回ずつ測って分布そのものを描いてみた。各軸の測定は、幅わずか σ≈0.008Hz のガウスに収まる——445Hzに対して 0.002% の細さだ。二つの山の中心は 1.43Hz(0.32%)離れていて、これは σ の177倍にあたる。統計でいう Cohen’s d が177というのは、「二つの分布が完全に分離」の基準(d>2)を、はるか彼方まで振り切っているということ。同じ指令を打っているのに、二つのクロックは重なりようがないほど別の場所に立っている。

axis0とaxis1をそれぞれ15回測った実測周波数のヒストグラムとガウスフィット。axis0はμ=444.21Hzで幅σ=0.009Hz、axis1はμ=445.64Hzで幅σ=0.006Hz。幅の狭い2つの山が1.43Hz(177σ相当)離れて完全に分離している

(最初は「片方をデチューンしてうなりの速さがδに比例する」実験もやったのだけど、そちらは可動域を守る0.5秒ごとの反転が2/4/6/8Hzの倍音を撒いて、うなりの遅い領域を汚染した——短いトラベルの軸で長周期のうなりを測るのは無理筋で、フィットを描くのは無茶だった。だからその図は引っ込めて、上の「繰り返し測る」ほうを証拠として採る。派手なグラフより、地味な反復のほうが正直だ。)

ひとつ面白い副産物。絶対値のほう(12.13MHz)は測定セッションごとに0.1%くらい揺れる。じゃあ2台のは完全に一定かというと、そこまでは言えない——正直に測り直すと、セッションによって 0.32%〜0.37% くらいの幅で動いた(だから上のガウスの0.32%と、その前の反復測定の0.36%は、別のセッションの値だ)。ただ、ここで効くのは「不変」より弱いが実務的にずっと大事な性質だ:差はどのセッションでも測定ノイズ σ の数十〜百倍以上あって、決してゼロに紛れ込まない。同じシリコンで温度係数が近いぶん、二つは一緒にドリフトしやすく、相対測定は絶対測定より素性の差を安定して映す——ただし『不変』ではなく『より安定』だ、と言い直しておく。教科書の「相対測定は強い」は、こういう“程度”の話なんだよ。

そして、これは本番の基板設計に直結する発見でもある。 各ドライバは1〜1.5%ばらつく自前のクロックを持つ。つまり、複数軸の位置を厳密に協調させたい運動では「同じ指令=同じ動き」が成り立たない。だから本番のTMC5240基板には、全軸でCLKを1本共有する選択肢(0Ωのランドを置いて後から繋げるように)を仕込んである。今夜聴いたこの小さなうなりは、その共有クロックがなぜ必要かを、耳で証明してくれた。おもちゃが本番の設計判断を裏取りした瞬間だ。

発見その3 ── StealthChopの電圧天井

TMC2209には静音モードのStealthChopと、剛いSpreadCycleがある。StealthChopは電圧モードで、逆起電力を打ち消すためにチップが内部でPWMの振幅(PWM_SCALE_SUM)を自動調整している。この「要求PWM振幅」を、速度と電流を変えながら覗いてみた:

PWM_SCALE_SUMを速度に対してプロットしたグラフ。IRUN=8、16、24の3本の曲線。どれも速度とともに右上がりで255(PWM飽和)で頭打ちになる。電流が大きいほど早く飽和に達する

綺麗な絵になった。要求PWMは速度にも電流にも比例して上がり、255で飽和する=電圧の天井に当たる。そして電流が大きいほど早く天井に当たる。物理的には、コイルに電流 I を流すのに必要な電圧が I×(抵抗 + 速度×インダクタンス) で効いていて、速度で効くのは巻線の ωL 項だ。だから縦軸は電流にも速度にも比例して伸びる。

これが嬉しいのは、演奏していたときの経験を全部説明するからだ。高速で大音量の曲をStealthChopで鳴らそうとすると電流が保てなくなる——だからSpreadCycle+フルステップに切り替えて音量を稼いでいた、あれは正解だった。そして電源電圧の余裕(18V→24V)が天井を押し上げる=高速が楽になる。この晩、古いCVCC電源がへたって高速域で電流制限に落ちてUARTごと沈黙する事件があったのだけど(後述)、それもこの天井の話と地続きだ。

「たぶんこうだろう」でやっていた運用が、チップの内部レジスタから定量的に裏取りできた。これはブラックボックスを開ける作業として、いちばん気持ちのいい部類だった。

発見その4 ── 止めた後も、2秒は握ったまま

VACTUAL=0 を書いてモータを止めた瞬間から、実電流(CS_ACTUAL)がどう抜けていくかを追った:

停止指令からの時間に対するCS_ACTUALのグラフ。停止後約1.9秒はIRUN=16の走行電流を保ったまま、その後160msごとに1段ずつ階段状にIHOLD=4まで降下する

停止指令の後、約1.9秒は走行電流をそのまま握り続け、それから160msごとに1段ずつ、保持電流まで階段状に降りる(この猶予と降下速度は TPOWERDOWNIHOLDDELAY で決まる)。

一見地味だけど、これは6軸で意味を持つ。全軸を同時に止めると、停止直後こそ電源負荷のピークになり得る——止めたのに全力で握ったままの時間が2秒ある。多軸システムの電源設計では、動いている時だけでなく「止めた直後」も考える必要がある、という実感が得られた。

発見その5 ── 同じ型でも、軸ごとに地理が違う

2軸目を足したので、両軸をまったく同じ条件で速度スイープして、カルテを取り比べた:

axis0とaxis1のSG_RESULTを速度に対して並べた2枚組のグラフ。axis0は広い共振帯を持つのに対し、axis1は狭く深い谷を持つ。正逆の非対称の向きも軸ごとに異なる

同じ型のモータ、同じ基板なのに、共振帯の地理が軸ごとに違う。axis0は8k〜20kの広い帯、axis1は16k〜18kの狭くて深い谷。正逆の非対称の「向き」も個体で違った。さらに、電源電圧を18Vから24Vに替えると、共振帯の谷底が浅くなった(電圧の余裕が電流制御を立て直して共振を鎮める)。

ひとつ正直に断っておくと、この2軸はデルタ機構で機械的に繋がっている。デルタは3本のタワーのキャリッジがエフェクタを介して結合しているので、片方の軸を動かすと、もう片方の姿勢・張力・負荷が変わる。だから「axis0とaxis1の違い」には、純粋なドライバ/モータの個体差だけでなく、測定時に相手の軸がどこにいたかという結合の影響が混ざっている可能性がある。これを綺麗に切り分けるには、片方を固定した状態や、両軸を同じ姿勢に揃えて測り直す実験が要る——それを、実際にやった。次の節がその話だ。ここで言えるのは「軸ごとにカルテが違う」という事実までで、その違いがどこまでIC由来でどこまで機構由来かは、次節の切り分けと併せて読んでほしい。

それを踏まえた上でも、結論は実務的に重い:しきい値は(軸ごと、電源条件ごと)に一枚のカルテで決めるしかない。使い回しは効かない。 本番の6軸ボードでは、起動時に各軸を自動較正するスクリプトを噛ませる価値がはっきりした——これはこの晩の実測がなければ「たぶん大丈夫だろう」で流していた設計判断だ。

発見その6 ── デルタ結合の正体は「隣が自由か固定か」だった

デルタ機構で繋がった2軸。素朴な予想はこうだ——「片方の軸の位置が、もう片方の負荷を変えるはず」。エフェクタを介してリンクしているのだから、隣がどこにいるかで幾何が変わり、こちらの負荷に響く。これを確かめにいった。

方法はシンプルにした。軸0を一定速度で往復させながらStallGuardを測り、その間、軸1を「自由(ドライバ無効)」と「その場で固定(通電)」で切り替える。SGが条件で変われば結合、変わらなければただの個体差——という切り分けだ。ドリフトを相殺するため、free と hold を交互に何度も対で測る。

まず速度を変えて対で測ると、ほとんどの速度では free と hold の差が往復運動のノイズに埋もれて見えなかった。ところが一点だけ、いちばん静かな動作点 VACTUAL=6000 で、はっきりした信号が顔を出した:軸1を固定すると、軸0のSGが再現性よく +130 上がる(負荷が軽くなる)。4回対で測って毎回 +110〜+146、これはノイズじゃない。

左パネル: 軸0の各速度で「SG(hold)−SG(free)」の対差をプロット。6000だけ4対とも+130付近に密集し、9000〜22000は0付近に大きくばらつく。右パネル: V=6000で軸1の保持電流IHOLDをfree/1/4/8/16/31と変えた時の軸0 SG。freeで約264、通電すると一気に約390へ跳ね上がりIHOLD=1で既に飽和、以降フラット。同時に読んだPWM_SCALE_SUMは66→68でほぼ水平

左パネルがそれだ。6000の対差だけが一貫して+130に固まり、他の速度は0をまたいで散らばる(往復の短いデルタ軸ではSGがそれだけ暴れる)。静かな動作点でだけ、結合が信号として立ち上がる。

さて、これは予想どおり「デルタの機械結合」なのか? ここで足を止めた。位置なのか、通電なのか、電源なのか——確かめずに「デルタ結合」と書いたら、この記事の他の場所で自分に課した『まず測定誤差を疑え』を、自分で破ることになる。だから容疑者を三つ、順に潰した(右パネル)。

  1. 位置か? 保持電流を同じにして(=電源への負荷は同じにして)、軸1を左端と右端に振り分けて測った。結果、hold_left ≈ hold_right(どちらも約388、差はほぼゼロ)。軸1の位置は軸0に効いていない。 素朴な予想は、きれいに外れた。
  2. 電源か? 軸1に通電すると電流を食う→共有電源が垂れる→軸0のチョッパがずれる、という電気的経路を疑った。軸0の PWM_SCALE_SUM(StealthChopが要求する電圧の指標)を同時に読むと、free と hold で 66→68、ほぼ不動。電源が垂れているなら、同じ電流を保つのにPWMを上げるはず。上がらない。電源垂れも否定。
  3. では何が効く? 軸1の保持電流を 1→31 と変えて軸0のSGを見た。効果はIHOLD=1(最弱ロック)で既に飽和していて、最大の31まで上げてもほぼ増えない。しかもPWM_SCALEはIHOLD=31でも68のまま——軸1が最大電流を食っても軸0の必要電圧は動かない。

答えが出た。効くのは軸1の位置でも電流量でも電源でもなく、「通電されているか否か」というステップだった。物理はこう読める——ドライバを無効にした軸は、コイルが開放され、ロータが電磁的に自由になる。すると軸0が往復するたび、共有フレーム越しにその自由なロータがつられて揺れ、軸0に余計な負荷(sympathetic な共振)を返す。ほんの少しでも通電すると(IHOLD=1でも)コイルが閉じてロータが磁気的に留まり、その揺れの道が死ぬ。だから位置に依らず、わずかな電流で飽和する。

実用の教訓が一つ増えた:「使っていない軸=無害」ではない。 電源を落とした隣の軸は、その自由なロータで、動いている軸に振動負荷を足しうる。多軸機では、待機中の軸もあえて低電流で通電(ロック)しておくほうが、動作軸が静かになる場合がある——これは6軸ボードの「アイドル時に電流を切るか保つか」というポリシーに、そのまま効く話だ。

(正直な限界も置いておく。この+130がノイズから見えたのは唯一の静穏点6000でだけで、他の速度では往復ノイズに埋もれて分離できていない。だから「結合は+130」という定量値はこの動作点に固有で、共振帯の内側でどう化けるかはまだ測れていない。それでも『位置ではなく通電が効く』という機構の切り分けは、上の三段で確かに取れた。素朴な予想=位置説を、実験がひっくり返してくれた——こういう「予想が外れて、外れ方から本当の機構が見える」瞬間が、実機のいちばん美味しいところだ。)

寄り道 ── ステッピングモータで協和音を測る

モータが音階を鳴らせるなら、2台で音程が作れる。片方を基音に固定して、もう片方を1度→オクターブへ動かし、二つの音の「ざらつき(roughness)」を測ってみた。単純な整数比(協和)なら滑らか、複雑な比(不協和)ならうなりが速くてざらつくはずだ:

音程比に対するroughnessのグラフ。ユニゾンが最も低く、トライトーンが最も高い山になり、完全4度と完全5度が局所的な谷になっている

そのまま協和曲線が出た。ユニゾン(1:1)が最も滑らかで、悪魔の音程トライトーンが最も不協和な山になり、完全4度(4:3)と完全5度(3:2)がちゃんと谷に凹んでいる。「なぜ5度は綺麗に響くのか=周波数比が単純で倍音がぶつからないから」を、2台のステッピングモータで描けた。

協和かどうかは、耳の好みじゃなくて物理だ——うなりの縞が粗いか細かいか、それだけ。さっきの「2台のクロックのズレ」も、この協和/不協和も、根っこは同じ「二つの周波数の干渉」という一つの現象の、別の顔なんだ。(正直に言うと、オクターブだけは録りこぼした。マイクの区間検出が録音ごとに不安定で、高い音が拾いにくかった。9/10の音程での曲線だ。)

音程が作れるなら、旋律も弾ける。2台のモータに、片方を主旋律・片方をベースに割り当てて、二声で演奏した。音源はMIDIから最上声部と低声部を抜き出して、ステッパの音域に折り畳んで、各音の回転方向は可動域を守るようにオフラインで決めてある。ピッチは音叉実験の実測クロックで調律した。フルステップ+SpreadCycleの、あのブザーみたいな音で:

測定器がそのまま楽器になる。これはこの晩、いちばん笑った瞬間だった。実機を触っていると、こういう「本来の用途じゃない遊び」に道が逸れて、その寄り道でむしろICの素性(音=ステップ周波数、静音モードの限界、2台のクロック差)が腑に落ちる。遊びと測定は、案外地続きなんだ。

数字 ── UARTバスはどれくらい速いか

2軸を1本のUARTバスにぶら下げて、通信の実力を測った:

  • 書込(VACTUAL等の指令)=637µs/件、約1570件/秒。8バイト×115200bpsの理論値694µsとほぼ一致。演奏で毎秒1500音イベント飛ばせる根拠はここにある。
  • 読取(query→エコー→応答の往復)=2.3ms/件、約436件/秒。往復とターンアラウンドが効く。
  • マルチドロップは無料:addr0だけ読むのと、addr0/addr1を交互に読むのが同じ2.3ms。1バスに複数台ぶら下げても遅くならない。
  • 6軸相当:6台の状態レジスタを読むと12ms=約83Hzで全軸ポーリング可能。

(ここでも罠を一つ。最初 uart.read() を読むバイト数を指定せずに呼んだら、1件55msという異常な遅さになった。UARTのタイムアウト(50ms)ぶんブロックする実装だったからで、読むバイト数を明示したら2.3msに落ち着いた。MicroPythonのUART定番の落とし穴。)

効かせられなかったこと ── CoolStepと、負荷が無いという壁

正直な失敗も書いておく。CoolStep(負荷に応じて電流を自動で増減する省エネ機能)を実演しようとして、この晩は効かせられなかった。

  • StealthChopのまま:無負荷のSGが約280で、電流を絞るしきい値(416)に届かず、電流は据え置き。
  • SpreadCycleに替える:今度はSGが約0(重負荷と判定)で電流を盛る側だが、すでにIRUN上限で頭打ち。

つまりCoolStepは「SpreadCycle+StallGuardをこのモータ用に較正+実際の負荷変動」の3つが揃わないと働かない。プラグ&プレイじゃない。無負荷でぶん回しているだけのベンチでは、本領が見えないのだ。

これは失敗であると同時に、次への矢印でもある。CoolStepを本当に見るには「既知の負荷をかけて、電流がそれに追従する」のを観測したい。それには軸に負荷をかける仕掛けと、実電流を読むセンサが要る。「見えなかった」という結果が、次に足すべき計器の動機を一つ増やした。

同じ理由で、マイクロステップの「滑らかさ」をStallGuardのばらつきで数値化しようとしたのも失敗した(機械的な滑らかさと、StallGuard推定のノイズが混ざってしまう)。滑らかさは、測るより見る・聴く・加速度計で拾うものだ。

帯域の外に、証人を置く

この晩いちばん教訓的だった事故の話をしておく。速度スイープの最中に、高速域でSGとUARTの読み出しが全滅した。直後の点呼でバス全体が沈黙。原因は、安物のCVCC電源が電流制限でトリップして、VMが落ちていたことだった(TMC2209はデジタルコアまでVM給電だから、電源が沈むと通信ごと死ぬ)。

ここで効いたのが、ずっと回していた録音だ:

速度スイープ中の音響スペクトログラム。中高速で倍音の梯子が上昇し、レジスタが沈黙した後もしばらく音は鳴り続け、約41秒で完全に沈黙する

スペクトログラムを読むと、レジスタが何も答えられなくなった瞬間も、しばらく音は鳴り続けていた。一番面白い事故の瞬間に、測定系(UART)自身が被測定系と電源を共有していて沈黙する——そのとき、マイクという帯域外の証人が事故の時系列を復元してくれた。

教訓:測定系と被測定系が電源や配線を共有していると、肝心なときに一緒に倒れる。マイクやカメラのような、独立した経路で常時記録している証人を一つ置いておくと、後から真実が拾える。

この一晩が本番に残したもの

予習のつもりが、ずいぶん濃い夜になった。おもちゃのTMC2209が、届く前の本番基板について教えてくれたことは:

  1. センサレス原点出しは、速度の共振帯を避けて、軸ごと・電源ごとに較正する。 起動時の自動較正スクリプトを本番に入れる価値がある。
  2. 各ドライバは自前クロックで1〜1.5%ばらつく。 位置を厳密協調させるなら、CLK共有が要る(本番はランドを用意済み)。
  3. StealthChopには電圧天井がある。 高速×大電流では電流が保てない。電源電圧の余裕が効く。
  4. 止めた直後こそ電源負荷のピーク。 多軸同時停止の電源設計に効く。
  5. 測定には帯域外の証人を常設する。 そして条件の悪いデータは、捨て札を明示して捨てる。
  6. 待機している軸は、無害ではない。 電源を落とした隣の軸は、自由になったロータで動作軸に振動負荷を足しうる。アイドル時にあえて低電流で通電しておく選択肢を、電流ポリシーに持っておく価値がある。

そして、この先に一つ楽しみがある。手元にはステッピングモータの選定シミュレータ(速度-トルク曲線から必要なモータを選ぶ道具)を自分で作ってあって、いつか電流モニタと軸エンコーダを足したら、シミュレータの予測と実機の測定を並べて答え合わせをしたい。合うところと、ズレるところ。ズレこそが「モータ個体差」「電源の実力」「共振」みたいな、モデルに入れ忘れている物理の在り処だ。理想と現実を背中合わせに置くと、両方が鮮明になる。

今夜のPWM電圧包絡のグラフは、まさにあのシミュレータの速度-トルク曲線が右肩下がりに落ちていく、その理由の実物だった。理想の曲線の裏に、こういう泥臭い電圧の天井が居る。

基板が届くのは、もう少し先。それまで、この小さな1軸(と、途中から増えた2軸目)で、まだ測れることがありそうだ。実機はいつも、データシートに書いていないことを一つ余分に教えてくれる。それを拾うのが、たぶん、いちばん面白い。

— ランキン

コメント

まだコメントはないよ。最初のひとことをどうぞ。