公開日:2019/05/11
title.png

5th Season


#5-7 マイクロステップ励磁

 今回は、再びステッピングモータを回します。基本的な仕組みについては「#3-6 ステッピングモータ」の回を復習してみてください。今回も、ULN2003ANドライバモジュール(下図左)と、28BYJ-48(2相ユニポーラステッピングモータ、下図右)を使います。

ar36_drv.jpgar36_stepper.jpg

 ただ回すだけなら、「#3-6 ステッピングモータ」で実験済みですので、今回は、マイクロステップ励磁という方式を使って回してみます。ついでに、処理をブロックせずに、ステッピングモータを回すことができる関数群を作ってみましたので、モータを回しながら並行して別な処理を実行したい時にも使えると思われます。

励磁方式

 「#3-6 ステッピングモータ」の時は、ArduinoのライブラリにあったStepperクラスを使いました。Stepperクラスの励磁方式が2相励磁方式だということは、「#3-6 ステッピングモータ」で述べた通りです。

 励磁方式には、主に以下表の様な方式が存在します。

  時間の流れ→
ステップ番号
1相励磁 IN1 1        
IN2   1    
IN3     1  
IN4       1
2相励磁 IN1 1 1    
IN2   1 1  
IN3     1 1
IN4 1     1
1-2相励磁 IN1 1 1 1          
IN2     1 1 1      
IN3         1 1 1  
IN4 1           1 1

 名前の由来は、「同時に電流を流す(励磁)コイル(相)の数」だと思われます。横軸が時間の流れなので、縦(同一時間)に見て、いくつのコイルに同時に電流が流れているか?と、名前の「xx相励磁」を見比べると、なんとなく理解できると思います。

 ご覧の通りON−OFFで、電流を流すコイル(IN1〜IN4)を変化していくことによって、モータを回転させています。使用するステッピングモータが同じなら、1相および2相励磁の4ステップ分で回転する角度と、1-2相励磁の8ステップ分で回転する角度は同じです。
 この時の回転角度をθ[°]とすると、1相、2相励磁ではθ/4[°/ステップ]単位で回転するのに対して、1-2相励磁では、θ/8[°/ステップ]単位で回転するので、より滑らかに回転させることができます。もっと滑らかに回転させるためには、ステップ数を増やして、かつ、コイルに流す電流値をON−OFFではなくアナログ的に制御すれば良いのです。このように制御した励磁方式をマイクロステップ励磁と呼んでいます。
 ステップ数を際限なく増やしても無意味なので、以降本ページでは、θ[°]回転に対応するステップ数を128として話を進めます。

※最終的に振り返って検証してみると、「128は多すぎたかな?」という印象はあります。減らす分には、間引いてテーブル参照すれば良いので、128で話を進めておきます。

 電流値をアナログ的に制御するために、印加する電圧に正弦波を使います。
 各励磁方式に対応したマイクロステップ波形(θ[°]に対応している)を以下図に示します。横軸が時間軸なので、縦に見て、同時に"1"になっている矩形波が何本あるか見ると、どの励磁方式か見分けがつきます。

ar57_1phase.pngar57_2phase.pngar57_12phase.png

 矩形波のHIGHパルス部分に正弦波の山が来るように描画された曲線が、今回生成するマイクロステップ励磁波形です。

