TA7291P モータードライバと HC-05 を使ってモーターを無線制御

昔から定番らしい、TA7291P を使ってモーターを駆動させます。DRV8830 の I2C 制御とは違って、GPIO ピンを2本使ってモータの正反転を制御します。ピンから送る信号を analogWrite を使ってパルスにすれば PWM 制御できるらしいので(本来の使い方ではないけど)モーターを可変でも動かせます。秋月電子で2個セットで買えます。

ただし、2個動かすならば L293D というモータードライバが、Arduino のモーターシールドには乗っています。2個のモーターを同時に自作しようかなと思ったのですが、L293D は日本では売ってません。でもって、この L239D の後継?っぽいのが、TB6612FNG ってやつで、これはスイッチサイエンスさんとかで売ってます。TA7291P もそうなのですが、制御線とモーターへの電力線が別に取れるので、結構な大電流をモーターに流すことができます。たぶん、モーターの回転によるパルスとがが制御線に与える影響も少ないかなと思うのですが、これは調べてみないとわかりません。DRV8830 を2個使ってモーターを動かしたときに、たまに I2C の信号が暴走してしまうらし、モーターが回りっぱなしになるんですよね。適切な抵抗とコンデンサを入れてやれば低減できるような気もするのですが、これはちょっと初心者には厳しい。センサーの類とかを同時につなげると良く分からない状態になりそうです。これは実地で調べていく予定。

ブレッドボードで組み立て

 

TA7291P_モーター1個_ブレッドボード

例によって、ブレッドボードの組み立てはこんな感じです。Frizing で TA7291P の部品を作って配置してみたのはいいけど、回路図のところが大きすぎて不細工なので…回路図のほうが後から。

image

端子はデータシートから。回路は モータドライバの使い方について -byうしこlog を参考にして作っています。Arduino の 8,9 ピンにつなげて正反転を制御しています。ここのピン番号がお好みで。Arduino から 5V 給電しているところに 100μF 程度のコンデンサを入れると Bluetooth から制御したときにモーターの動作が安定します。パスコンは、もっと計算しないと駄目かと思ったけど、意外とフィーリングで大丈夫そうなので、パスコンって何? を参照にして適当に(苦笑)。

例によって HC-05 を使って Bluetooth 制御するので、TX/RX をつなげておきます。

Arduino のスケッチ

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#include <Wire.h>
 
const int OUTR1 = 8 ;
const int OUTR2 = 9 ;
const int OUTL1 = 10 ;
const int OUTL2 = 11 ;
 
void setup() {
  // put your setup code here, to run once:
  pinMode( OUTR1, OUTPUT );
  pinMode( OUTR2, OUTPUT );
  pinMode( OUTL1, OUTPUT );
  pinMode( OUTL2, OUTPUT );
  digitalWrite( OUTR1, LOW );
  digitalWrite( OUTR2, LOW );
  digitalWrite( OUTL1, LOW );
  digitalWrite( OUTL2, LOW );
 
  Serial.begin(9600);
  Serial.println( "Motor Standby" );
  delay( 2000 );
}
 
void loop() {
  int len = Serial.available();
  if ( len < 2 ) return ;
  int type = Serial.read();   // M/N or L
  int num  = Serial.read();   // MF/MB/M0, L0/L1
 
  if ( type == 'M' || type == 'N') {
    int mode = 0;
    switch ( num ) {
      case '0': mode = 0; break;
      case 'F': mode = 1; break;
      case 'B': mode = 2; break;
      default: mode = 0; break;
    }
    switch ( mode ) {
      case 0:
        Serial.println("stop----" );
        if ( type == 'M' ) {
          digitalWrite( OUTR1, LOW );
          digitalWrite( OUTR2, LOW );
        } else {
          digitalWrite( OUTL1, LOW );
          digitalWrite( OUTL2, LOW );
        }
        break;
      case 1:
        Serial.println("forward-" );
        if ( type == 'M' ) {
          digitalWrite( OUTR1, HIGH );
          digitalWrite( OUTR2, LOW );
        } else {
          digitalWrite( OUTL1, HIGH );
          digitalWrite( OUTL2, LOW );
        }
        break;
      case 2:
        Serial.println("back----" );
        if ( type == 'M' ) {
          digitalWrite( OUTR1, LOW );
          digitalWrite( OUTR2, HIGH );
        } else {
          digitalWrite( OUTL1, LOW );
          digitalWrite( OUTL2, HIGH );
        }
        break;
    }
  }
}

このスケッチは、モーターを2個使ったものですが、8,9 ピンを交互に LOW/HIGH してやれば反転します。両方 HIGH にするとブレーキがかかる状態ですが、ここでは制御していません。ここの digitalWrite 関数のところを、analogWrite 関数を使ってやれば、モーターの回転数を制御できます。ただし、マブチモーターぐらいだと、高速/中速/低速ぐらいしかできないだろうから(回転数が分からんし、あとはギアで変えてしまうし)Nゲージを動かすとか、プラレールを動かすとかぐらいならば、前後進だけでいいような気がします。これは、実際に Trinket mini を使って試す予定。

埋め込み画像への固定リンク

でもって netduino で試してみよう

Netduino、知ってますか? – Build Insider で連載が開始したようなので、Netduino でもやってみます。コードは、こんな感じ。Bluetooth にはつなげずに、単純に 8,9 ピンを使って正反転を繰り返しているだけです。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
public class Program
{
    public static void Main()
    {
        // write your code here
        new Program().main();
 
    }
    public void main()
    {
        OutputPort pin8 = new OutputPort(Pins.GPIO_PIN_D8, false);
        OutputPort pin9 = new OutputPort(Pins.GPIO_PIN_D9, false);
        Thread.Sleep(1000);
        new Thread(() =>
        {
            while (true)
            {
                // 正転
                Debug.Print("motor forward");
                pin8.Write(true);
                pin9.Write(false);
                Thread.Sleep(3000);
                // 停止
                Debug.Print("motor stop");
                pin8.Write(false);
                pin9.Write(false);
                Thread.Sleep(1000);
                // 反転
                Debug.Print("motor back");
                pin8.Write(false);
                pin9.Write(true);
                Thread.Sleep(3000);
                // 停止
                Debug.Print("motor stop");
                pin8.Write(false);
                pin9.Write(false);
                Thread.Sleep(1000);
            }
 
        }).Start();
        Thread.Sleep(Timeout.Infinite);
    }
}

このくらいの制御だと、Arduino も Netduino も変わらないのですが、結構複雑な処理をするときには、Netduino のほうがやり易いかなと思ってます。が、Netduino の認知度が低いので、Arduino のほうがハック的なライブラリがたくさんあって、そういう点では Netduino で進めるのは結構大変なんですよね。ただし、ライブラリは結構揃っているようなので(I2C制御を苦戦している感じなので、それぐらいの習熟度ですが)それなりに組みやすいはずです。ちなみに、2年前に fez spider を知った頃にデバイスドライバーズさんに聞いたのですが、Netduino 系のは結構クロック数が早いので、他の組み込みのようにリアルタイムによるセンサー受信も可能だそうです。.NET だとガベージコレクションだとか、アセンブリで書くより遅いのでは?とおもわれるかもしれませんが(私もそう思っていました)センサーのデータ受信をできる程度にはうまく動くてくれるそうです。このあたりも、Arduino, Netduino で試してみたいところです。

埋め込み画像への固定リンク

カテゴリー: Arduino, Netduino パーマリンク