goo blog サービス終了のお知らせ 

Ganponブログ

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

RC可動 M2A2ブラッドレー 回路&プログラム(番外)

2023-04-26 23:55:45 | 1/35 M2A2ブラッドレー

2023-04-27
備忘録として、完成したM2A2ブラッドレーの回路図とプログラムを残します。
尚、ESP32-WROOM-32E-MINIとモータドライバDRV8835は秋月電子通商で購入しました。

▼回路図

画像をクリックすると拡大します

 
  1.   2023-04-18
  2.   効果音はDFPlayer Mini
  3.   モータドライバはDRX8835
  4.    【操作手順】
  5.     PSボタンでペアリング開始。白色インジケータランプ高速点滅。
  6.    戦車の電源投入。
  7.    インジケータランプ青色点灯でペアリング完了。
  8.  
  9.    【走行コントロール】
  10.      コントローラーの左スティック上下で前後進、
  11.      右スティックの左右でステアリングを制御。
  12.      ステアリングを振っていくと回転軸側が減速していき(緩旋回から信地旋回)、
  13.      一杯に倒すと回転軸側は停止。(信地旋回)
  14.      左スティック中央で右ステアリングを一杯に振ると超信地旋回(速度50%)
  15.  
  16.    【砲身上下】右十字キーの △と?ボタンで砲身上下。□ボタンでセンター。
  17.    【砲塔旋回】 左スティック左右で砲塔旋回。離した位置で止まる。
  18.    【リアゲート開閉」 左十字キーのUPとDOWNボタンでゲート閉、開。
  19.    【機関砲】 R1ボタンで主砲発射 40mm自動擲弾銃Mk.19
  20.    【機銃】 L1ボタンで射撃
  21.    【ヘッドライト】左十字キーのRIGHTボタンで点灯、LEFTボタンで消灯。
  22.    【ブレーキランプ】走行中以外に点灯。ヘッドライト点灯時はスモール兼用。
  23.  
  24.    【疑似追尾モード】
  25.    R2ボタンで右超信地旋回 + 砲塔左旋回
  26.    L2ボタンで左超信地旋回 + 砲塔右旋回
  27. */
  28.  
  29. #include // Arduino ヘッダインクルード
  30. #include "SoftwareSerial.h" // EspSoftwareSerial
  31. #include "DFRobotDFPlayerMini.h"
  32.  
  33. //SoftwareSerial mySoftwareSerial(16, 17); // RX, TX EspSoftwareSerial
  34. HardwareSerial Serial_df(2); // use HardwareSerial UART2 (16pin=RX, 17pin=TX)
  35.  
  36. DFRobotDFPlayerMini myDFPlayer;
  37. void printDetail(uint8_t type, int value);
  38. #include
  39. #include
  40. Servo servo1; // create four servo objects
  41. int servo1Pin = 27;
  42. Servo servo2;
  43. int servo2Pin = 14;
  44. Servo servo3;
  45. int servo3Pin = 12;
  46.  
  47. int LED_1 = 23; //ブレーキランプ
  48. int LED_2 = 22; //ヘッドライト
  49. int LED_3 = 19; //砲撃
  50. int LED_4 = 18; //銃撃
  51. int k = 0;
  52. int s = 0;
  53. int d_time = 50;
  54. int angle_servo1 = 80; // 上下;
  55. int dtime = 10; //砲身上下スピード(遅延時間)
  56. int anglenow = angle_servo1 ;
  57. int angle_servo3 = 20 ; // リアゲート閉
  58. int anglenow3 = angle_servo3 ;
  59. int motor_speed;
  60. float steering;
  61. int pos_ly;
  62. int pos_lx;
  63. int pos_ry;
  64. int pos_rx;
  65. int AIN1 = 32; // A入力1/APHASE 左モータ AIN1
  66. int BIN1 = 25; // B入力1/BPHASE 右モータ BIN1
  67. int PWMApin = A5; // A入力2/AENABLE 左モータ AIN2 IO33
  68. int PWMBpin = A19; // B入力2/BENABLE 右モータ BIN2 IO26 (IO0は起動時不安定)
  69. int PWMA = 2; //PWMAチャンネル 0=NG 1=NG 0〜15
  70. int PWMB = 3; //PWMBチャンネル 0=NG 1=NG 0〜15 
  71.  
  72. void setup() {
  73.   servo1.setPeriodHertz(50); // Standard 50hz servo PWMサイクル:20mS FS0307 120°
  74.   servo1.attach(servo1Pin, 900, 2100); // (servo1Pin, minUs, maxUs)
  75.   servo2.setPeriodHertz(50); // Standard 50hz servo PWMサイクル:20mS
  76.   servo2.attach(servo2Pin, 500, 2400); // (servo1Pin, minUs, maxUs)
  77.   servo3.setPeriodHertz(50); // Standard 50hz servo PWMサイクル:20mS FS0307 120°
  78.   servo3.attach(servo3Pin, 900, 2100); // (servo1Pin, minUs, maxUs)
  79.   //delay(50);
  80.  
  81.   //mySoftwareSerial.begin(9600);
  82.   Serial_df.begin(9600); // RX2 = 16, TX2 = 17
  83.   Serial.begin(115200);
  84.  
  85.   //Ps3.begin("00:11:22:33:44:55"); //SixaxisPairToolで調べたmac adresに修正
  86.   //Ps3.begin("0c:b8:15:f5:8a:a2"); // PS3-Eコントローラ ESP32-1
  87.   Ps3.begin("00:00:00:00:00:26"); // PS3-Eコントローラ ESP32-2
  88.   Serial.println("PS3 Ready");
  89.  
  90.   if (!myDFPlayer.begin(Serial_df)) { //Use HardwareSerial to communicate with mp3.
  91.     Serial.println(F("Unable to begin:"));
  92.     Serial.println(F("1.Please recheck the connection!"));
  93.     Serial.println(F("2.Please insert the SD card!"));
  94.     while (true) {
  95.       delay(0); // Code to compatible with ESP8266 watch dog.
  96.     }
  97.   }
  98.  
  99.   Serial.println(F("DFPlayer Mini online."));
  100.   myDFPlayer.volume(20); //Set volume value. From 0 to 30
  101.  
  102.   ledcSetup(PWMA, 5000, 8); //チャンネル,周波数,解像度(8bit=256段階)
  103.   ledcAttachPin(PWMApin, PWMA); //ledPinをPWMCHチャンネルに接続
  104.   ledcSetup(PWMB, 5000, 8); //チャンネル,周波数,解像度(8bit=256段階)
  105.   ledcAttachPin(PWMBpin, PWMB); //ledPinをPWMCHチャンネルに接続
  106.   pinMode(AIN1, OUTPUT);
  107.   pinMode(BIN1, OUTPUT);
  108.   pinMode(LED_1, OUTPUT);
  109.   pinMode(LED_2, OUTPUT);
  110.   pinMode(LED_3, OUTPUT);
  111.   pinMode(LED_4, OUTPUT);
  112.  
  113.   LEDtenmetsu(LED_2);
  114.  
  115.   servo1.write(angle_servo1); // 0 - 180
  116.   delay(100);
  117.   servo2.write(90); // 0 - 180
  118.   delay(100);
  119.   servo3.write(angle_servo3); // 0 - 180
  120.   delay(200);
  121.   servo3.detach();
  122.  
  123.   myDFPlayer.play(28); //エンジン始動
  124.   delay(2000);
  125. }
  126.  
  127. void loop() {
  128.   if (Ps3.isConnected()) {
  129.     pos_lx = Ps3.data.analog.stick.lx;
  130.     pos_lx = pos_lx + 128;
  131.     pos_ly = Ps3.data.analog.stick.ly;
  132.     pos_ly = pos_ly + 128;
  133.     pos_rx = Ps3.data.analog.stick.rx;
  134.     pos_rx = pos_rx + 128;
  135.  
  136.     //砲塔旋回 && pos_ly > 102 && pos_ly
  137.     if ( pos_lx > 230 && pos_ly > 102 && pos_ly
  138.       servo2.write(105);
  139.     } else if (pos_lx < 25 && pos_ly > 102 && pos_ly
  140.       servo2.write(75);
  141.     } else { //停止
  142.       servo2.write(90);
  143.     }
  144.  
  145.     //砲身上下
  146.     if ( Ps3.event.button_down.square) { // center
  147.       if (anglenow > angle_servo1) {
  148.         for (anglenow = anglenow; anglenow >= angle_servo1; anglenow -= 1) {
  149.           servo1.write(anglenow);
  150.           delay(dtime);
  151.         }
  152.       }
  153.       else {
  154.         for (anglenow = anglenow; anglenow <= angle_servo1; anglenow += 1) {
  155.           servo1.write(anglenow);
  156.           delay(dtime);
  157.         }
  158.       }
  159.     }
  160.  
  161.     if ( Ps3.event.button_down.triangle) { // up
  162.       for (anglenow = anglenow; anglenow >= (angle_servo1 - 45); anglenow -= 1 ) {
  163.         servo1.write(anglenow);
  164.         delay(dtime);
  165.       }
  166.     }
  167.  
  168.     if ( Ps3.event.button_down.cross) { // down
  169.       for (anglenow = anglenow; anglenow < (angle_servo1 + 35); anglenow += 1 ) {
  170.         servo1.write(anglenow);
  171.         delay(dtime);
  172.       }
  173.     }
  174.  
  175.     // リアゲート開閉
  176.     if ( Ps3.event.button_down.up) { // ゲートup=閉
  177.       servo3.attach(servo3Pin);
  178.       for (anglenow3 = anglenow3; anglenow3 >= angle_servo3; anglenow3 -= 1 ) {
  179.         servo3.write(anglenow3);
  180.         delay(20);
  181.       }
  182.       delay(50);
  183.       servo3.detach();
  184.     }
  185.  
  186.     if ( Ps3.event.button_down.down) { // ゲートdown=開
  187.       servo3.attach(servo3Pin);
  188.       for (anglenow3 = anglenow3; anglenow3 < (angle_servo3 + 110); anglenow3 += 1 ) {
  189.         servo3.write(anglenow3);
  190.         delay(20);
  191.       }
  192.       delay(50);
  193.       servo3.detach();
  194.     }
  195.  
  196.     if (Ps3.event.button_down.circle) {
  197.       if (s == 0) {
  198.         s = 1;
  199.         myDFPlayer.play(28); //エンジン始動
  200.         delay(5000); // delay(8000);
  201.         myDFPlayer.loop(23); //Loop 5th mp3 アイドリング
  202.         delay(d_time);
  203.       } else {
  204.         myDFPlayer.disableLoop(); //アイドリング停止
  205.         s = 0;
  206.         //delay(100);
  207.       }
  208.     }
  209.  
  210.     if (Ps3.event.button_down.r3) {
  211.       myDFPlayer.disableLoop(); //アイドリング停止
  212.       s = 0;
  213.     }
  214.  
  215.     if (Ps3.event.button_down.right) {
  216.       digitalWrite(LED_2, HIGH); // Headlight ON
  217.     }
  218.  
  219.     if (Ps3.event.button_down.left) {
  220.       digitalWrite(LED_2, LOW); // Headlight off
  221.     }
  222.  
  223.     if (Ps3.data.button.r2) { //右超信地旋回疑似砲塔追尾デモ
  224.       servo2.write(75); //砲塔左旋回
  225.       motor_speed = 255;
  226.       motor_run(motor_speed, 0, motor_speed, 1, 0);
  227.       delay(500);
  228.  
  229.     }
  230.  
  231.     if (Ps3.data.button.l2) { //左超信地旋回疑似砲塔追尾デモ
  232.       servo2.write(105); //砲塔右旋回
  233.       motor_speed = 255;
  234.       motor_run(motor_speed, 1, motor_speed, 0, 0);
  235.       delay(500);
  236.     }
  237.  
  238.     if (Ps3.event.button_down.r1) { //機関砲
  239.       myDFPlayer.play(31);
  240.       for ( int i = 0; i < 3 ; i++) {</li>
  241.         digitalWrite(LED_3, HIGH); //発光
  242.         delay(80);
  243.         digitalWrite(LED_3, LOW);
  244.         delay(220);
  245.       }
  246.       if (s == 1) {
  247.         myDFPlayer.loop(23); //Loop 5th mp3 アイドリング
  248.         delay(d_time);
  249.       }
  250.     }
  251.  
  252.     if (Ps3.event.button_down.l1) { //機銃
  253.       myDFPlayer.play(30);
  254.       delay(100);
  255.       for ( k = 0; k < 9; k++) {
  256.         digitalWrite(LED_4, HIGH); //発光
  257.         delay(40);
  258.         digitalWrite(LED_4, LOW);
  259.         delay(60);
  260.       }
  261.       if (s == 1) {
  262.         myDFPlayer.loop(23); //Loop 5th mp3 アイドリング
  263.         delay(d_time);
  264.       }
  265.     }
  266.  
  267.     //走行コントロール
  268.     /* pos_ly = Ps3.data.analog.stick.ly;
  269.        pos_rx = Ps3.data.analog.stick.rx;
  270.        pos_ly = pos_ly + 128;
  271.        pos_rx = pos_rx + 128;
  272.     */
  273.  
  274.     /* //左スティックがセンター付近は停止(ブレーキ)
  275.         if (pos_rx > 102 && pos_rx < 152 && pos_ly > 102 && pos_ly
  276.           motor_run(0, 0, 0, 0, 1);
  277.         }
  278.     */
  279.  
  280.     //前進
  281.     if (pos_ly <= 102 && pos_rx >= 102 && pos_rx <= 152) {
  282.       motor_speed = map(pos_ly, 102, 0, 0, 255);
  283.       motor_run(motor_speed, 0, motor_speed, 0, 0);
  284.     }
  285.  
  286.     //後進
  287.     else if ( pos_ly >= 152 && pos_rx >= 102 && pos_rx <= 152) {
  288.       motor_speed = map(pos_ly, 152, 255, 0, 255) ;
  289.       motor_run(motor_speed, 1, motor_speed, 1, 0);
  290.     }
  291.  
  292.     //前進右緩旋回、信地旋回
  293.     //else if ( pos_ly <= 102 && pos_rx > 152 && pos_rx <= 245) {
  294.     else if ( pos_ly <= 102 && pos_rx >= 152) {
  295.       motor_speed = map(pos_ly, 102, 0, 0, 255);
  296.       steering = motor_speed * (1.00 - (map(pos_rx, 152, 255, 0, 255) / 255.00));
  297.       motor_run(motor_speed, 0, steering, 0, 0);
  298.     }
  299.  
  300.     //前進左緩旋回、信地旋回
  301.     //else if ( pos_ly <= 102 && pos_rx < 102 && pos_rx >= 10) {
  302.     else if ( pos_ly <= 102 && pos_rx <= 102) {
  303.       motor_speed = map(pos_ly, 102, 0, 0, 255);
  304.       steering = motor_speed * (1.00 - (map(pos_rx, 102, 0, 0, 255) / 255.00));
  305.       motor_run(steering, 0, motor_speed, 0, 0);
  306.     }
  307.  
  308.     //後進右緩旋回、信地旋回
  309.     //else if ( pos_ly >= 152 && pos_rx > 152 && pos_rx <= 245) {
  310.     else if ( pos_ly >= 152 && pos_rx >= 152 ) {
  311.       motor_speed = map(pos_ly, 152, 255, 0, 255);
  312.       steering = motor_speed * (1.00 - (map(pos_rx, 152, 255, 0, 255) / 255.00));
  313.       motor_run(motor_speed, 1, steering, 1, 0);
  314.     }
  315.  
  316.     //後進左緩旋回、信地旋回
  317.     //else if ( pos_ly >= 152 && pos_rx < 102 && pos_rx >= 10) {
  318.     else if ( pos_ly >= 152 && pos_rx <= 102 ) {
  319.       motor_speed = map(pos_ly, 152, 255, 0, 255);
  320.       steering = motor_speed * (1.00 - (map(pos_rx, 102, 0, 0, 255) / 255.00));
  321.       motor_run(steering, 1, motor_speed, 1, 0);
  322.     }
  323.  
  324.     //右超信地旋回
  325.     else if (pos_rx >= 245 && pos_ly >= 102 && pos_ly <= 152) {
  326.       motor_speed = 204;
  327.       motor_run(motor_speed, 0, motor_speed, 1, 0);
  328.     }
  329.  
  330.     //左超信地旋回
  331.     else if (pos_rx <= 10 && pos_ly >= 102 && pos_ly <= 152) {
  332.       motor_speed = 204;
  333.       motor_run(motor_speed, 1, motor_speed, 0, 0);
  334.     }
  335.  
  336.     else { //停止(ブレーキ)
  337.       motor_run(0, 0, 0, 0, 1);
  338.     }
  339.   }
  340. }
  341.  
  342.  
  343. void motor_run(int D0, int D1, int D2, int D3, int D4) {
  344.   //D0 : モータスピード(左)
  345.   //D1 : モータA(左)1 = HIGH / 0 = LOW
  346.   //D2 : モータスピード(右)
  347.   //D3 : モータB(右)1 = HIGH / 0 = LOW
  348.   //D4 : LED_3 ON/OFF 1 = HIGH / 0 = LOW
  349.  
  350.   //analogWrite(PWMA, D0);
  351.   ledcWrite(PWMA, D0); //(チャンネル,解像度)
  352.   digitalWrite(AIN1, D1);
  353.   //analogWrite(PWMB, D2);
  354.   ledcWrite(PWMB, D2); //(チャンネル,解像度)
  355.   digitalWrite(BIN1, D3);
  356.   digitalWrite(LED_1, D4);
  357. }
  358.  
  359. void LEDtenmetsu(int LED) {
  360.   for (int i = 0; i
  361.     digitalWrite(LED, HIGH);
  362.     delay(500);
  363.     digitalWrite(LED, LOW);
  364.     delay(500);
  365.   }
  366. }