ラズベリーパイでモーター制御をしてみた ~ TA7291Pを使う

2019年6月9日

ラズベリーパイ(Raspberry Pi)を使った電子工作の定番であるモーター制御をしてみました。やっぱりラジコンの類をいつかは作ってみたいです。いきなりドローンは難しいですが、まずは2モーターで動くラジコンくらいから作りたいと考えています。

そこで、まずはモーター制御ICを入手して動かしてみました。モーター制御の電子工作には「ラズベリーパイ 3 A+」を使う予定でしたが、テスト時点では発売されていないので、再び「ラズベリーパイ zero WH」(今回は、素直にピンヘッダ付きのWHを購入しました)を使います。

1.モータードライバ「TA7291P」と配線

モーターを動かすには少し大きな電力が必要なため、ラズベリーパイ zeroGPIOの出力では足りません。そこで、モータードライバを使って制御します。モータードライバの種類は多いですが、今回は一般的な「TA7291P」を利用します。

今回のテストでは、モータードライバに以下の配線を行いました。

PIN1 GND ラズパイのGNDと電池の(-)が繋がる
PIN2 モーター(+)
PIN3
PIN4 GPIO12
PIN5 GPIO7
PIN6 GPIO8
PIN7 5V
PIN8 バッテリー(+)
PIN9
PIN10 モーター(-)

使用したモーターは、子供の頃のプラモデルか何かで使ったもので、かなりくたびれています。回転が滑らかでないので、工作には使えない状態です。接続はブレッドボードを利用して繋げました。特に難しくもないので、配線図は省略します。

2.モーター制御プログラム

プログラムは、「カイワレスタイル」さんの記事を参考にさせていただきました。

カイワレスタイル:http://kaiware007.hatenablog.jp/entry/2015/07/07/024930

配線が若干違うので、修正を施しています。モーターへの電力を制御できるGPIOは、12番と18番ですが、今回は12番を使いました。18番はGPSを使うときに1PPSで使うため、GPSを使ったモーター製作では競合してしまいますね(ソフトPWMなどを使うようです)。

また、モーターの出力をキーボード入力で変更できるようにしました。0を入力(してリターン)すると出力がプラスになり、1を入力すると出力がマイナスになります。出力値がマイナスになると、モーターは逆転します。

#include <stdio.h>
#include <stdlib.h>
#include <wiringPi.h>
#include <unistd.h>

#define MOTOROUT1 7
#define MOTOROUT2 8
#define MOTORPWM 12

int g_power = 500 ;

int main(void) {
    int i = 0;
    int c ;
    int isKeyPush = 0 ;

    if ( wiringPiSetupGpio() == -1) {
        printf("setup error");
        return 1;
    }

    pinMode(MOTOROUT1, OUTPUT);
    pinMode(MOTOROUT2, OUTPUT);
    pinMode(MOTORPWM, PWM_OUTPUT);

    digitalWrite(MOTOROUT1, 0);
    digitalWrite(MOTOROUT2, 0);
    digitalWrite(MOTORPWM, 0);

    while(1) {
        
        isKeyPush = 0 ;

        printf("0:+power\n");
        printf("1:-power\n");
        printf("q:End\n");
        c=getchar();

        for(int i=0;i<100;i++) {
            if (getchar() == '\n') {
                break ;
            }    
        }    

        if(c == 'q') break;

        if(c == '0') {

            g_power += 100 ;
            if (g_power > 1000) {
                g_power = 1000 ;
            }
            
            isKeyPush = 1 ;    

        } else if (c == '1') {
        
            g_power -= 100 ;
            if (g_power < -1000) {
                g_power = -1000 ;
            } 
 
             isKeyPush = 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) ;

        }    
    }

    return 0;
}

3.動作結果

私の環境では、出力値が800を超えたあたりからモーターが回転しました。増減値は100にしていますが、小さくすれば回転速度も細かく制御できると思います。正転や逆転も想定どおり動作しました。

これで2系統を用意すれば、ラジコン動作も可能になります。しかし、このままではキャタピラを使ったラジコン程度しか作れませんね。やっぱりステッピングモーターで舵を作ったり、4モーターでのドローンなどを考えないと作ってもお蔵入りになってしまいます。

あと、コントローラー側をどうするかも考える必要があります。今のままでは、パソコンがないと制御できません。ここはスマートフォンからタッチ式で動作を制御させたいです。この方法も検討します。

4.モーターを2つ制御する場合は?

後日、2モーター版を作り、テストしました。

ラズベリーパイにおけるPWMは2系統が用意されていることが分かりました。

1系統:GPIO12とGPIO18
2系統:GPIO13とGPIO19

モーター1つでテストした時は、GPIO12GPIO18で2系統を制御すると思っていましたが、これは同じ系統扱いです。そこで、2系統になるように、GPIO12とGPIO13を使ってテストしてみたのですが、動作してくれません。プログラムの記述にミスはないし、どうしてだろうと少し悩みました。配線やプログラムでは解決しないので、ネットで検索してみます。すると、2系統で動作させる場合は、追加の設定が必要なようです。

これは一筋縄でいかないです。また調べたのちに報告します。

後日、2モーターのテストを行いました。以下の記事を見てください。