前回の記事では、WeMos D1 miniとMotor Shieldを使ってキャタピラ車のモーターを制御してみました。Motor ShieldはI2Cインターフェース対応で制御用にピンを2つしか消費しないエコな作りになっている上に、用意されているライブラリを使って非常に簡単にモーターを制御することができます。
しかーし、いかんせん、日本で売ってなくて入手の敷居が高いという問題がありました。
そこで、日本で入手可能な部品で作るとどうなるか試してみることにしました。
ブレッドボード版キャタピラ車
代わりに使ったもの
WeMos D1 miniとMotor Shieldの代わりに、ブレッドボードで作った回路に使用した部品のリストです。
- TB6612使用 Dual DCモータードライブキット
秋月電子 ¥350(税込) - ESP-WROOM-02開発ボード
秋月電子 ¥1,280(税込) - 低損失レギュレーター 3.3V2A PQ3RD23(2個入)
秋月電子 ¥100(税込) - 電源用マイクロUSBコネクタDIP化キット
秋月電子 ¥130(税込) - ブレッドボード BB-801
秋月電子 ¥200(税込) - 電解コンデンサ 16V 47μF
千石電商 ¥11(税込) - セラミックコンデンサ 50V 0.1μF
千石電商 ¥18(税込) - ジャンパーワイヤ 16本
今回メインの「TB6612使用 Dual DCモータードライブキット」はMotor Shieldと同じTB6612を使用していて、ブレッドボードで使えるように基板に半田付けされています。
また、今回は電源を1つに統合しました。モーター用に単三電池2本、WeMos D1 mini用にモバイルバッテリーを使用してたのを、レギュレーターを使ってモーターとESP8266の両方に電源を供給することで、モバイルバッテリーだけで動作するようにしました。
※2017/12/28追記
ダイソーで300円で買えるモバイルバッテリーは過電流保護回路が付いているらしく、1電源で使用していると電流供給がストップすることが多々あります。このモバイルバッテリーの仕様は1Aとなっているので、2A程度の電流供給能力のあるモバイルバッテリーであれば1電源で使えると思います。
また、秋月電子のESP-WROOM-02開発ボードは、ハズレを引くと外部電源での動作が安定しなくなります。FAQ参照。FAQにはTXDをプルアップするとありますが、この対処を行ってもスケッチが動作しないことが多々ありました。
実写回路
ブレッドボード配線図
配線表
テストコース試走映像
スマホのBlynk Joystick操作はクラウドサーバー経由でESP8266に届きますが、動作は非常にスムーズです。Motor Shieldの時は反応が悪かったので原因を探ってみたら、Motor Shieldのライブラリに記述されていたdelay(100);
が原因でした。
スケッチ
TB6612の真理値表
TB6612の真理値表に従って、TB6612の入力端子に繋がっているESP8266のGPIOを制御すればモーターを動かすことができますが、前回WeMos Motor Shield用のスケッチ作りましたので、それを活かせるようにMotor Shieldライブラリのクラスと同じ仕様のクラスにTB6612のGPIO制御を書いてみました。
BlynkTankスケッチの#include <WEMOS_Motor.h>
を#include "TB6612_Motor.h"
に変更して、次の2つのファイルをBlynkTankスケッチフォルダに保存すれば動作します。
TB6612_Motor.h
/*
* TB6612_Motor.h
* October 24, 2017
* By Hiroyuki ITO
* http://intellectualcuriosity.hatenablog.com/
* MIT Licensed.
*
* This file was created with reference to "WEMOS_Motor.h".
* Thanks to WEMOS Electronics for publishing a great library.
*
*/
#define _MOTOR_A 0
#define _MOTOR_B 1
#define _SHORT_BRAKE 0
#define _CCW 1
#define _CW 2
#define _STOP 3
#define _STANDBY 4
class Motor {
public:
Motor(uint8_t address, uint8_t motor, uint32_t freq);
void setmotor(uint8_t dir, uint8_t pwm_val);
void setmotor(uint8_t dir);
private:
uint8_t _motor;
};
TB6612_Motor.ino
/*
* TB6612_Motor.ino
* October 24, 2017
* By Hiroyuki ITO
* http://intellectualcuriosity.hatenablog.com/
* MIT Licensed.
*
* This file was created with reference to "WEMOS_Motor.cpp".
* Thanks to WEMOS Electronics for publishing a great library.
*
*/
// GPIO Define
#define PIN_AIN1 12
#define PIN_AIN2 13
#define PIN_PWMA 14
#define PIN_BIN1 15
#define PIN_BIN2 4
#define PIN_PWMB 5
#define PIN_STBY 2
/*
* Motor()
* address:
* DUMMY
* freq:
* PWM's frequency
*/
Motor::Motor(uint8_t address, uint8_t motor, uint32_t freq) {
_motor = motor;
pinMode(PIN_STBY, OUTPUT);
digitalWrite(PIN_STBY, LOW);
pinMode(PIN_AIN1, OUTPUT);
pinMode(PIN_AIN2, OUTPUT);
pinMode(PIN_PWMA, OUTPUT);
pinMode(PIN_BIN1, OUTPUT);
pinMode(PIN_BIN2, OUTPUT);
pinMode(PIN_PWMB, OUTPUT);
analogWriteFreq(freq);
analogWriteRange(100);
}
/*
* setmotor() -- set motor
* dir:
* _SHORT_BRAKE 0
* _CCW 1
* _CW 2
* _STOP 3
* _STANDBY 4
* pwm_val:
* 0 - 100 (%)
*/
void Motor::setmotor(uint8_t dir, uint8_t pwm_val) {
if (_motor == _MOTOR_A) {
switch (dir) {
case _SHORT_BRAKE :
digitalWrite(PIN_AIN1, HIGH);
digitalWrite(PIN_AIN2, HIGH);
break;
case _CCW :
digitalWrite(PIN_AIN1, LOW);
digitalWrite(PIN_AIN2, HIGH);
digitalWrite(PIN_STBY, HIGH);
break;
case _CW :
digitalWrite(PIN_AIN1, HIGH);
digitalWrite(PIN_AIN2, LOW);
digitalWrite(PIN_STBY, HIGH);
break;
case _STOP :
digitalWrite(PIN_AIN1, LOW);
digitalWrite(PIN_AIN2, LOW);
break;
case _STANDBY :
digitalWrite(PIN_STBY, LOW);
break;
}
analogWrite(PIN_PWMA, pwm_val);
} else {
switch (dir) {
case _SHORT_BRAKE :
digitalWrite(PIN_BIN1, HIGH);
digitalWrite(PIN_BIN2, HIGH);
break;
case _CCW :
digitalWrite(PIN_BIN1, LOW);
digitalWrite(PIN_BIN2, HIGH);
digitalWrite(PIN_STBY, HIGH);
break;
case _CW :
digitalWrite(PIN_BIN1, HIGH);
digitalWrite(PIN_BIN2, LOW);
digitalWrite(PIN_STBY, HIGH);
break;
case _STOP :
digitalWrite(PIN_BIN1, LOW);
digitalWrite(PIN_BIN2, LOW);
break;
case _STANDBY :
digitalWrite(PIN_STBY, LOW);
break;
}
analogWrite(PIN_PWMB, pwm_val);
}
}
void Motor::setmotor(uint8_t dir) {
setmotor(dir, 100);
}
おわり