Ganponブログ

趣味の模型作り、ドライブ、旅行など
since Mar.2017

ArduinoでRC可動戦車(4)

2018-10-30 13:28:08 | Arduino

2018-10-29
砲撃時のリコイルアクション+LED点灯、銃撃時のLED点滅(5回)の機能を追加しました。
残念ながら、現在のシステムでは出力ピンの空きは3から9までの7個です。
DCモータ1個に+、-、PWMの3個が2セットで6個と、LEDに1個で残りゼロです。

砲塔旋回、砲身上下などの機能を追加するにはどうするか?

Arduino PS3 Bluetooth controlled tank ver.2

【使用パーツ】
1.Aruduino UNO R3(ELEGOO)
2.USBホストシールド 2.0 for Arduino(互換品)
3.KKHMF デュアル・モータードライバ モジュール TB6612FNG
4.DD昇圧コンバータ(IN:
DC3V / OUT:DC5V):100均モバイルバッテリから移植
 モータドライブ用電源に使用
5.Lipoバッテリ DC3.7V 350mAh(DD昇圧コンバータ用)
6.006Pアルカリ電池(Arduino外部電源用)
7.タミヤ タンク工作基本セット[70108]
8.タミヤ ツインモーターギヤーボックス [70097]
9.タミヤ ユニバーサルプレートセット [70098]

(注意)DC5Vコンバータ出力電流値は0.8A(実測)でした。
    100均のモバイルバッテリのDDコンバータの使用は自己責任です。

【直近の問題点】
1.006Pアルカリ電池はもったいないので、他の電源供給方法を検討したい。
 この電圧が6Vまで下がってくると暴走します。


2018-10-30
009Pアルカリ電池の代替案を実施。
容量不足で使わなかったDDコンバータを使い、同じ3.7VのLipoバッテリからモータ用とは別のコンバータで5Vを作成。
Arduino外部入力(Vin)へ接続します。(実測電流値0.1A以下)
コンバータを分けることで、モータ駆動時のラッシュ電流などで5Vが一瞬低下してArduinoが動作不良するのを回避します。
動作テストの結果も良好なので、この方法で解決です。(100μFコンデンサ実装だけでは回避できない)

 

【ver.2のスケッチ】

