前回まではライブラリなどに頼りながら、ステッピングモーターを動作させるところまでやってみました。今回は、このステッピングモーターのプログラムについてちょっとだけ詳しくその動作と、ステッピングモーターを扱う上でよく出会う問題と対処についても勉強してみたいと思います。
今回の電子工作レシピ
時間目安:90分
必要なパーツ
- Arduino UNO R3
https://www.switch-science.com/catalog/789/ - 42mm ステッピングモータ 12V 2相
https://strawberry-linux.com/catalog/items?code=12026 - L6470 ステッピングモータ・ドライバキット
https://strawberry-linux.com/catalog/items?code=12023 - L6470/42x34mmステッピングモーター用ネジセット
https://strawberry-linux.com/catalog/items?code=12051 - 5mmユニバーサルマウント(2個セット)
https://strawberry-linux.com/catalog/items?code=12049 - 006P 9V電池ホルダー
http://akizukidenshi.com/catalog/g/gP-02665/
ステッピングモーターのおさらい
第37回のステッピングモーターの基礎でも触れましたが、ステッピングモーターをプログラムで制御するためにもう一度おさらいをしておきます。下記の特徴からもわかるように、通常のモーターやサーボモーターなどと比べてステッピングモーターの特徴は「回転を制御できる」ということですね。
- モーター:電力をかけるとひたすら回る
- サーボモーター:信号に応じて0度からN度の範囲で回転する
- ステッピングモーター:信号に応じてモーターを制限なく制御できる
また、これらの制御を実際行うためにはPWM信号をモーターに送るのですが、Arduinoに直接ステッピングモーターを取り付けても制御が難しいため、実際にはArduinoなどのマイコンからステッピングモーターを制御するためのモータードライバを経由することでモーターのさまざまな制御が可能となります。(通常のモータードライバ扱い方に関しては第12回の記事を参照)
今回利用しているL6470というステッピングモーター用のモータードライバは、安価でステッピングモーターに対する過電流検出・DSP・通信用I/Fなどを搭載した制御・発振回路が組み込まれています。本格的に回転数やモーターのパワーを必要とする、動作の正確性が欲しいという状況の場合は、下記のリンクのように機能や用途にあったモータードライバを選んで回路を作成する必要があります。
今回は手軽に安価に利用したいということなので、L6470を利用していますが、前回・前々回とステッピングモーターを動かしてみて、回転するはずなのに、音と振動だけで軸が回らないなどのように、動作がおかしくなったことはなかったでしょうか?
ステッピングモーターの脱調(だっちょう)現象
ステッピングモーターを扱う上で、よく出会うのがこの脱調(だっちょう)。脱調とは簡単に説明するとステッピングモーターを回す制御信号に対して、実際のステッピングモーターの動作が追いつかない場合に、モータードライバ側で認識している回転位置と実際のステッピングモーターの位置がずれてしまうため、うまく同期が取れずにモーターが回らない現象です。
脱調が発生する原因はいろいろあるのですが、下記のような動作をステッピングモーターにさせた場合発生しやすくなります。
- ステッピングモーターを急に加速・減速させる
- 急な加速・減速のタイミングで信号とモーターがずれる確率があがります。これらの場合は、最初徐々に加速・減速するなど工夫をすることで解消できる場合が多いです。
- トルク不足
- モーター自体のトルク(回す力)が足りていない場合も発生しやすいです。この場合は、トルクがある程度あるモーターに変更するなどの対策が必要です。
- 駆動電圧が低い・安定していない
- 駆動電圧が低かったり、安定していないと脱調の原因になります。L6470の仕様は8V-45V ですが、ぎりぎり8Vなどで利用する場合などは注意が必要です。
- 振動による影響
- モーターに振動を加えるとその影響で脱調してしまうことがあります。
主に、脱調している場合は上記のいずれかの理由が考えられますが、急加速や速度の出しすぎによるトルク不足などはその中でもよく原因になりますので、ステッピングモーターが脱調しているな、という場合はこれらの原因を洗ってみてください。
またL6470を販売するストロベリーリナックスのサポートページには脱調を含め、FAQがまとまっておりますので、そちらも参照するのをおすすめします。
ステッピングモーターのプログラムについて
今回の主題、ステッピングモーターのプログラムについて、詳しく勉強してみます。ArduinoからL6470を通してステッピングモーターを制御するには、L6470に制御信号を送るプログラムが必要です。回路は下記のとおりです。
ステッピングモーターのプログラム動作の流れ
下記がステッピングモーターのプログラムです。第37回、第38回と出てきましたが、このプログラムの流れを紐解いていきます。
#include <Arduino.h> #include <SPI.h> //(1)SPI通信をするための読み込み //(2)ステッピングモーター用のピンの定義 #define PIN_SPI_MOSI 11 #define PIN_SPI_MISO 12 #define PIN_SPI_SCK 13 #define PIN_SPI_SS 10 void setup() { delay(1000); Serial.begin(9600); //(3)ステッピングモーター用のピンの準備 pinMode(PIN_SPI_MOSI, OUTPUT); pinMode(PIN_SPI_MISO, INPUT); pinMode(PIN_SPI_SCK, OUTPUT); pinMode(PIN_SPI_SS, OUTPUT); digitalWrite(PIN_SPI_SS, HIGH); //(4)SPI通信の開始宣言 SPI.begin(); SPI.setDataMode(SPI_MODE3);//SCKの立上りでテータを送受信、アイドル時はpinをHIGHに設定 SPI.setBitOrder(MSBFIRST);//MSBから送信 //(5)L6470の利用設定 L6470_setup(); } //********************************************** //(6)SPI通信するための関数 //********************************************** void L6470_send(unsigned char value){ digitalWrite(PIN_SPI_SS, LOW); SPI.transfer(value); //制御信号をSPI通信で送る digitalWrite(PIN_SPI_SS, HIGH); } //********************************************** // (7)L6470のセットアップ //********************************************** void L6470_setup(){ //デバイス設定 L6470_send(0x00); L6470_send(0x00); L6470_send(0x00); L6470_send(0x00); L6470_send(0xc0); //最大回転スピード設定 L6470_send(0x07);//レジスタアドレス L6470_send(0x20);//値(10bit),デフォルト0x41 //モータ停止中の電圧設定 L6470_send(0x09);//レジスタアドレス L6470_send(0xFF);//値(8bit),デフォルト0x29 //モータ定速回転時の電圧設定 L6470_send(0x0a);//レジスタアドレス L6470_send(0xFF);//値(8bit),デフォルト0x29 //加速中の電圧設定 L6470_send(0x0b);//レジスタアドレス L6470_send(0xFF);//値(8bit),デフォルト0x29 //減速中の電圧設定 L6470_send(0x0c);//レジスタアドレス L6470_send(0xFF);//値(8bit),デフォルト0x29 //フルステップ,ハーフステップ,1/4,1/8,…,1/128ステップの設定 L6470_send(0x16);//レジスタアドレス L6470_send(0x00);//値(8bit) } //********************************************** // (8)メイン処理 - loop() //********************************************** void loop(){ //360度 - 1回転させる処理 L6470_send(0x50);//Run(DIR,SPD),0x51:正転,0x50:逆転 L6470_send(0x00); L6470_send(0x20);//回転スピードの設定 L6470_send(0x00); delay(1604);//1604msで約1回転 L6470_send(0xB8);//急停止(ハードストップ) }
制御信号 – SPI通信について
まず、L6470とArduinoの間では、制御信号のやりとりをSPI通信(シリアル・ペリフェラル・インタフェース – Serial Peripheral Interface, SPI)という方式で行います。このSPI通信とは、ArduinoなどのマイコンやICチップ同士などで信号をやりとりする際に使われる方式です。
プログラムの2行目(1)にある「#include <SPI.h>;」という表記で、Arduino上でSPI通信を利用する準備をしています。これまでライブラリを利用する際にも、「#include <***.h>」などのような表記がありましたね。
次に、(2)の部分で、L6470で利用するピンの設定を行います。ここではMOSIとかMISOとか書いてますが、これらがSPI通信の基本となる信号線になります。
SPI通信では、信号線は下記の基本的に3本(SS信号を使う場合は4本)で構成されます。それぞれ信号線はクロック(SCK)と出力信号(MOSI : Master Out Slave In)と入力信号(MISO : Master In Slave Out)という役割を持っていて、実際に通信する時に内部では、Arduino側が出力するクロック信号(SCK)を基準にして、L6470側と互いに向かい合わせて接続したそれぞれのインとアウト(MISOとMOSI)を使って、同時に8ビット単位のデータの送受信を行うしくみです。
- SCK – Serial Clock
- MISO – Master In Slave Out
- MOSI – Master Out Slave In
- SS – Slave Select
(3)で実際に利用する信号線のピンモードを設定します。次に(4)でSPI通信の利用モードを設定します。これは接続するデバイスにあったモードを選択する必要があります。(慣れないうちはこういうものか、という感じでとらえてください)
SPI通信の準備ができたので、(5)でようやくSPI通信を利用してL6470のセットアップを開始していきます。実際にSPI通信の信号を送信する部分は(6)でL6470_send()関数としてまとめてあります。
L6470のセットアップでは、データシートやマニュアルに記載されている仕様を確認しながら必要な項目をセットアップしていきます。
L6470 データシート – ストロベリーリナックス
※ページ下部にL6470説明書 と データシートが記載されています。
データシートの中身を見てみると、下記のような表やコマンドのアドレスが記載されています。今回12026モーターを使っていますので、表を参考にレジスタアドレスをSPI通信で送信してL6470の初期設定を行います。
表とプログラムの見方としては、例えば
//最大回転スピード設定 L6470_send(0x07);//レジスタアドレス L6470_send(0x20);//値(10bit),デフォルト0x41
とプログラム側でありますが、これは表の機能「最大回転スピード」の行を見ていただければ、アドレスに「 0x07」、長さ「10」bit、初期値が「0x20」(12026モータの例)となっていますね。この表の値をSPI通信で送信することで設定ができるようになっています。
初期設定が完了したら、(8)メイン処理で、実際にステッピングモータを動かす命令を書きます。さらにデータシートを確認すると、さまざまなコマンドが記載されていますね。
- 回転させるコマンド
0x51(正回転の場合)、0x50(逆回転の場合) - ストップ(ソフト)コマンド 0xB0
例として、回転コマンドでは正回転か逆回転かを送信したのちに、20bitの回転スピードを送信、delay(1604);で指定した時間分回転をさせています。この回転スピードの値を変更すれば遅くなったり早くしたりすることが可能です。
これが、ステッピングモーターをL6470を使ってArduinoで動かす場合の流れになります。また、これを応用して接続方法を若干変えることで前回紹介したように複数のステッピングモーターを制御することができます。
2輪走行ロボットを動かしてみる
ステッピングモーターのプログラム処理の流れがわかったところで、2輪走行ロボットを完成させましょう。前回、3Dプリンターで出力したタイヤとボディの用意ができたので、必要な部品をボディに載せます。
Arduino、ブレッドボード、ステッピングモーター用9V電池(直列で2個)と、載せていくと結構スペースがないですね…汗
ということでArduino UNOではなく、Arduino Pro Miniに載せ替えてみました。
すべてのパーツを載せ終わったら、いよいよ電源を入れて動かしてみます。
無事動きましたね!動画では12Vのアダプタにステッピングモーターをつないでいますが、9V電池をつないだときには、ちょっと重いためかステッピングモーターのトルクが若干足りていない現象が見られました。この場合は、最初に書いたようにある程度重い場合であればモーター自体を変えたり、軽量化を図ったり、電源をもう少し改良するなどで安定した走行が可能となります。
まとめ
今回ステッピングモーターを使って2輪走行ロボットを作ってみました。今回はプログラムに記載された処理に応じて走行するだけでしたが、例えばここに光センサを四方につけて、明るいほうに進んで行くロボットを作ったり、音に反応して近づいたり、はたまた以前に紹介したESP-WROOM-02をベースにwifi通信でスマートフォンから操作できるロボットに改良したりと、応用次第でなんでもできてしまいますね。今後、本連載でも改良の方法をご紹介できればと思っています。
次回は、地磁気センサーという何やらかっこよさそうな名前のセンサーを利用して、デバイスを作ってみたいと思います!