ラズベリーパイで2つのモーターを制御する ~ PWM制御

2020年1月19日

ラズベリーパイ 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」ですが、すでに生産が終わった製品で手に入れずらいかもしれません。そして使用方法についても問題があるようで、違うモータードライバを使用する方が良いようです。

でも、基本的な考え方はモータードライバにおいて共通なので、移植も難しくないと思います。