AS5048Aでエンコーダーが完成したタイミングでステッピングモータの制御もできるようにしておきたくなり、パルス制御についていろいろ試してみました。
raspberry piでパルス制御する方法を探っていると、以下の方法があることがわかりました。
基本的には今後も、wiringPi => Puredataという流れで実装していくので、wiringPiのライブラリーの範疇でという制限の中での話になります。
- ハードウェアPWM (PWM.c)
- ソフトウェアPWM(softPWM.c)
- ソフトウェアサーボ(softServo.c)
- ソフトウェアトーン(softTone.c)
ハードウェアPWMはその名の通り、ハードウェア側で周波数やDutyを制御させるものです。精度とか安定性を求める使い方はこちらを使うべきですが、制限があって、使えるピンがGPIO18に限定される、かつ管理者権限での実行のみにしか使用できません。puredataのGUI使用時は管理者権限ではできないため、一旦このやり方は見送りました(もしかしたらやるかもですが)
ちなみにraspberry pi のピンのナンバリングは、ユーザー権限とか管理者権限で呼び名や番号が変わるので注意です。(以下はRPI 2+Bのピン配置)
wiringPiを使用した場合は、使用するときの以下のsetup方法によって変わります。http://wiringpi.com/reference/setup/
- wiringPisetup(); 以下の青色のピン(Wpi x)でroot権限で実行する必要があり
- wiringPisetupGpio(); 以下の緑色のピン(Gpio x )でroot権限で実行する必要あり
- wiringPisetupphy(); 以下の黒のピン(Phys x)でroot権限で実行する必要あり
- wiringPisetupsys(); 以下の緑色のピン(Gpio x)でnon root権限でも実行可能 (suid経由でrootとして実行されている?) /sys/class/gpioにアクセス
自分の環境では、puredataをGUIで実行しているときは、wiringPisetupsys();で、puredataをnon GUIモードで実行する(電源起動時に自動でパッチが起動するモード)時は、wiringPisetupGpio();を起動するようにしています。
ソフトウェアPWM(softPWM.c)は完全にGPIOをソフト的にH/L制御する方法です。ソフトウェアでH/Lする部分をライブラリー関数で実装しているだけです。そのためCPUを食います。またH/Lするタイミングは若干安定性が悪いです。
基本的にはサーボ(softServo.c)もトーン(softTone.c)も原理は一緒です。Hの時間やLの時間の制御の仕方が変わる感じです。まとめると以下のような感じ。
- PWMはDutyを変える、周期は固定(途中で変えたりもできます)
- サーボはHighの時間(時間単位で設定)が変わり、H/Lの周期も変わる(周期をピンポイントでセットはできなく計算したりしないといけない)
- トーンはDuty 50%(固定)でH/Lの周期が変わる
ステッピングモータの制御は、基本はパルス幅は一定で、周期だけを制御してスピードを変えたいので、PWMでやるかトーンでやる感じですが、トーンだとHighの時間が周期の半分で変わるのが気持ち悪い(ステッピングモーターとしては動作するとは思いますが)ので、PWMで無理やり行う方法がいいかもと思っています。
ということで、、softPWM.cを使用する方向で、まず試してみました。
softPWM_test.cを作ります。
#include <wiringPi.h> /* include wiringPi library */ #include <stdio.h> #include <softPwm.h> /* include header file for software PWM */ int main(){ //int PWM_pin = 1; /* GPIO1 as per WiringPi(WPi1),GPIO18 as per BCM */ int PWM_pin = 5; /* GPIO1 as per WiringPi(WPi1),GPIO18 as per BCM */ int i; //wiringPiSetup(); /* initialize wiringPi setup */ wiringPiSetupGpio(); /* initialize wiringPi setup */ pinMode(PWM_pin,OUTPUT); /* set GPIO as output */ //softPwmCreate(PWM_pin,1,100); /* set PWM channel along with range*/ while (1) { for (i = 5; i<1000; i++) { softPwmStop(PWM_pin); softPwmCreate(PWM_pin,1,i); //softPwmWrite (PWM_pin, 1); /* change the value of PWM */ delay (100) ; } } }
wiringPiのexampleフォルダーに上記のソースファイル(softPWM_test.c)を入れた状態で、以下でビルド
gcc -Wall -o softPWM_test softPWM_test.c -lwiringPi
エラーがなければ以下で実行します。
sudo ./softPWM_test
ステッピングモータのドライバーは3Dプリンタとかで使用されているTMC2100を使用しました。(A4988とかでも動作します)
TMC2100はステルスチョップという機能がついており、モーターの動作時の音がかなり静かです。
VMOTに12V
ENN_PDはGNDでドライバーがEnable
MR0,MR1,CSはオープンでステルスチョップ(1/16)
DIAGはオープン(使用しない)
STEPに今回のPWMの信号
DIRは回転方向(とりあえず動かすならどっちでもOK)
V_IOに制御系の電源(3.3Vを入れてます)
OA,OBにステッピングモータ(NEMA17)接続