ラズベリーパイで2つのモーターを制御する ~ PWM制御
「ラズベリーパイ Zero(Raspberry Pi Zero)」で2つのLEDの明るさを制御できたので、2つのモーターの動作を制御してみます。
1つのモーターで行ったテストは以下の記事です。
1.プログラムのソース
プログラムのソースは以下の通りです。
#include <stdio.h> #include <stdlib.h> #include <wiringPi.h> #include <unistd.h> #define MOTOROUT1 7 #define MOTOROUT2 8 #define MOTORPWM 18 #define MOTOROUT1_2 17 #define MOTOROUT2_2 27 #define MOTORPWM_2 13 int g_power = 100 ; int g_power2 = 100 ; int main(void) { int i = 0; int c ; int isKeyPush = 0 ; int isKeyPush2 = 0 ; if ( wiringPiSetupGpio() == -1) { printf("setup error"); return 1; } // pwmSetRange(1024); // pwmSetClock(100); pinMode(MOTOROUT1, OUTPUT); pinMode(MOTOROUT2, OUTPUT); pinMode(MOTORPWM, PWM_OUTPUT); pinMode(MOTOROUT1_2, OUTPUT); pinMode(MOTOROUT2_2, OUTPUT); pinMode(MOTORPWM_2, PWM_OUTPUT); digitalWrite(MOTOROUT1, 0); digitalWrite(MOTOROUT2, 0); digitalWrite(MOTORPWM, 0); digitalWrite(MOTOROUT1_2, 0); digitalWrite(MOTOROUT2_2, 0); digitalWrite(MOTORPWM_2, 0); while(1) { isKeyPush = 0 ; isKeyPush2 = 0 ; printf("z:+power\n"); printf("x:-power\n"); printf("n:+power2\n"); printf("m:-power2\n"); printf("q:End\n"); c=getchar(); for(int i=0;i<100;i++) { if (getchar() == '\n') { break ; } } if(c == 'q') break; if(c == 'z') { g_power += 100 ; if (g_power > 1000) { g_power = 1000 ; } isKeyPush = 1 ; } else if (c == 'x') { g_power -= 100 ; if (g_power < -1000) { g_power = -1000 ; } isKeyPush = 1 ; } else if (c == 'n') { g_power2 += 100 ; if (g_power2 > 1000) { g_power2 = 1000 ; } isKeyPush2 = 1 ; } else if (c == 'm') { g_power2 -= 100 ; if (g_power2 < -1000) { g_power2 = -1000 ; } isKeyPush2 = 1 ; } if (isKeyPush == 1) { if (g_power > 0) { pwmWrite(MOTORPWM, g_power); digitalWrite(MOTOROUT1, 1); } else if (g_power < 0) { pwmWrite(MOTORPWM, g_power*(-1)); digitalWrite(MOTOROUT2, 1); } else { pwmWrite(MOTORPWM, 0); digitalWrite(MOTOROUT1, 0); digitalWrite(MOTOROUT2, 0); } printf("power=%d\n", g_power); sleep(1) ; } if (isKeyPush2 == 1) { if (g_power2 > 0) { pwmWrite(MOTORPWM_2, g_power2); digitalWrite(MOTOROUT1_2, 1); } else if (g_power2 < 0) { pwmWrite(MOTORPWM_2, g_power2*(-1)); digitalWrite(MOTOROUT2_2, 1); } else { pwmWrite(MOTORPWM_2, 0); digitalWrite(MOTOROUT1_2, 0); digitalWrite(MOTOROUT2_2, 0); } printf("power2=%d\n", g_power2); sleep(1) ; } } return 0; }
今回はPWMに、GPIO18とGPIO13を使っています。
2.PWMの設定
モーター一つの時はPWMをデフォルトの設定で使いましたが、個別に設定することもできます。
pwmSetMode(PWM_MODE_PWM); // サーボモーターは、PWM_MODE_MS
pwmSetRange(1024);
pwmSetClock(100);
ここでPWMの周波数があり、モーターの周波数から割り出す計算式があります。しかしモーターの周波数も分からないし、参考にした計算式も納得できなかったので、使いませんでした。(使っても結果は同じだった)
3.動作結果
動作結果ですが、無事2つのモーターの回転を制御できました。前回できなかった理由が、OSやライブラリのアップデートをしていなかったためとは言い切れないです。
ともかく、「ラズベリーパイ zero」を使った2つのモーター制御が可能になりました。これからは、簡単なラジコンを作ることができそうです。
4.ラズベリーパイ 4でPWM制御ができない
※モーターを換装したのと、モーター用電源をUSB電源に切り替えました
「ラズベリーパイ zero」で一通りPWM制御が出来たので、「ラズベリーパイ 4 model B」でも動かしたところ、PWMが全然動作しません。PWMの設定をいろいろ変えてテストしましたが、全然動作してくれません。ラズベリーパイのOSやwiringPiのバージョンなど疑うポイントはありますが、今のところ分かりません。
「ラズベリーパイ 4 model B」でPWM制御する予定はないですが、まだPWMをマスターしたとは言えないです。やはり、周波数などをマスターしなければならないですね。
何か分かったら追記します。
2020/1/26 「ラズベリーパイ 4 model B」のPWM制御が解決
wiringPiのライブラリを更新することで解決しました。wiringPiのインストールディレクトリで
$git pull origin
$./build
で、wiringPiを再構築してください。
フォーム版も作ってみた
ターミナルからの起動はスマートフォンでは操作しずらいので、フォーム版も作ってみました。ターミナル版のソースをそっくり移植しているだけです。
これならば、ラジコンの制御も容易ですね。何か作りたいのですが、まだまとまっていません。そのうち何かは作りたいと思います。
TA7291Pの使用について
今回のテストで使用しているモータードライバ「TA7291P」ですが、すでに生産が終わった製品で手に入れずらいかもしれません。そして使用方法についても問題があるようで、違うモータードライバを使用する方が良いようです。
でも、基本的な考え方はモータードライバにおいて共通なので、移植も難しくないと思います。