マイクロステップ波形を生成する

 「正弦波を作ってモータを駆動する」、デジャヴですね。前回(「#5-6 正弦波を生成する」で)やったばかりです。5Vのアナログ波形なんて生成してどうする(何に使う)の?」と、思われたかもしれませんが、応用利いたでしょ?
 「#5-6 正弦波を生成する」のテクニックを使えば、単純な正弦波に限らず任意のアナログ波形を生成可能ですから、前節に示したマイクロステップ波形だって、生成することができます。

 ただ、今回は4相分の波形計算(float、遅い)が必要となり、これを毎回Arduino UNOにやらせるのは酷なので、あらかじめ正弦波を生成するためのデューティ値(0〜255、符号無8ビット整数)を計算して、テーブルにしておきます。

  const int mstep_max=128;  // maximum steps
  PROGMEM const uint8 mstep_2micro[mstep_max]=
  {
    0x80,0x86,0x8c,0x92,0x98,0x9f,0xa5,0xab,
    0xb0,0xb6,0xbc,0xc1,0xc7,0xcc,0xd1,0xd5,
    0xda,0xde,0xe2,0xe6,0xea,0xed,0xf0,0xf3,
    0xf6,0xf8,0xfa,0xfc,0xfd,0xfe,0xff,0xff,
    0xff,0xff,0xff,0xfe,0xfd,0xfc,0xfa,0xf8,
    0xf6,0xf3,0xf0,0xed,0xea,0xe6,0xe2,0xde,
    0xda,0xd5,0xd1,0xcc,0xc7,0xc1,0xbc,0xb6,
    0xb0,0xab,0xa5,0x9f,0x98,0x92,0x8c,0x86,
    0x80,0x79,0x73,0x6d,0x67,0x60,0x5a,0x54,
    0x4f,0x49,0x43,0x3e,0x38,0x33,0x2e,0x2a,
    0x25,0x21,0x1d,0x19,0x15,0x12,0x0f,0x0c,
    0x09,0x07,0x05,0x03,0x02,0x01,0x00,0x00,
    0x00,0x00,0x00,0x01,0x02,0x03,0x05,0x07,
    0x09,0x0c,0x0f,0x12,0x15,0x19,0x1d,0x21,
    0x25,0x2a,0x2e,0x33,0x38,0x3e,0x43,0x49,
    0x4f,0x54,0x5a,0x60,0x67,0x6d,0x73,0x79,
  };


 そこそこ大きなテーブルなので、PROGMEMを指定して、Flashメモリ上に配置しておきます。PROGMEMについては「#4-3 赤外線リモコン(送信)」で解説済みです。

 マイクロステップではない、矩形波のxx相励磁方式と比較できるように、xx相励磁方式(ON−OFF制御)のテーブルも作っておきます。同じプログラムで共通使用できるように、全て128ステップに引き伸ばして作成します。

  PROGMEM const uint8 mstep_12phase[mstep_max]=
  {
    0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
    0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
    0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
    0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
    0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
    0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  };


 このようにしておくと、使うテーブルを変更するだけで、様々な励磁方式でステッピングモータを回転させることができます。それぞれの特徴を同じプログラムで見比べることができるので、有意義な実験ができるはずです。

 時間のマネージメント、ステップ番号の計算、テーブルの参照など、具体的なアプリケーションになった分、見た目は大きく異なっていますが、「#5-6 正弦波を生成する」で解説したテクニックと同じですので、実際のコーディングについては完成版プログラム(test_mic_step.ino)で各自確認して下さい。

マイクロステッピングモータ制御関数群

 マイクロステップ励磁方式を使ったステッピングモータ制御関数群の仕様は以下の通りです。

 analogWrite()関数が使っているタイマのカウントクロックはfcpu/64で、この時のPWM周波数はfcpu/64/(2×255)≒490Hzです。これでは少し遅すぎて、128ステップ/θのマイクロステップを活かしきれないと判断したため、タイマのカウントクロックをfcpu/8に変更することにしました。この場合のPWM周波数はfcpu/8/(2×255)≒3.9kHzです。

  TCCR1B=0x02;  // fcpu/8
  TCCR2B=0x02;  // fcpu/8


※後ほど、別な理由でもう一度カウントクロックを変更することになりますが、この場はひとまず、fcpu/8としておきます。

モータを繋ぐ前に

 モータを繋ぐ前に、ドライバモジュールに設けられたLEDを使って、プログラムのデバッグを実施します。と、言っても、執筆時点でプログラムは完成しているので、皆様には完成版プログラムを提供しておきます。

  完成版プログラム:test_mic_step.ino

 Arduino UNOに転送したら、シリアルモニタを開いてください。以下のコマンドを受け付けるようになっています。

 モータは繋がずに、Arduino UNOとULN2003ANドライバモジュールを以下の様に接続します。

Arduino UNO 接続 ULN2003AN
5V + (プラス端子)
GND − (マイナス端子)
D9 IN1
D10 IN2
D11 IN3
D3 IN4

 ドライバモジュール基板上に搭載されているLEDを使って、励磁方式のデバッグを行います。モータを支えるだけの電力を供給できない恐れがあるので、モータはまだ繋がないでください。

  実験サンプル:【 】内はシリアルモニタからの送信データ
  【spd,2000,128】 …… 128マイクロステップを2,000ms(=2s)で実行
  OK: speed 15625[us/step]

  【pat,p1】 …… 励磁パタンテーブルを1相励磁にセット
  OK: pattern p1

  【step,512】 …… 512マイクロステップ実行(実行時間は8s)
  OK: step 512 (512)

 指定した励磁パタンに従って、LEDが順番に光ればOKです。

  実験サンプル:【 】内はシリアルモニタからの送信データ
  【pat,m12】 …… 励磁パタンテーブルを1-2相マイクロステップ励磁にセット
  OK: pattern m12

  【step,512】 …… 512マイクロステップ実行(実行時間は8s)
  OK: step 512 (512)

 PWMによって、中間的な明るさでLEDが光りますので、先程のON−OFF発光とは違った印象に見えるはずです。このスピードなら、LEDの光る様子を目視でき、各励磁方式の違いを観測できると思います。【pat】コマンドで励磁パタンテーブルを変えながら試してみてください。【step】コマンドに負の数を与えて、逆回転させる時のLEDの光り方なども確認しておきます。

 各励磁方式でLEDを光らせた時の動画です(↓)。



 どうやら、正しくインプリできているようですので、モータを繋いで回してみましょう。

モータを繋いで回す

 Arduino UNOのVccでは、ステッピングモータの電力を支え切れない恐れがあるので、ACアダプタと電源モジュールを使います。

ar26_acpow.jpg

 結線を以下の様に変更します。

Arduino UNO 接続 ULN2003AN 接続 電源モジュール
Vcc × + (プラス端子) 5V
GND − (マイナス端子) GND
D9 IN1  
D10 IN2
D11 IN3
D3 IN4
  モータコネクタ 28BYJ-48

 1ステップの回転角度は非常に小さいので、下図の様にモータの回転軸に結束ワイヤ(配線などを束ねるのに使うワイヤ)を巻き付け、回転軸から18cmほど伸ばし、変位量が増幅された先端の動きを観測します。

ar57_step.jpg

 ポイントは、以下の状態を確認することです。

 用意した励磁パタンテーブルは6つ(p1,p2,p12,m1,m2,m12)あるのですが、全部見ても、差が見え難いものもあるので、この内、p2、p12、m12で回転させた動画をご覧に入れます。
 2相励磁方式(p2)に比べて、1-2相励磁方式(p12)では最小回転角度が1/2となるため、少し滑らかに回転しますが、まだカクカクと離散的に動いていることがわかります。1-2相マイクロステップ励磁(m12)にすると、滑らかに、連続的に回転している様子がわかると思います。



 とは言え、動画のフレームレートやネットワークの通信速度によっては、わかり難いかもしれないので、その場合はご自身で回して確かめてください。

※今回使用したステッピングモータ28BYJ-48は、ギア比が1:64と言うことで、1ステップに相当する回転角度が本来(ギアが無かった場合)の1/64になっています。このせいで、マイクロステップの効果が観測し難くなっています。マイクロステップの評価には、ギア無しか、なるべくギア比の小さなモータの方が適している様です。

 その他雑感ですが、マイクロステップ励磁の中で、1相マイクロステップ励磁方式(m1)は、カクカクと離散的に回転しており、マイクロステップ励磁の長所が観測できませんでした。隣相励磁パタンとの重なり部分が最小になっているから、でしょうか?相互作用で中間的な角度に回転させる力が弱いのでは?と言うのが個人的な見解です。
 印加電圧波形を、通常のON−OFF励磁波形と比べるとわかりますが、最大電圧値でドライブする時間が圧倒的に短くなっていますので、トルクも弱くなっているでしょう。
 何でもかんでも、「マイクロステップにすれば良い」と言う物ではないみたい……。

耳障りな雑音

 もう一つ気になったのが、モータから聞こえる「ピ〜〜〜」という甲高い雑音です。マイクロステップ励磁を選択した時だけ発生します。と言うことは恐らく、PWMの周波数(約3.9kHz)に起因する雑音だと思われます。3.9kHzは可聴域(20〜20k[Hz])内ですから。
 この時は、タイマのカウントクロックにfcpu/8を使用していました。1段速くすると、fcpu/1(16MHz)でのカウントも可能で、その場合のPWM周波数はfcpu/(2×255)≒31.4kHzとなります。→可聴域を超えるので、雑音が消えるはずです。

 ただ、PWMの一番短いパルスでは、周波数fcpu/1で2周期分(=125ns@16MHz)のHIGHパルスやLOWパルスが出力されることになります。ULN2003ANのトランジションは大丈夫でしょうか?
 ULN2003ANのデータシートは、「#3-6 ステッピングモータ」で検索して確認済みです。関係しそうなスペックは、tPLH,tPHL(Propagation delay time)ですが、MAX 10μsと、nsオーダの最小パルスは通過できそうにないですね……。Ta=25℃のTYP条件でようやく250ns。これでも、最小パルスはフルスケールまで振れないかも?
 最小パルスが出るのは、正弦波の頂点と谷底の周辺だけで、その辺りなら電圧変化もなだらかなので、まあ、何とかなるかな?幸い、波形が少しでも崩れるとアウト!な、通信系ではないですし、ね。

 プログラムの先頭付近にある、「#define USE_CLK_DIV_1」を有効にすると、fcpu/1でPWM出力するように設定することができるようにしておきました。と、言うより、デフォルトで有効になっているので、あえて、雑音を聞いてみたい方は、#defineをコメントして試してみてください。

※あるいは、本当にワースト条件下(低電圧、高温環境、製造ばらつき等、tPLH,tPHLがMAX 10μsになる条件下)で使用する場合には、かなり波形が崩れる恐れがあるので、USE_CLK_DIV_1をコメントして使った方が無難です。

 タイマのカウントクロックをfcpu/1に変更して回してみたところ、先ほどの耳障りな雑音が消えました。予想通り(1^−^)v。

 念のため、ISR内の処理時間を計測したところ、約15μs前後かかっていることが分かりました。fcpu/1のカウントクロックでは、TC1がオーバフロウする間隔は2×255/fcpu≒31.9μsなので、まだ、何とか破綻せずに処理可能なレベルです(∵割り込み周期>割り込み処理時間)。これで耳障りな雑音が消えるなら、良いのかな?

※ただし、CPUタイムのほぼ半分がモータを回すため(ISR内処理)に費やされる事になるので、モータ回転中のCPUスピードは8MHz相当だと思った方が良いです。モータ回転中に、並行して重い処理をさせたい場合は注意してください。


 歳を取ると高音域が聞こえ難くなるらしいですが(1^^;)、可聴域20〜20k[Hz]に対して、約31.4kHzまで突き抜けているので、さすがに若い方でも聞こえない周波数のはずです。


btn_arduino.png

btn_prev.png btn_next.png

home