/*
  PS3BT_arduino_tank_2dcmotor_TB6612
  モータドライバはTB6612
  サーボモータを動かす Ver.2
*/
#include <PS3BT.h>
#include <usbhub.h>
#ifdef dobogusinclude
#include <spi4teensy3.h>
#endif
const int LED = 3; //砲撃 LED 3ピン
int val = 0;
int pos_y;
int pos_x;
int PWMA = 5; // ← 11  Aモータ PWM 左側モータ
int AIN1 = 4; // ← 9  Aモータ IN1  ( 9ピンはUSBホストシールド使用
int AIN2 = 2; // ← 8  Aモータ IN2
int BIN1 = 8; // ← 7  Bモータ IN1
int BIN2 = 7; // ← 6  Bモータ IN2
int PWMB = 6; // ← 10 Bモータ PWM 右側モータ ( 10ピンはUSBホストシールド使用
int motor_speed;
const int motor_sp1 = 128; //超信地旋回速度
const int motor_sp0 = 255; //超高速
USB Usb;
BTD Btd(&Usb); //そうしたBluetooth Dongleの事例を作成する必要があります
PS3BT PS3(&Btd); //これで事例が作成されます
//PS3BT PS3(&Btd, 0x00, 0x15, 0x83, 0x3D, 0x0A, 0x57);
// これにはBluetoothアドレスも格納されます
// これはスケッチを実行するときにドングルから取得できます
void setup() {
  pinMode(PWMA, OUTPUT);
  pinMode(AIN1, OUTPUT);
  pinMode(AIN2, OUTPUT);
  pinMode(BIN1, OUTPUT);
  pinMode(BIN2, OUTPUT);
  pinMode(PWMB, OUTPUT);
  pinMode(LED, OUTPUT);
  Serial.begin(115200);
  while (!Serial); // Wait for serial port to connect - used on Leonardo, Teensy and other boards with built-in USB CDC serial connection
  if (Usb.Init() == -1) {
    Serial.print(F("\r\nOSC did not start"));
    while (1); //halt
  }
  Serial.print(F("\r\nPS3 Bluetooth Library Started"));
}
void loop() {
  Usb.Task();
  if (PS3.PS3Connected) {
    //スティックの中央は127だけどピタリと止まらないので+-10ほど余裕を持たせる。
    //左スティック上下の値(最上部0、中央127、最下部255)を読み込む
    pos_y = PS3.getAnalogHat(LeftHatY);
    pos_x = PS3.getAnalogHat(LeftHatX);
    //砲撃
    //リコイル
    if (PS3.getButtonClick(R1) ) {
      Serial.println("FIRE");
      digitalWrite(LED, HIGH);
      digitalWrite(AIN1, LOW);
      digitalWrite(AIN2, HIGH);
      analogWrite(PWMA, motor_sp0);
      digitalWrite(BIN1, LOW);
      digitalWrite(BIN2, HIGH);
      analogWrite(PWMB, motor_sp0);
      delay(70);
      digitalWrite(LED, LOW);
      digitalWrite(AIN1, HIGH);
      digitalWrite(AIN2, LOW);
      analogWrite(PWMA, motor_sp1);
      digitalWrite(BIN1, HIGH);
      digitalWrite(BIN2, LOW);
      analogWrite(PWMB, motor_sp1);
      delay(95);
    }
    //銃撃
    if ( PS3.getButtonClick(L1)) {
      for ( int i = 0; i < 5 ; i++) {
        val++;
        Serial.print("L1 : ");
        Serial.println(PS3.getButtonClick(L1));
        Serial.println("DA ");
        Serial.println(val);
        digitalWrite(LED, HIGH);
        delay(50);
        digitalWrite(LED, LOW);
        delay(50);
        Serial.println("");
      }
    }
    //左スティックがセンター付近は停止
    if (pos_x >= 117 && pos_x <= 137 && pos_y >= 117 && pos_y <= 137) {
      analogWrite(PWMA, 0);
      digitalWrite(AIN1, LOW);
      digitalWrite(AIN2, LOW);
      analogWrite(PWMA, 0);
      digitalWrite(BIN1, LOW);
      digitalWrite(BIN2, LOW);
    }
    //前進
    else if (pos_y < 117 && pos_x > 117 && pos_x < 137) {
      //左スティック中央(127)から最上部(0)の値をモーターのスピード0から255に変換
      motor_speed = map(pos_y, 117, 0, 0, 255);
      digitalWrite(AIN1, HIGH);
      digitalWrite(AIN2, LOW);
      analogWrite(PWMA, motor_speed);
      digitalWrite(BIN1, HIGH);
      digitalWrite(BIN2, LOW);
      analogWrite(PWMB, motor_speed);
    }
    //後進
    else if ( pos_y > 137 && pos_x > 117 && pos_x < 137) {
      motor_speed = map(pos_y, 137, 255, 0, 255);
      digitalWrite(AIN1, LOW);
      digitalWrite(AIN2, HIGH);
      analogWrite(PWMA, motor_speed);
      digitalWrite(BIN1, LOW);
      digitalWrite(BIN2, HIGH);
      analogWrite(PWMB, motor_speed);
    }
    //前進右旋回
    else if ( pos_y < 117 && pos_x > 137) {
      motor_speed = map(pos_y, 117, 0, 0, 255);
      digitalWrite(AIN1, HIGH);
      digitalWrite(AIN2, LOW);
      analogWrite(PWMA, motor_speed);
      digitalWrite(BIN1, LOW);
      digitalWrite(BIN2, LOW);
      analogWrite(PWMB, motor_speed);
    }
    //前進左旋回
    else if ( pos_y < 117 && pos_x < 117) {
      motor_speed = map(pos_y, 117, 0, 0, 255);
      digitalWrite(AIN1, LOW);
      digitalWrite(AIN2, LOW);
      analogWrite(PWMA, motor_speed);
      digitalWrite(BIN1, HIGH);
      digitalWrite(BIN2, LOW);
      analogWrite(PWMB, motor_speed);
    }
    //後進右旋回
    else if ( pos_y > 137 && pos_x > 137) {
      motor_speed = map(pos_y, 137, 255, 0, 255);
      digitalWrite(AIN1, LOW);
      digitalWrite(AIN2, HIGH);
      analogWrite(PWMA, motor_speed);
      digitalWrite(BIN1, LOW);
      digitalWrite(BIN2, LOW);
      analogWrite(PWMB, motor_speed);
    }
    //後進左旋回
    else if ( pos_y > 137 && pos_x < 117) {
      motor_speed = map(pos_y, 117, 0, 0, 255);
      digitalWrite(AIN1, LOW);
      digitalWrite(AIN2, LOW);
      analogWrite(PWMA, motor_speed);
      digitalWrite(BIN1, LOW);
      digitalWrite(BIN2, HIGH);
      analogWrite(PWMB, motor_speed);
    }
    //右超信地旋回
    else if ( pos_y > 117 && pos_y < 137 && pos_x > 137) {
      digitalWrite(AIN1, HIGH);
      digitalWrite(AIN2, LOW);
      analogWrite(PWMA, motor_sp1);
      digitalWrite(BIN1, LOW);
      digitalWrite(BIN2, HIGH);
      analogWrite(PWMB, motor_sp1);
    }
    //左超信地旋回
    else if ( pos_y > 117 && pos_y < 137 && pos_x < 117) {
      digitalWrite(AIN1, LOW);
      digitalWrite(AIN2, HIGH);
      analogWrite(PWMA, motor_sp1);
      digitalWrite(BIN1, HIGH);
      digitalWrite(BIN2, LOW);
      analogWrite(PWMB, motor_sp1);
    }
  }
}


 
 

