ラズベリーパイで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」ですが、すでに生産が終わった製品で手に入れずらいかもしれません。そして使用方法についても問題があるようで、違うモータードライバを使用する方が良いようです。
でも、基本的な考え方はモータードライバにおいて共通なので、移植も難しくないと思います。

日本周遊マップ