« 2018年02月 | 2018年03月のアーカイブ | 2018年04月 »
2018/03/29
ステッピングモーターの制御についてもう少しメモ
さて、ステッピングモーターの加減速についてもうちょっと追加でメモ
取りあえず計算が簡単な台形制御での 時間(T)-速度(V) の動きがこれ。
ここでの問題は加速度がステップ状になっていて不連続な点があり、そこで多少の衝撃が発生する事。なのでこの速度変化を滑らかにするのが S字制御である。こんな感じ↓
このカーブの作り方にも色々とやり方がありそう。
定石的に良く使われるのが三角関数での接続。
変化部分の時間経過を 0 < t < 1、min から max までの速度を 0 < v < 1 として、
\[
v = 0.5 - 0.5 cos( t \pi)
\]
テーブルを引いて処理するならこれで良いのだけど、一応リアルタイムに計算できそうなやり方も考える。負荷的に一番軽そうなのが、カーブの中心で上下を分けて上半分、下半分をそれぞれ二次曲線で接続するという方法
\[
\begin{eqnarray}
v =
\begin{cases}
t^2 & ( t \lt 0.5 ) \\
1 - (1 - t)^2 & ( t \geqq 0.5 )
\end{cases}
\end{eqnarray}
\]
あるいは三次曲線で一気に繋ぐという方が良いかも。
\[
v = -2 t^3 + 1.5 t + 0.5
\]
時間 - 速度のグラフで見てみるとこんな感じになる。
加速度の変化で見ると違いがわかりやすい
更に微分した加速度の変化、加加速度 = 躍度で言えば二次曲線でもカーブの繋ぎで不連続点がでる。
逆に三角関数接続と3次関数接続の違いはもうほとんどわからないのではないかな。というか実際にモーターを回してみると台形制御と3次関数接続の違いもモーターの軸の回転を見ているだけだとあまりわからない。定量的測定が必要。
注意すべきは、同じ時間内で動作を完了するには加速度のピークが台形制御よりも高くなり、逆に加速度の上限値を揃えた状態で比較すると動作時間が長くなる事。ピークの高さは
* 二次曲線で2倍
* 三次曲線で1.5倍
* 三角関数曲線で \(\pi/2\)倍
モーターの仕様では加速度の最大値が決まっていたりするので、これがボトルネックになると動作時間が長くなってしまう。しかし実際問題現在の回転数等に関わらず一定の加速度が上限になるというのも割合雑な取り決めのような気がするし、動かしてみて大丈夫ならOKというような世界なのかも知れない。
後、総移動距離が少なくて最大速度に到達する前に減速が始まるパターンの場合の計算が面倒。台形制御なら加速時の直線と減速時の直線のクロスポイントで切り替えるだけだが、S字制御でそれをやるとせっかくなだらかにした加速度に不連続点が出るため、最大加速度を下げてカーブを繋ぐ必要がある。
posted by g200kg : 10:51 AM : PermaLink
2018/03/24
ステッピングモーターをいじっていて得た知見のメモ
せっかくなのでメモを残しておく。
話を簡単にするために、パルスを1つ送るとステッピングモーターのステップが1つ進む、という前提にしておく。
で、ステッピングモーターを1000ステップ回すためにはパルスを1000発送るわけだけど、モーターの特性として加減速レートの限界があり、急すぎる加速や急すぎる減速はできない。という事でゆっくりとスタートしてから加速して目的の速度に達すればそのまま維持、目的のステップ数に近づくと減速してから停止する、という処理が必要になる。
S字カーブみたいなのを使うと計算が面倒なので一般的に良く使われるのが台形制御。つまり下の図のような奴。
モーターの速度は秒間のパルス数、つまり周波数 \(Hz\) で表される。
\(minSpeed\) は静止状態との間で移行できる速度。\(accelRate\) は加速/減速の程度で速度が単位周波数変化するために必要な時間。単位は \(mSec / kHz\)、つまり \(uSec / Hz\)。 モーターが回転を開始すると \(minSpeed\) から一定の加速度で加速して目的の \(maxSpeed\) に達すると一定速度で運転、目的のステップ数が近づくと減速を開始し、目的のステップ数になった時にちょうど最低速度\(minSpeed\)になって停止する、という制御をしたい。
ここで問題なのがいつ減速を開始するか、つまり \(t2\) に到達したかの判定。
減速時、モーターに対して指示したステップ数の経過後に \(minSpeed\) に到達するため \(t2\) から \(t3\) 間に何ステップ進むかを知り、(総ステップ数 - 現在のステップ数) = 残りのステップ数 との比較で判定する必要がある。
という事で、\(t2\) から \(t3\) の間のステップ数は、
\[ steps = \int_{t2}^{t3} speed(t) dt \] \[ = (t3 - t2) * (maxSpeed + minSpeed) / 2 \]
また、 \[ t3 - t2 = (maxSpeed - minSpeed) * \frac{accelRate}{1000000} \] なので \[ steps = (maxSpeed - minSpeed) * (maxSpeed + minSpeed) * accelRate / 1000000 / 2\] \[ = (maxSpeed^2 - minSpeed^2) * accelRate / 2000000 \] という事になる。
逆に、残りステップ数が \(step\) の時の速度は \[ speed = \sqrt{ \frac{step * 2000000}{accelRate} + minSpeed^2 } \] になるが、これを直接使うと平方根計算に時間を取られるので、現在の速度は差分で積算する。 ステップ毎に処理する場合の減速中の現在速度\(currentSpeed_{(Hz)}\)の変化は \[ currentSpeed_{n+1} = currentSpeed_n - \frac{1000000}{currentSpeed_n * accelRate} \]
浮動小数計算だと遅すぎるのでなんとかオーバーフローしないように誤魔化しながら整数演算するとして、\(currentSpeed\)等は少なくとも 24.8 形式程度の固定小数で扱わないと誤差が累積しすぎる。
これを基に結構真面目にチューニングした奴を 16MHz Arduino で動かしてパルス速度 8kHz くらいまで動く。計算の手を抜けばもう少し速くなるけど、どうやら今使っているモーターの方がついてこない (1/8 マイクロステップ) のでこの辺にしておく。
https://github.com/g200kg/arduino-stepping-motor
posted by g200kg : 2:57 AM : PermaLink
今更だけどWeb Audio API 日本語訳の数式まわりの修正
もう1年くらい前になるんだけど、MathJax の 公式 CDN が終了した時に Web Audio API の日本語訳ページの数式が表示されなくなっていたのだけど、まったく気付かなくてずっと放置してしまっていたのをようやく修正した。
CDN の終了とか常にチェックしているわけではないので、こういうの絶対どこかに対応に抜けが発生するよな。
というかこのページの元ページの Working Draft も 2015 年 12 月版のままだからなあ。
AudioWorklet じゃなくて AudioWorker のままだし、最新仕様とかなり違ってきてしまったし、そろそろ W3C の Working Draft を更新して欲しいかな...。
更新の速い Editor's Draft の方を翻訳するのは W3C 的にはオススメではないのだろうけど、そうも言ってられないかも。
posted by g200kg : 12:40 AM : PermaLink
2018/03/22
CHIRIMEN for Raspberry Pi 3 で Stepping Motor を回す
CHIRIMEN for Raspberry Pi 3 でステッピングモーターを回す記事を Qiita に書きました。
Qiita : CHIRIMEN for Raspberry Pi 3 チュートリアル 6. ステッピングモーター編
信号を処理するタイミングが厳しいので Arduino を I2C スレーブデバイスとして使っていますが、この Arduino 用の I2C => SteppingMotor I/F のスケッチは別途 GitHub に置いてあります。
GitHub : arduino-stepping-motor
やってみてわかったのは減速レートの処理のあたりがなかなかポイントのようです。現在の回転速度からいつブレーキをかけ始めると指定のステップ数でぴたっと止まるか、みたいな。
計算式ベースでオプティマイズして Arduino でパルス周波数 7kHz あたりが限界くらい。まあまあ良いかなと思ってるのだけどこのあたりは計算負荷がきつくなるのでテーブルを引いちゃうのが一般的みたいですね。テーブル化すればもう少し速く回せる気がするけどちょっと負けた気もする。
posted by g200kg : 11:36 PM : PermaLink
2018/03/11
Arduino の電源回路
今まであまり気にしてなかったのだけど、良く見ると Arduino の電源部分ってなかなか興味深い事になっているのだな。
推奨される Arduino に電源を供給する手段としては
・DCジャックに 7 - 12V を供給する
・VIN端子に 7 - 12V を供給する
・USBケーブルを接続して5Vを供給する
という方法があり、その他に 5V 端子に 5V を供給する、という手段も良く使われているようです。
下の図が Arduino の電源部分の抜粋なのだけど、上の段 X1 がDCジャックで逆流防止のダイオードを通した所が VIN、そこから U1 の NCP1117 がレギュレータで 5V を作っていると。一方下の段、USBVCC が USB からの 5V でこちらは MOS FET のスイッチを通して 5V ラインに直結されます。で、この MOS FET のスイッチは U5 で制御されるのですが、VIN の電圧が 3.3V の 2倍、6.6V 以下であればオンになって USB 側から給電されると。
FETはどうやってオンするの?
しかし、良く見るとこの FET は GS 間の電位差がないとオンしないし、U5の電源も +5V ラインから取っているからそもそもオンしないんじゃ? と思ったけど、この MOS FET って更に良く見ると逆電圧使用になっている。なのでオンしなくても取りあえず寄生ダイオード経由で USBVCC が 5V ラインにだだ漏れしていくと。なるほど。つまりこの FET は USBVCC を完全に切り離すのではなく逆流防止として使われているという事らしい。なかなかトリッキーな気がするけどこういう方法って一般的なのかな?
5V 端子から電源入れて良いの?
そしてもう一つ。 電源供給で 5V 端子に外部から 5V を供給するやりかた。この方法を使った事例は良くみるのだけど、一応公式のドキュメントとしては、
5V.This pin outputs a regulated 5V from the regulator on the board. The board can be supplied with power either from the DC power jack (7 - 12V), the USB connector (5V), or the VIN pin of the board (7-12V). Supplying voltage via the 5V or 3.3V pins bypasses the regulator, and can damage your board. We don't advise it.
という事でどうやらおすすめされていない。
気になる点としてはレギュレータの NCP1117 の出力側にだけ電圧をかけちゃう事かなぁ、と思ったけどよく考えると DC ジャックを繋がずに USB で駆動している状態と同じじゃないか。これで壊れるなら USB 電源で動かしているだけで壊れるって。という事で先の公式の文言はどうやら、ここに変な電圧をかけるとボードが一発で駄目になるからおすすめしない、という意味での注意ではないかと解釈するのが正しそうだ。そうだよね?
となると、そもそもレギュレータの出力端子にだけ電圧をかけてぶっ壊れるという件に対しては大丈夫なのか? という疑問があるが、これはレギュレータ NCP1117 のデータシートに答えがある。
Protection Diodes
The NCP1117 family has two internal low impedance diode paths that normally do not require protection when used in the typical regulator applications. The first path connects between Vout and Vin, and it can withstand a peak surge current of about 15 A. Normal cycling of Vin cannot generate a current surge of this magnitude.
だそうだ。つまり電圧が出力端子>入力端子になっても保護ダイオードが内蔵されているので大丈夫だよ、と。
ふむ、という事で安心して 5V 端子から 5V を供給して動かす事にしよう。まあ、5V端子から給電している時にVINに変なものを繋いでるとまずそうだし、直結なので注意しないといけないというのは確かだけどね。
Arduino UNO Rev.3 回路図
Arduino UNO Rev.3 DOCUMENTATION
NCP1117 Datasheet
posted by g200kg : 1:07 AM : PermaLink
2018/03/04
CHIRIMEN for Raspberry Pi 3 で WebBluetooth
CHIRIMEN for Raspberry Pi 3上の WebBluetooth 経由で BLE ライトの PLAYBULB を制御する記事を Qiita に書きました。
Qiita : CHIRIMEN for Raspberry Pi 3 で WebBluetooth
他の形状のバージョンもありますがこの丸っこい奴が Bluetooth 経由で制御できるライト、PLAYBULB です。しかしまあ、ブラウザ上から Bluetooth のペアリングを設定して制御できるとか、えらいことになってますね。
このサンプルは、音に反応して光ったりなかなか楽しい事ができますから PLAYBULB (sphere または candle) をお持ちの方は是非。
posted by g200kg : 8:06 PM : PermaLink
« 2018年02月 | 2018年03月のアーカイブ | 2018年04月 »
-->
g200kg