ArduinoでRC可動戦車(3)

2018-10-30 00:59:36 | Arduino
2018-10-27
モータドライバーを従来よく使っていたTB6612に変えます。
こちらの方が電圧降下が少なく、より低い電圧で扱えます。
実装はArduino用ユニバーサル基板を使い、積み重ねます。
入力は3.7V350mAHのLipoバッテリで、100均のモバイルバッテリの中身の昇圧コンバータで5Vを作ります。
 
モータドライブシールドを止めたので、スケッチを書き換えます。
特にUSBホストシールドが9ピンと10ピンを使っているので、競合しない様に他のピンに振り替えます。
この競合の事は知らなかったのですが、基板組立後の動作確認時に誤動作を繰り返すことから判りました。
 
【変更後のスケッチ】
// PS3BT_arduino_tank_2dcmotor_TB6612
// 空きデジタルPIN2でLEDを点灯/消灯
//モータドライバはTB6612
#include <PS3BT.h>
#include <usbhub.h>
#ifdef dobogusinclude
#include <spi4teensy3.h>
#endif
USB Usb;
BTD Btd(&Usb); //そうしたBluetooth Dongleの事例を作成する必要があります
PS3BT PS3(&Btd); //これで事例が作成されます
//PS3BT PS3(&Btd, 0x00, 0x15, 0x83, 0x3D, 0x0A, 0x57);
// これにはBluetoothアドレスも格納されます
// これはスケッチを実行するときにドングルから取得できます
int pos_y;
int pos_x;
int PWMA = 5; // ← 11  Aモータ PWM 左側モータ
int AIN1 = 4; // ← 9  Aモータ IN1  ( 9ピンはUSBホストシールド使用
int AIN2 = 3; // ← 8  Aモータ IN2
int BIN1 = 8; // ← 7  Bモータ IN1
int BIN2 = 7; // ← 6  Bモータ IN2
int PWMB = 6; // ← 10 Bモータ PWM 右側モータ ( 10ピンはUSBホストシールド使用
int motor_speed;
const int motor_sp1 = 128; //超信地旋回速度
const int motor_sp0 = 0; //超低速
const int LED = 2;
int btn;
int i ;
 
