IoTサービス「Blynk」を携帯電話にインストールし、これをロボットカーのコントローラにして、小型Wi-Fiモジュール「ESP-8266」で動作するロボットカーを作成します。ロボットカーのシャーシは、タミヤの「ダブルギヤボックス」を使用します。関連するリンクを次に示します。
- ESP8266とモータードライバ「TB6612FNG」とタミヤの「ダブルギヤボックス」を使ったモータ制御
- Raspberry Pi 3にBlynkサーバの構築
- ESP8266のリセット時の各ピンの信号レベルとPWMの設定方法
ロボットカーの構成
作成したロボットカーの画像を次に示します。車体は、タミヤのユニバーサルプレートにダブルギヤボックスを取り付けます。ユニバーサルプレートには電池ホルダーと基板を取り付けます。基板に取り付けた赤基板はモータードライバ「TB6612FNG」で、青基板は小型Wi-Fiモジュール「ESP-8266」です。電池ホルダーは車体の後ろに2段に積み重ね、2種類使用しています。ESP-8266用には単三6本(9V)を降圧して3.3Vにし、モータ用には単三4本(6V)を、PWMにより3Vで使用しています。コネクタは、左右の車輪用のモータへの電源、電池からESP-8266用とモータ用で4個のコネクタを基板に取り付けます。オレンジ色のLEDは、コントローラと接続しているかを確かめるために使用します。基板の後ろ端には、スライドスイッチを設けて電源をON/OFFし、基板の中央にあるRSETスイッチによりロボットカーをリセットします。
車体に使用したタミヤの部品については、「ESP8266とモータードライバ「TB6612FNG」とタミヤの「ダブルギヤボックス」を使ったモータ制御」を参照してください。
ESP8266とモータードライバ「TB6612FNG」のモーターを制御する信号ピン6本は、次にように接続します。
| ESP8266 | TB6612FNG |
|---|---|
| 3.3V | VCC |
| GND | GND(2か所) |
| IO2 | PWMA |
| IO13 | AIN1 |
| IO15 | AIN2 |
| IO5 | PWMB |
| IO4 | BIN2 |
| IO14 | BIN1 |
| IO12 | STBY |
1. STBYへの信号は、ESP-8266をリセットするとアクティブになりロボットカーが暴走するので、トランジスタ(2SA1015)を使って極性を反対にします。詳細については「ESP8266のリセット時の各ピンの信号レベルとPWMの設定方法」を参照してください。
2. VCCへは、単三電池9VをDC/DCコンバータ(AMS1117-3.3モジュール)で3.3Vに降圧して供給します。電池の容量が少ないと、モーターを動かすときにESP-8266がリセットが頻発します(4本ではダメ)。
次に左右のモーターからのケーブルとモータードライバー「TB6612FNG」の出力ピンは、次のように接続します。
| モーター | TB6612FNG |
|---|---|
| 5V | VM |
| 左モーター黒ケーブル | AOUT1 |
| 左モーター赤ケーブル | AOUT2 |
| 右モーター赤ケーブル | BOUT1 |
| 右モーター黒ケーブル | BOUT2 |
その他にLEDをIO16に接続し、リセットボタンをResetに接続します。
Blynkによるコントローラの作成
AQUOS PAD「SH-08E」でBlynkを起動し、LEDとジョイスティックのWidgetを次のように配置します。なお、Blynkのインストールおよび設定については、「Raspberry Pi 3にBlynkサーバの構築」に示します。
ジョイスティックは次のように設定し、ジョイスティックの動きにより、エンコードされたx/yデータが-100から100の値をとるように設定します。
ESP-8266のプログラム
「ESP8266とモータードライバ「TB6612FNG」とタミヤの「ダブルギヤボックス」を使ったモータ制御」で作成したESP-8266のプログラムに、Blynkから渡されるジョイスティックデータに従いモータを制御する機能を追加します。Blynkのジョイスティックを前方に動かすと前進し、後方に動かすと後進し、右に動かすと右折し、左に動かすと左折、ジョイスティックを動かさないと停止します。曲がり方は、右上にすると前進右折となり、右下にすると後進右折等となります。ジョイスティックの動きが中心から小さいと無効のデータとして捨てられます。
carrobot.ino
// TB6612FNG
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#define INVALID 30 // 無効エリア
#define SPEED 60
// Set Blynk Auth Token and WiFi credentials.
const char *auth = "xxxx";
const char *ssid = "xxxx";
const char *pass = "xxxx";
// DRV8835
// GPIO
#define AIN1 13 // Right Motor Blue
#define AIN2 15 // Right Motor Yellow
#define PWMA 2
#define BIN1 14 // Left Motor Yellow
#define BIN2 5 // Left Motor Blue
#define PWMB 4
#define STBY 12
// PWN
#define PWN_FREQ 1000 // PWM frequency: 1000Hz(1kHz)
#define PWN_RANGE 100 // PWN range: 100
// Joystick x axis, y axis
BLYNK_WRITE(V1) {
int x = param[0].asInt(); // Joystick x axis
int y = param[1].asInt(); // Joystick y axis
// Serial.print("x:");
// Serial.println(x);
// Serial.print("y:");
// Serial.println(y);
if ((x == 0) && (y == 0)) {
// 停止
digitalWrite(AIN1, HIGH);
digitalWrite(AIN2, LOW);
analogWrite(PWMA, 0);
digitalWrite(BIN1, HIGH);
digitalWrite(BIN2, LOW);
analogWrite(PWMB, 0);
// Serial.println("Stop");
}
else if ((abs(x) < INVALID) && (abs(y) < INVALID)) {
// 無効エリア
// Serial.println("Invalid Area");
}
else if ((y > 0) && (x > INVALID)) {
// 前進右回り
digitalWrite(AIN1, LOW);
digitalWrite(AIN2, HIGH);
analogWrite(PWMA, SPEED);
digitalWrite(BIN1, LOW);
digitalWrite(BIN2, HIGH);
analogWrite(PWMB, SPEED/2);
// Serial.println("Forward Right");
}
else if ((y > 0) && (x < -INVALID)) {
// 前進左回り
digitalWrite(AIN1, LOW);
digitalWrite(AIN2, HIGH);
analogWrite(PWMA, SPEED/2);
digitalWrite(BIN1, LOW);
digitalWrite(BIN2, HIGH);
analogWrite(PWMB, SPEED);
// Serial.println("Forward Left");
}
else if ((y < 0) && (x > INVALID)) {
// 後進右回り
digitalWrite(AIN1, HIGH);
digitalWrite(AIN2, LOW);
analogWrite(PWMA, SPEED);
digitalWrite(BIN1, HIGH);
digitalWrite(BIN2, LOW);
analogWrite(PWMB, SPEED/2);
// Serial.println("Back Right");
}
else if ((y < 0) && (x < -INVALID)) {
// 後進左回り
digitalWrite(AIN1, HIGH);
digitalWrite(AIN2, LOW);
analogWrite(PWMA, SPEED/2);
digitalWrite(BIN1, HIGH);
digitalWrite(BIN2, LOW);
analogWrite(PWMB, SPEED);
// Serial.println("Back Left");
}
else if (y > 0) {
// 前進
digitalWrite(AIN1, LOW);
digitalWrite(AIN2, HIGH);
analogWrite(PWMA, SPEED);
digitalWrite(BIN1, LOW);
digitalWrite(BIN2, HIGH);
analogWrite(PWMB, SPEED);
// Serial.println("Forward");
}
else if (y < 0) {
// 後進
digitalWrite(AIN1, HIGH);
digitalWrite(AIN2, LOW);
analogWrite(PWMA, SPEED);
digitalWrite(BIN1, HIGH);
digitalWrite(BIN2, LOW);
analogWrite(PWMB, SPEED);
// Serial.println("Back");
}
digitalWrite(STBY, LOW);
}
void setup() {
delay(10);
// Serial.begin(9600);
// Serial.println("start!");
// Initialize GPIO mode
pinMode(AIN1, OUTPUT);
pinMode(AIN2, OUTPUT);
pinMode(BIN1, OUTPUT);
pinMode(BIN2, OUTPUT);
pinMode(STBY, OUTPUT);
// Initialize PWN
analogWriteFreq(PWN_FREQ);
analogWriteRange(PWN_RANGE);
digitalWrite(STBY, HIGH);
digitalWrite(AIN1, LOW);
digitalWrite(AIN2, LOW);
analogWrite(PWMA, 0);
digitalWrite(BIN1, LOW);
digitalWrite(BIN2, LOW);
analogWrite(PWMB, 0);
// Connect WiFi and Blynk cloud server
Blynk.begin(auth, ssid, pass);
}
void loop() {
Blynk.run();
delay(3);
}
ロボットカーの走行
基板のスライドスイッチをオンにすると、DC/DCコンバータのLEDが点灯し、DC/DCコンバータが電池から入力した9Vを3.3Vに変換し、ESP-8266の電源に供給します。同時に、モーターの電源として電池から4.5VがTB6612FNGに供給されます。Blynkを起動し、LEDのボタンを押すと、基板上のLEDが点滅します。Blynkのジョイスティックを回すと、ジョイスティックの動きに応じてロボットカーが走行します。



