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のジョイスティックを回すと、ジョイスティックの動きに応じてロボットカーが走行します。