Ganponブログ

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

RC可動化 1/35 ドラゴン T34/85 スケッチ&回路(更新)

2024-09-12 22:33:11 | 1/35 ドラゴン T-34/85
リクエストが有りましたので、T34のスケッチと回路図を公開します。
久しぶりにT34を動かしてみて、気になるところを変更して動作を確認しました。
▼先日のスケッチに手を入れ変更後のスケッチを公開します。
2024-09-12 更新 IRremote Ver.2.2.3より2.8.0の方が安定しています。
メモリー容量ギリギリなのでIDEやライブラリのバージョンを調整しました。


 
  1. /* PS3BT_arduino_NANO_tank_TB6612_IRw_MP3_T34spec3c
  2.   2024-09-11
  3.   砲塔旋回サーボ停止追加 detach()
  4.   モータドライバはTB6612
  5.   砲撃時のリコイルアクション
  6.   irremote PIN3 赤外線発光(砲撃)システム
  7.   A0ピンに赤外線受光モジュール出力を接続し、被弾処理を追加
  8.   主砲発光はミニUSBシールドのGPOUTピン0を使用
  9.   機銃主砲発光はミニUSBシールドのGPOUTピン1を使用
  10.   ヘッドライトはミニUSBシールドのGPOUTピン2を使用
  11.   MP3プレーヤーで効果音を発生

  12.   開発環境
  13.   Arduino 1.8.19
  14.   IRremote Ver.2.8.0
  15.   DFRobotDFPlayerMini.h 1.0.5
  16.   USBホストシールド 2.0 1.20

  17.   スケッチが使用できるメモリが少なくなっています。動作が不安定になる可能性があります。
  18.   最大30720バイトのフラッシュメモリのうち、スケッチが30282バイト(98%)を使っています。
  19.   最大2048バイトのRAMのうち、グローバル変数が1626バイト(79%)を使っていて、
  20.   ローカル変数で422バイト使うことができます。
  21.   
  22. */

  23. #include <SoftwareSerial.h>
  24. #include <DFRobotDFPlayerMini.h>
  25. SoftwareSerial mySerial(A2, A3); // DFPlayer TX,RX
  26. DFRobotDFPlayerMini myDFPlayer;

  27. #include <PS3BT.h>
  28. #include <usbhub.h>
  29. #ifdef dobogusinclude
  30. #include <spi4teensy3.h>
  31. #endif
  32. //#include <Usb.h> // needed by Arduino IDE
  33. #include <USB_Host_Shield_GPIO.h> // GPOUTピンで主砲LEDを発光させるため 1.20
  34. MaxGPIO max;

  35. USB Usb;
  36. BTD Btd(&Usb);
  37. PS3BT PS3(&Btd);
  38. //PS3BT PS3(&Btd, 0x00, 0x1B, 0xDC, 0xF2, 0x53, 0xFA); //for Dongke B
  39. /*シリアルモニタにBluetooth DongleのアドレスがSerial.printされる。
  40.   書き出された6個のコードをスケッチを変更し、
  41.   ドングルを指した状態でArduinoに書き込む(電源は切らない)
  42.   ドングルを抜いてUSBケーブルでPS3コントローラを接続する(電源は切らない)
  43.   ケーブルを抜いてドングルを指し直す(Arduinoを再起動する)
  44.   PS3コントローラのPS ボタンを押してペアリングする。
  45. */

  46. #include <IRremote.h>
  47. IRsend irsend;
  48. int RECV_PIN = A0 ; //赤外線受光部をPIN A0に
  49. IRrecv irrecv(RECV_PIN);
  50. decode_results results; //受信信号を格納する
  51. const long sign_hit = 0x4CB0FADD;
  52. int cnt = 0 ;

  53. #include <VarSpeedServo.h>
  54. VarSpeedServo myservo_1;
  55. VarSpeedServo myservo_2;
  56. int servo_1pos = 75;
  57. const int servo1_sp = 20;
  58. const int servo2_sp = 5;
  59. int ch = 0;
  60. int pos_y;
  61. int pos_x;
  62. int pos_ry;
  63. int pos_rx;
  64. int PWMA = 5; // Aモータ PWM 左側モータ
  65. int AIN1 = 4; // Aモータ IN1 ( 9ピンはUSBホストシールド使用
  66. int AIN2 = 2; // Aモータ IN2
  67. int BIN1 = 8; // Bモータ IN1
  68. int BIN2 = 7; // Bモータ IN2
  69. int PWMB = 6; // Bモータ PWM 右側モータ( 10ピンはUSBホストシールド使用

  70. int motor_speed;
  71. int steering;
  72. const int LED_3 = A1 ; //ブレーキランプ

  73. void setup() {
  74.   irrecv.enableIRIn(); // Start the receiver
  75.   pinMode(RECV_PIN, INPUT) ; // 赤外線受信モジュールに接続ピンをデジタル入力に設定
  76.   pinMode(PWMA, OUTPUT);
  77.   pinMode(AIN1, OUTPUT);
  78.   pinMode(AIN2, OUTPUT);
  79.   pinMode(BIN1, OUTPUT);
  80.   pinMode(BIN2, OUTPUT);
  81.   pinMode(PWMB, OUTPUT);
  82.   pinMode(LED_3, OUTPUT);
  83.   pinMode(A4, OUTPUT);
  84.   pinMode(A5, OUTPUT);
  85.   myservo_1.attach(A4); //servo1 砲身上下
  86.   myservo_1.write(servo_1pos);
  87.   myservo_1.detach();
  88.   myservo_2.attach(A5); //servo2 砲塔旋回
  89.   myservo_2.write(90);

  90.   Serial.begin (115200);
  91.   mySerial.begin (9600);
  92.   myDFPlayer.begin(mySerial);
  93.   myDFPlayer.volume(20); //Set volume value (0~30)

  94.   while (!Serial); // Wait for serial port to connect - used on Leonardo, Teensy and other boards with built-in USB CDC serial connection
  95.   if (Usb.Init() == -1) {
  96.     Serial.print(F("\r\nOSC did not start"));
  97.     while (1); //halt
  98.   }
  99.   Serial.print(F("\r\nPS3 Bluetooth Library Started"));
  100. }

  101. void loop() {
  102.   Usb.Task();
  103.   if (PS3.PS3Connected) {
  104.     if (irrecv.decode(&results)) { // 受信コードの値が
  105.       if (results.value == sign_hit) { // 0x4CB0FADDだったら被弾
  106.         Hit();
  107.       }
  108.       irrecv.resume();
  109.     }

  110.     //砲身 UP/DOWN
  111.     if ( PS3.getButtonClick(R3)) { //CENTER
  112.       myservo_1.attach(A4);
  113.       myservo_1.write(servo_1pos, servo1_sp, true);
  114.       // myservo_1.detach();
  115.     }
  116.     pos_ry = PS3.getAnalogHat(RightHatY);
  117.     if (pos_ry < 10) { // UP
  118.       myservo_1.attach(A4);
  119.       myservo_1.write(servo_1pos - 30, servo1_sp, true);
  120.       // myservo_1.detach();
  121.     } else if (pos_ry > 245) { //DOWN
  122.       myservo_1.attach(A4);
  123.       myservo_1.write(servo_1pos + 30, servo1_sp, true);
  124.       // myservo_1.detach();
  125.     } else { //停止
  126.       myservo_1.detach();
  127.     }

  128.     //砲塔旋回
  129.     if ( PS3.getAnalogHat(LeftHatX) > 230) { //右旋回
  130.       myservo_2.attach(A5);
  131.       myservo_2.write(100, servo2_sp);
  132.     } else if (PS3.getAnalogHat(LeftHatX) < 26) { //左旋回
  133.       myservo_2.attach(A5);
  134.       myservo_2.write(80, servo2_sp);
  135.     } else { //停止
  136.       //myservo_2.attach(A5);
  137.       myservo_2.write(90, 255, true);
  138.       myservo_2.detach();
  139.     }

  140.     //砲撃 + リコイル
  141.     if (PS3.getButtonClick(R1) && ch == 0 ) {
  142.       int khz = 38; // 38kHz carrier frequency for the NEC protocol
  143.       unsigned int irSignal[] = {4100, 1000, 2000, 2050, 1000}; // vs BATTLE TANK jr T-72 40MHz
  144.       // AnalysIR Batch Export (IRremote) - RAW
  145.       irsend.sendRaw(irSignal, (sizeof(irSignal) / sizeof(irSignal[0])), khz);
  146.       //irsend.sendRaw(data buf, length, hertz)
  147.       irrecv.enableIRIn(); // 受信を再開する  
  148.       max.write(0, HIGH); //主砲発光
  149.       myDFPlayer.play(15);

  150.       delay(200);
  151.       motor_run(128, 0, 1, 128, 0, 1, 1);
  152.       ch = 5000; //約2秒間は砲撃不可
  153.       delay(100);
  154.       motor_run(0, 0, 0, 0, 0, 0, 1);
  155.       delay(200);
  156.       max.write(0, LOW);
  157.       motor_run(64, 1, 0, 64, 1, 0, 1);
  158.       delay(260);
  159.     } else {
  160.       if (ch > 0) {
  161.         ch--;
  162.       }
  163.     }

  164.     //銃撃
  165.     if ( PS3.getButtonClick(L1)) {
  166.       //mp3_play (10);
  167.       myDFPlayer.play(10);
  168.       delay(200);
  169.       for ( int i = 0; i < 5 ; i++) {
  170.         max.write(1, HIGH);
  171.         delay(100);
  172.         max.write(1, LOW);
  173.         delay(80);
  174.       }
  175.     }

  176.     //ヘッドライト
  177.     if (PS3.getButtonClick(RIGHT)) { //点灯
  178.       max.write(2, HIGH);
  179.     } else if (PS3.getButtonClick(LEFT)) { //消灯
  180.       max.write(2, LOW);
  181.     }

  182.     //走行コントロール
  183.     pos_y = PS3.getAnalogHat(LeftHatY);
  184.     pos_x = PS3.getAnalogHat(RightHatX);

  185.     //前進
  186.     if (pos_y <= 102 && pos_x >= 102 && pos_x <= 152) {
  187.       motor_speed = map(pos_y, 102, 0, 0, 180);
  188.       motor_run(motor_speed, 1, 0, motor_speed, 1, 0, 0);
  189.     }

  190.     //後進
  191.     else if ( pos_y >= 152 && pos_x >= 102 && pos_x <= 152) {
  192.       motor_speed = map(pos_y, 152, 255, 0, 180);
  193.       motor_run(motor_speed, 0, 1, motor_speed, 0, 1, 0);
  194.     }

  195.     //前進右緩旋回、信地旋回
  196.     else if ( pos_y <= 102 && pos_x > 152) {
  197.       motor_speed = map(pos_y, 102, 0, 0, 180);
  198.       steering = motor_speed * (1.00 - (map(pos_x, 152, 255, 0, 255) / 255.00));
  199.       motor_run(motor_speed, 1, 0, steering, 1, 0, 0);
  200.     }

  201.     //前進左旋回、信地旋回
  202.     else if ( pos_y < 102 && pos_x < 102) {
  203.       motor_speed = map(pos_y, 102, 0, 0, 180);
  204.       steering = motor_speed * (1.00 - (map(pos_x, 102, 0, 0, 255) / 255.00));
  205.       motor_run(steering, 1, 0, motor_speed, 1, 0, 0);
  206.     }

  207.     //後進右旋回、信地旋回
  208.     else if ( pos_y > 152 && pos_x > 152) {
  209.       motor_speed = map(pos_y, 152, 255, 0, 180);
  210.       steering = motor_speed * (1.00 - (map(pos_x, 152, 255, 0, 255) / 255.00));
  211.       motor_run(motor_speed, 0, 1, steering, 0, 1, 0);
  212.     }

  213.     //後進左旋回、信地旋回
  214.     else if ( pos_y > 152 && pos_x < 102) {
  215.       motor_speed = map(pos_y, 152, 255, 0, 180);
  216.       steering = motor_speed * (1.00 - (map(pos_x, 102, 0, 0, 255) / 255.00));
  217.       motor_run(steering, 0, 1, motor_speed, 0, 1, 0);
  218.     }

  219.     //右超信地旋回
  220.     else if ( pos_x > 245 && pos_y >= 102 && pos_y <= 152) {
  221.       motor_speed = 90;
  222.       motor_run(motor_speed, 1, 0, motor_speed, 0, 1, 0);
  223.     }

  224.     //左超信地旋回
  225.     else if ( pos_x < 10 && pos_y >= 102 && pos_y <= 152) {
  226.       motor_speed = 90;
  227.       motor_run(motor_speed, 0, 1, motor_speed, 1, 0, 0);
  228.     }

  229.     else { //停止
  230.       motor_run(0, 1, 1, 0, 1, 1, 1);
  231.     }
  232.   }
  233. }


  234. void motor_run(int D0, int D1, int D2, int D3, int D4, int D5, int D6) {
  235.   /* D0 : モータスピード(左)
  236.      D1 : モータA(左)CH1 , D2 : モータA(左)CH2 1 = HIGH / 0 = LOW
  237.      D3 : モータスピード(右)
  238.      D4 : モータB(右)CH1 , D5 : モータB(右)CH2 1 = HIGH / 0 = LOW
  239.      D6 : LED_3 ON/OFF 1 = HIGH / 0 = LOW
  240.   */
  241.   analogWrite(PWMA, D0);
  242.   digitalWrite(AIN1, D1);
  243.   digitalWrite(AIN2, D2);
  244.   analogWrite(PWMB, D3);
  245.   digitalWrite(BIN1, D4);
  246.   digitalWrite(BIN2, D5);
  247.   digitalWrite(LED_3, D6);
  248. }

  249. // ====被弾====
  250. void Hit() {
  251.   motor_run(255, 0, 1, 255, 1, 0, 0); //左超信地旋回
  252.   delay(100);
  253.   motor_run(0, 1, 1, 0, 1, 1, 1); //停止
  254.   delay(50);
  255.   motor_run(255, 1, 0, 255, 0, 1, 0); //右超信地旋回
  256.   delay(100);
  257.   motor_run(0, 1, 1, 0, 1, 1, 1); //停止
  258.   delay(50);
  259.   /*
  260.     motor_run(128, 1, 0, 1, 0, 0);  //前進
  261.     delay(50);
  262.     motor_run(0, 1, 1, 1, 1, 1); //停止
  263.     delay(50);
  264.   */
  265.   cnt++;
  266.   if ( cnt >= 5 ) {
  267.     motor_run(0, 1, 1, 0, 1, 1, 0); //停止
  268.     delay(30000); //復活までに30秒
  269.     cnt = 0;
  270.   } else {
  271.     delay(1000);
  272.   }
  273. }


コメントを投稿