第12回

・モータドライバ

ロボットを動かすにはモータを動かす必要があります。でも、マイコンのピンに直接モータをつなげるわけにはいきません。というのは、マイコンから出せる電流量は最大で40mAであるのに対し、皆さんがよく使うギヤボックスのモータ(260モータ)は最大で1.5Aとか流れるので、そんな事をやってしまうとマイコンが死んでしまいます。
そこで、登場するのが、モータドライバです。モータドライバとは、その名の通り、モータを動かす回路のことです。これを使うことで、マイコンからの少ない電流でモータを回すことができます。
ただ、モータドライバとは、モータを動かす回路の総称であり、その仕組みにはいろいろあります。
おおまかな構造としては、一般的にはHブリッジ回路の構造をしています。
みんなHブリッジを覚えてるかな?リモコン講座のときにやったはず!まぁ以下の回路だよね
ロボットを動かす上でモータが一方向にしか回転できないのは不便なので、正転・逆転ができるHブリッジが使われますが、実際、モータドライバを作る際には、上記のHブリッジのスイッチ部分をリレーやFETなどに置き換えて作ります。

ただ、FETなどを使おうと思うと、回路設計をしなくてはいけません。そんなの面倒だという人のためにモータドライバicというものを紹介します。これは何かというと、モータを動かすための回路が内臓されている電子パーツで、秋月などに売っています。
モータドライバicにもいろいろな型番のものがありますが、今回はTA7291Pを紹介します。(秋月で2個入り300円で売っています)
http://akizukidenshi.com/catalog/g/gI-02001/
これの使い方を説明するので、このicのデータシートを見てみましょう。
TA7291Pのピン番号は左から1~10となっていて、その説明は上記の端子説明の通りです。(Pタイプを見てね)
ロジック側電源端子と出力側電源端子は電池ボックスのプラスに、GNDは電池ボックスのマイナスに、出力端子はモータ端子につないでください。
また、2つの入力端子はマイコンのピンにつなぎ、電圧を操作することでモータの回転方向を制御できます。その仕様はファンクションを見てください。
残った制御電源端子は、そのピンにかかる電圧の大小によって回転速度を制御できるので、速度制御をしたければマイコンのピンにつなぎPWMで電圧制御をし、一定速度でよければ電池ボックスのプラスにつないでください。
しかし、注意してほしいことあるので、まず最大絶対定格(この条件はちょっとでも超えちゃだめだゾ☆)を見てください。
ロジック側電源電圧、出力側電源電圧、制御電源電圧は25V以下にしてください。
また、260モータだとストールすると電流が2.5Aぐらい流れるので、モータはストールさせないようにしてください。
そのほかには最大絶対定格には書いていませんが、制御側電源電圧は出力電源電圧より小さくしてください。


・オープンコレクタとCMOS

センサの出力端子の種類としてオープンコレクタとCMOSがあります。どちらもデジタル出力(0か1)ですが、それぞれの特徴を覚えておきましょう。
  • オープンコレクタ
センサの出力端子がトランジスタのコレクタになっているものを指します。これは使うときに注意しなければならない事があります。というのは、ベース・エミッタ間に電流が流れている時出力端はGNDにつながりますが、流れていない時は出力端は電位的に浮いてしまいます。なので、出力端はプルアップ抵抗をつなげるようにしてください
そして、これはプルアップの特徴を覚えている人ならわかるかもしれないですが、ドレインの電位がLの時は出力端はHになるので、信号は反転してしまいます。
また、出力端がFETのドレインになっている場合もあり、この場合はオープンドレインと呼びます。
  • CMOS
センサの出力端がPchFETとNchFETで構成されているものを指します。これは信号がLの時はPchFETを通って出力端はHになり、信号がHの時はNchFETを通って出力端はLになります。つまり、オープンコレクタと同様に信号は反転します。
特徴としては、CMOS出力の部品は素子を二つ使っているため高価になりがちですが、HighとLowがはっきりと出力される(曖昧な判定をする幅が狭い)点や、信号の切り替えが高速である点など、基本的に優れています。また、外部に回路を加える必要もありません。

参考までに,B0,B1に左モータドライバ,B2,B3に右モータドライバICのIN1,IN2をつなぎ,
シリアル通信で差動二輪車を動かすプログラムです.
teratarmで通信します.
wで前進,sで後退,aで左折,dで右折,それ以外で停止します.

#include <avr/io.h>
#define F_CPU 1000000
#include <util/delay.h>
#include <avr/interrupt.h>

#define FORWARD 'w'
#define BACKWARD 's'
#define TURN_R 'd'
#define TURN_L 'a'

void port_init(void);
void serial_init(void);

void forward(void);
void backward(void);
void turn_R(void);
void turn_L(void);
void stop(void);

enum data_stat
{
	UNREAD, ALREADY_READ
};

volatile uint8_t serial_data = 0;
volatile data_stat serial_data_stat = ALREADY_READ;

ISR(USART_RX_vect)
{
	serial_data = UDR0;
	serial_data_stat = UNREAD;
}

int main(void)
{
	uint8_t command;
	
	port_init();
	serial_init();
	sei();
	
	while(1)
	{
		if(serial_data_stat == UNREAD)
		{
			command = serial_data;
			serial_data_stat = ALREADY_READ;
			if(command == FORWARD)
			{
				forward();
			}
			else if(command == BACKWARD)
			{
				backward();
			}
			else if(command == TURN_R)
			{
				turn_R();
			}
			else if(command == TURN_L)
			{
				turn_L();
			}
			else
			{
				stop();
			}
		}
	}
}

void port_init(void)
{
	DDRB = 0b00001111;
}

void serial_init(void)
{
	UBRR0 = 12 ;//1MHz4800bps.倍速で9600bps
	UCSR0A = 0b00000010;//倍速モード許可 1対1通信 
	UCSR0B = 0b10011000;//受信完了割り込み有効、送受信機起動許可
	UCSR0C = 0b00000110;//非同期動作、パリティなし、ストップ1ビット、データ8ビット
}

void forward(void)
{
	PORTB = 0b00001010;
}
void backward(void)
{
	PORTB = 0b00000101;
}
void turn_R(void)
{
	PORTB = 0b00000010;
}
void turn_L(void)
{ 
	PORTB = 0b00001000;
}
void stop(void)
{
	PORTB = 0b00000000;
}
最終更新:2017年09月25日 19:11