void setup() {
  Usb.Init();
  Serial.begin(115200);
  while (!Serial); // シリアルポートが接続するのを待つ
  if (Usb.Init() == -1) {
    Serial.print(F("\r\nOSC did not start"));
    while (1); //halt
  }
  Serial.print(F("\r\nPS3 Bluetooth Library Started"));
  pinMode(PWMA, OUTPUT);
  pinMode(AIN1, OUTPUT);
  pinMode(AIN2, OUTPUT);
  pinMode(BIN1, OUTPUT);
  pinMode(BIN2, OUTPUT);
  pinMode(PWMB, OUTPUT);
  pinMode(LED, OUTPUT);
  // turn on servo
  //servo0.attach(9);
  //servo1.attach(10);
}
void loop() {
  Usb.Task();
  if (PS3.PS3Connected) {
    //スティックの中央は127だけどピタリと止まらないので+-10ほど余裕を持たせる。
    //左スティック上下の値(最上部0、中央127、最下部255)を読み込む
    pos_y = PS3.getAnalogHat(LeftHatY);
    pos_x = PS3.getAnalogHat(LeftHatX);
    pos_rx = PS3.getAnalogHat(RightHatX);
    //LED点灯
    if (PS3.getButtonClick(UP)) {
      digitalWrite(LED, HIGH);
    }
    //LED消灯
    if (PS3.getButtonClick(DOWN)) {
      digitalWrite(LED, LOW);
    }
    //サーボUP
    //    if (PS3.getButtonClick(TRIANGLE)) {
    //      servo0.write(168);
    //      delay(20);
    //    }
    //サーボDOWN
    //    if (PS3.getButtonClick(CROSS)) {
    //      servo0.write(12);
    //      delay(20);
    //    }
    //サーボ右回転
    //    if (pos_rx > 137) {
    //      servo1.write(168);
    //      delay(20);
    //    }
    //サーボ左回転
    //    if (pos_rx < 117 ) {
    //      servo1.write(12);
    //      delay(20);
    //    }
    //左スティックがセンター付近は停止
    if (pos_x >= 117 && pos_x <= 137 && pos_y >= 117 && pos_y <= 137) {
      analogWrite(PWMA, 0);
      digitalWrite(AIN1, LOW);
      digitalWrite(AIN2, LOW);
      analogWrite(PWMA, 0);
      digitalWrite(BIN1, LOW);
      digitalWrite(BIN2, LOW);
    }
    //前進
    else if (pos_y < 117 && pos_x > 117 && pos_x < 137) {
      //左スティック中央(127)から最上部(0)の値をモーターのスピード0から255に変換
      motor_speed = map(pos_y, 117, 0, 0, 255);
      digitalWrite(AIN1, HIGH);
      digitalWrite(AIN2, LOW);
      analogWrite(PWMA, motor_speed);
      digitalWrite(BIN1, HIGH);
      digitalWrite(BIN2, LOW);
      analogWrite(PWMB, motor_speed);
    }
    //後進
    else if ( pos_y > 137 && pos_x > 117 && pos_x < 137) {
      motor_speed = map(pos_y, 137, 255, 0, 255);
      digitalWrite(AIN1, LOW);
      digitalWrite(AIN2, HIGH);
      analogWrite(PWMA, motor_speed);
      digitalWrite(BIN1, LOW);
      digitalWrite(BIN2, HIGH);
      analogWrite(PWMB, motor_speed);
    }
    //前進右旋回
    else if ( pos_y < 117 && pos_x > 137) {
      motor_speed = map(pos_y, 117, 0, 0, 255);
      digitalWrite(AIN1, HIGH);
      digitalWrite(AIN2, LOW);
      analogWrite(PWMA, motor_speed);
      digitalWrite(BIN1, LOW);
      digitalWrite(BIN2, LOW);
      analogWrite(PWMB, motor_speed);
    }
    //前進左旋回
    else if ( pos_y < 117 && pos_x < 117) {
      motor_speed = map(pos_y, 117, 0, 0, 255);
      digitalWrite(AIN1, LOW);
      digitalWrite(AIN2, LOW);
      analogWrite(PWMA, motor_speed);
      digitalWrite(BIN1, HIGH);
      digitalWrite(BIN2, LOW);
      analogWrite(PWMB, motor_speed);
    }
    //後進右旋回
    else if ( pos_y > 137 && pos_x > 137) {
      motor_speed = map(pos_y, 137, 255, 0, 255);
      digitalWrite(AIN1, LOW);
      digitalWrite(AIN2, HIGH);
      analogWrite(PWMA, motor_speed);
      digitalWrite(BIN1, LOW);
      digitalWrite(BIN2, LOW);
      analogWrite(PWMB, motor_speed);
    }
    //後進左旋回
    else if ( pos_y > 137 && pos_x < 117) {
      motor_speed = map(pos_y, 117, 0, 0, 255);
      digitalWrite(AIN1, LOW);
      digitalWrite(AIN2, LOW);
      analogWrite(PWMA, motor_speed);
      digitalWrite(BIN1, LOW);
      digitalWrite(BIN2, HIGH);
      analogWrite(PWMB, motor_speed);
    }
    //右超信地旋回
    else if ( pos_y > 117 && pos_y < 137 && pos_x > 137) {
      digitalWrite(AIN1, HIGH);
      digitalWrite(AIN2, LOW);
      analogWrite(PWMA, motor_sp1);
      digitalWrite(BIN1, LOW);
      digitalWrite(BIN2, HIGH);
      analogWrite(PWMB, motor_sp1);
    }
    //左超信地旋回
    else if ( pos_y > 117 && pos_y < 137 && pos_x < 117) {
      digitalWrite(AIN1, LOW);
      digitalWrite(AIN2, HIGH);
      analogWrite(PWMA, motor_sp1);
      digitalWrite(BIN1, HIGH);
      digitalWrite(BIN2, LOW);
      analogWrite(PWMB, motor_sp1);
    }
  }
}