目次
前
次
モーターを回す
書籍の付録には、DCモータがひとつ入っていました。
DCモータを回すためのドライブ回路が紹介されています。
ドライブ回路は、パワートランジスタのコレクタにモータの
片側を接続し、もう一方は電源に接続。
DCモータ内部のブラシで発生するノイズ低減にキャパシタを
入れ、逆起電力でパワートランジスタが破損することを防ぐ
ためのフライホィールダイオードが入っています。
ドライブ回路は、電源からモータに電力を与えることですが
マイコンの出力ピンから流せる電流は1mA程度で、モータが
必要とする電流(最大500mAくらい)には、ほど遠いために
電流増幅の目的で、トランジスタを使っています。
電源電圧を5Vとすると、500mA流すと2500mWくらいになり
ますが、回ってしまえば10mA程度になるので1Aくらいの
電流を流せるパワートランジスタを利用します。
ボタンを押したときだけ、モータが回転するという
システムを実現する回路は、以下。
LEDは、スイッチを押していることとモータを回転して
いることのモニタに使っています。
ポートBの各ビットは、次のように利用。
- RB0 (input) push button
- RB1 (output) LED
- RB2 (output) motor driver
I/Oの設定は、次のコードでよいでしょう。
TRISB = 0x01 ; /* 0b00000001 */
スイッチを押したときに、RB0に'0'が印加されるので
LEDが点灯、モータが回転となるには、'1'を出力する
となります。
PORTB.F1 = ~PORTB.F0 ;
PORTB.F2 = ~PORTB.F0 ;
モータを回転させるための制御コードは、以下。
#define OFF 0
#define ON OFF+1
/* prototype */
void usr_init(void);
void main(void)
{
/* initialize PORT */
usr_init();
/* endless loop */
while (ON) {
PORTB.F1 = ~PORTB.F0 ;
PORTB.F2 = ~PORTB.F0 ;
}
}
void usr_init(void)
{
/* turn off LED */
PORTB.F1 = OFF ;
/* stop motor */
PORTB.F2 = OFF ;
/* direction */
TRISB = 0x01 ;
}
これで回すだけはできるようになりました。
モータの回転制御には、PWM(Pulse Width Modulation)を
利用します。
PWMは、モータに与える電力を電流が流れている時間幅で
制御します。
PWMによるモータの回転スピードを制御するシステムは以下。
ポートBの各ビットは、次のように利用。
- RB0 (input) push button
- RB1 (input) push button
- RB2 (output) LED
- RB3 (output) motor driver
PWMに利用する波形生成のための関数を定義して利用します。
typedef unsigned char UBYTE ;
void PWM(UBYTE x)
{
/* turn on LED and rotate motor */
PORTB.F2 = ON ;
PORTB.F3 = ON ;
/* delay */
Vdelay_ms(x);
/* turn off LED and stop motor */
PORTB.F2 = OFF ;
PORTB.F3 = OFF ;
/* delay */
Vdelay_ms(10-x);
}
10msの間で、電流を流している時間を止めている時間を
用意し、PWMの波形を構成します。
片方のボタンを押していると高速、もう一方の
ボタンを押していると低速回転となるように
システムを構成するときのコードは、以下。
#define OFF 0
#define ON OFF+1
#define SWON 0
#define SWOFF SWON+1
#define HS 9
#define LS 1
typedef unsigned char UBYTE ;
/* prototype */
void usr_init(void);
void PWM(UBYTE x);
void main(void)
{
/* initialize PORT */
usr_init();
/* endless loop */
while (ON) {
/* switch 0 */
while ( PORTB.F0 == SWON ) {
PWM(HS);
}
/* switch 1 */
while ( PORTB.F1 == SWON ) {
PWM(LS);
}
}
}
void usr_init(void)
{
/* turn off LED */
PORTB.F2 = OFF ;
/* stop motor */
PORTB.F3 = OFF ;
/* direction */
TRISB = 0x03 ;
}
void PWM(UBYTE x)
{
/* turn on LED and rotate motor */
PORTB.F2 = ON ;
PORTB.F3 = ON ;
/* delay */
Vdelay_ms(x);
/* turn off LED and stop motor */
PORTB.F2 = OFF ;
PORTB.F3 = OFF ;
/* delay */
Vdelay_ms(10-x);
}
高速と低速の回転ではなく、回転と停止にしたい場合
#defineによる値定義を、次のように変更します。
#define HS 8
#define LS 0
プログラム本体ではなく、先頭におかれている数値の
定義を変更するだけで対応できます。
回転スピード制御が可能になったので、回転方向を
変更できるようにします。それにはHブリッジを利用。
Hブリッジ回路を入れたシステムは、以下。
Hブリッジ回路を使うには、電流が流れる方向を決めれば
よいので、左回転、右回転の関数を定義して対応します。
左回転、右回転の関数は、以下。
void motor_left(void)
{
PORTB.F2 = ON ;
PORTB.F3 = OFF ;
}
void motor_right(void)
{
PORTB.F2 = OFF ;
PORTB.F3 = ON ;
}
void motor_stop(void)
{
PORTB.F2 = OFF ;
PORTB.F3 = OFF ;
}
片方のボタンを押していると右回転、もう一方の
ボタンを押していると左回転となるようにコード
を記述すると、以下。
#define OFF 0
#define ON OFF+1
#define SWON 0
#define SWOFF SWON+1
/* prototype */
void usr_init(void);
void motor_left(void);
void motor_right(void);
void motor_stop(void);
void main(void)
{
/* initialize PORT */
usr_init();
/* endless loop */
while (ON) {
motor_stop();
/* switch 0 (left rotate) */
while ( PORTB.F0 == SWON ) {
motor_left();
}
/* switch 1 (right rotate) */
while ( PORTB.F1 == SWON ) {
motor_right();
}
}
}
void usr_init(void)
{
/* turn off LED */
PORTB.F2 = OFF ;
/* stop motor */
PORTB.F3 = OFF ;
/* direction */
TRISB = 0x03 ;
}
void motor_left(void)
{
PORTB.F2 = ON ;
PORTB.F3 = OFF ;
}
void motor_right(void)
{
PORTB.F2 = OFF ;
PORTB.F3 = ON ;
}
void motor_stop(void)
{
PORTB.F2 = OFF ;
PORTB.F3 = OFF ;
}
通常は右回転していて、片方のボタンを押すと停止、
もう一方のボタンを押すると左回転にするにはmain
の中の記述を変えます。
/* endless loop */
while (ON) {
/* right rotate */
motor_right();
/* switch 0 (stop) */
while ( PORTB.F0 == SWON ) {
motor_stop();
}
/* switch 1 (left rotate) */
while ( PORTB.F1 == SWON ) {
motor_left();
}
}
ライントレースロボットを動かすような場合、モータの回転
スピードを変えつつ、回転方向も逆にすることが要求されて
きます。
モータを2個以上使う場合、タイマー割込みを利用し
main関数は、処理の交通整理と指示だけにします。
複数のモータを同時に動かすコードは、次ページで説明します。
目次
前
次