リモートコントロール(RC)戦車をつくる【スケッチ_モータ制御②】 [RC戦車]
前回の記事(リモートコントロール(RC)戦車をつくる【赤外線コントロール②】)で赤外線リモコンのコードが判ったのでスケッチを修正するのですが、もう一つ修正する箇所があります。
これまでは
>#define SPEED 128 //モータへの電圧(スピード)は一定
として、どの方向に対してもスピードを一定にしていましたが、緩旋回では左右のキャタピラのスピードに差分をつけるため、左右のモータへかける電圧(Vref)を変える必要があります。
ジョイスティックであればアナログ的に電圧を変化させる(スピードを変化させる)ことができるのですが、今回はリモコンボタンのため2種類の電圧を組み合わせての変化とします。
他にも全般的にスケッチを見直して修正しています。
【スケッチ】
※#include <IRremote.h>は表示の不具合で全角<>で記載しています。本当は半角<>ですのでご注意ください。
【動作確認】
早速、動かしてみます。
右/左と緩旋回もできています。動作の変化時のwaitも外したので、前回よりスムーズに動作してラジコンらしい動きになりました。直進でやや左に寄ってしまうのはおそらく車軸がずれているか?、それともVref電圧に少々の電圧差があるのかもしれません。真っ直ぐ走らせるためにはこのズレを補正する形でVref電圧を調整すればよいのですが、今回はやりません。(動けばOK!だったので。。。)
(2020.06.14 スケッチ修正)
#define SPEED_2 153 //0~255(MAX):Vref電圧を3Vまでに制限
SPEED_2が196だとVrefにかかる電圧が3.8Vとなり、モータへの電圧が高過ぎるはずなので、Vrefにかかる電圧を3Vにするために、MAXを255*(3[V]/5[V]) = 153
に修正する。
これまでは
>#define SPEED 128 //モータへの電圧(スピード)は一定
として、どの方向に対してもスピードを一定にしていましたが、緩旋回では左右のキャタピラのスピードに差分をつけるため、左右のモータへかける電圧(Vref)を変える必要があります。
ジョイスティックであればアナログ的に電圧を変化させる(スピードを変化させる)ことができるのですが、今回はリモコンボタンのため2種類の電圧を組み合わせての変化とします。
他にも全般的にスケッチを見直して修正しています。
【スケッチ】
/* SparkFun Electronics 2013 Playing with Infrared Remote Control IR Receiver Breakout (SEN-8554): Supply voltage of 2.5V to 5.5V Attach OUT: To pin 13 on Arduino GND: GND VCC: 5V This is based on Ken Shirriff's code found on GitHub: https://github.com/shirriff/Arduino-IRremote/ This code works with cheap remotes. If you want to look at the individual timing of the bits, use this code: http://www.arduino.cc/playground/Code/InfraredReceivers */ #include <IRremote.h> // 赤外線送受信用ヘッダファイル int RECV_PIN = 11; // 赤外線受信モジュール IRrecv irrecv(RECV_PIN); // 赤外線受信用オブジェクトの設定 decode_results results; // 赤外線受信結果を格納する #define POWER 0x8F71BE4 #define A 0x8F71FE0 #define B 0x8F71EE1 #define C 0x8F71AE5 #define UP 0x8F705FA #define DOWN 0x8F700FF #define LEFT 0x8F708F7 #define RIGHT 0x8F701FE #define SELECT 0x8F704FB #define UP_LEFT 0x8F78D72 #define DOWN_LEFT 0x8F78877 #define UP_RIGHT 0x8F7847B #define DOWN_RIGHT 0x8F7817E #define SPEED_0 0 //モータへの電圧(スピード)を3種類用意 #define SPEED_1 77 #define SPEED_2 153 //0~255(MAX):Vref電圧を3Vまでに制限 // set pin numbers: // 右キャタピラ用ピン const int R_Vref = 5; //D5(PWM) const int R_OUT1 = 3; //D3 const int R_OUT2 = 4; //D4 // 左キャタピラ用ピン const int L_Vref = 6; //D6(PWM) const int L_OUT1 = 7; //D7 const int L_OUT2 = 8; //D8 // 初期化(電源投入/リセット時1回のみ実行): void setup() { Serial.begin(9600); irrecv.enableIRIn(); // Start the receiver // initialize the motor driver pin as an output(Arduinoにモータドライバへのピンが出力であることを伝える) pinMode(R_Vref, OUTPUT); pinMode(R_OUT1, OUTPUT); pinMode(R_OUT2, OUTPUT); pinMode(L_Vref, OUTPUT); pinMode(L_OUT1, OUTPUT); pinMode(L_OUT2, OUTPUT); } // main loop: void loop() { if (irrecv.decode(&results)) //(★これが無いと動作しない) { switch(results.value) { case UP: //UPなら前進 analogWrite(R_Vref, SPEED_2); // モータドライバのスピードを指定 analogWrite(L_Vref, SPEED_2); digitalWrite(R_OUT1, LOW); //貫通電流防止(ストップ) digitalWrite(R_OUT2, LOW); digitalWrite(L_OUT1, LOW); digitalWrite(L_OUT2, LOW); digitalWrite(R_OUT1, HIGH); digitalWrite(R_OUT2, LOW); digitalWrite(L_OUT1, HIGH); digitalWrite(L_OUT2, LOW); break; case RIGHT: //RIGHTなら右超信地旋回 analogWrite(R_Vref, SPEED_2); // モータドライバのスピードを指定 analogWrite(L_Vref, SPEED_2); digitalWrite(R_OUT1, LOW); //貫通電流防止(ストップ) digitalWrite(R_OUT2, LOW); digitalWrite(L_OUT1, LOW); digitalWrite(L_OUT2, LOW); digitalWrite(R_OUT1, LOW); digitalWrite(R_OUT2, HIGH); digitalWrite(L_OUT1, HIGH); digitalWrite(L_OUT2, LOW); break; case LEFT: //LEFTなら左超信地旋回 analogWrite(R_Vref, SPEED_2); // モータドライバのスピードを指定 analogWrite(L_Vref, SPEED_2); digitalWrite(R_OUT1, LOW); //貫通電流防止(ストップ) digitalWrite(R_OUT2, LOW); digitalWrite(L_OUT1, LOW); digitalWrite(L_OUT2, LOW); digitalWrite(R_OUT1, HIGH); digitalWrite(R_OUT2, LOW); digitalWrite(L_OUT1, LOW); digitalWrite(L_OUT2, HIGH); break; case DOWN: //DOWNなら後進 analogWrite(R_Vref, SPEED_2); // モータドライバのスピードを指定 analogWrite(L_Vref, SPEED_2); digitalWrite(R_OUT1, LOW); //貫通電流防止(ストップ) digitalWrite(R_OUT2, LOW); digitalWrite(L_OUT1, LOW); digitalWrite(L_OUT2, LOW); digitalWrite(R_OUT1, LOW); digitalWrite(R_OUT2, HIGH); digitalWrite(L_OUT1, LOW); digitalWrite(L_OUT2, HIGH); break; case SELECT: //SELECTなら停止(ブレーキ→ストップ) analogWrite(R_Vref, SPEED_0); // モータドライバのスピードを指定 analogWrite(L_Vref, SPEED_0); digitalWrite(R_OUT1, LOW); //貫通電流防止(ストップ) digitalWrite(R_OUT2, LOW); digitalWrite(L_OUT1, LOW); digitalWrite(L_OUT2, LOW); digitalWrite(R_OUT1, HIGH); //ブレーキ digitalWrite(R_OUT2, HIGH); digitalWrite(L_OUT1, HIGH); digitalWrite(L_OUT2, HIGH); digitalWrite(R_OUT1, LOW); //ストップ digitalWrite(R_OUT2, LOW); digitalWrite(L_OUT1, LOW); digitalWrite(L_OUT2, LOW); break; case UP_RIGHT: //UP_RIGHTなら右前進緩旋回 analogWrite(R_Vref, SPEED_1); // 右キャタピラの速度を遅く analogWrite(L_Vref, SPEED_2); // 左キャタピラの速度を速く digitalWrite(R_OUT1, LOW); //貫通電流防止(ストップ) digitalWrite(R_OUT2, LOW); digitalWrite(L_OUT1, LOW); digitalWrite(L_OUT2, LOW); digitalWrite(R_OUT1, HIGH); digitalWrite(R_OUT2, LOW); digitalWrite(L_OUT1, HIGH); digitalWrite(L_OUT2, LOW); break; case DOWN_RIGHT: //DOWN_RIGHTなら右後進緩旋回 analogWrite(R_Vref, SPEED_1); // 右キャタピラの速度を遅く analogWrite(L_Vref, SPEED_2); // 左キャタピラの速度を速く digitalWrite(R_OUT1, LOW); //貫通電流防止(ストップ) digitalWrite(R_OUT2, LOW); digitalWrite(L_OUT1, LOW); digitalWrite(L_OUT2, LOW); digitalWrite(R_OUT1, LOW); digitalWrite(R_OUT2, HIGH); digitalWrite(L_OUT1, LOW); digitalWrite(L_OUT2, HIGH); break; case UP_LEFT: //UP-LEFTなら左前進緩旋回 analogWrite(R_Vref, SPEED_2); // 右キャタピラの速度を速く analogWrite(L_Vref, SPEED_1); // 左キャタピラの速度を遅く digitalWrite(R_OUT1, LOW); //貫通電流防止(ストップ) digitalWrite(R_OUT2, LOW); digitalWrite(L_OUT1, LOW); digitalWrite(L_OUT2, LOW); digitalWrite(R_OUT1, HIGH); digitalWrite(R_OUT2, LOW); digitalWrite(L_OUT1, HIGH); digitalWrite(L_OUT2, LOW); break; case DOWN_LEFT: //DOWN-LEFTなら左後進緩旋回 analogWrite(R_Vref, SPEED_2); // 右キャタピラの速度を速く analogWrite(L_Vref, SPEED_1); // 左キャタピラの速度を遅く digitalWrite(R_OUT1, LOW); //貫通電流防止(ストップ) digitalWrite(R_OUT2, LOW); digitalWrite(L_OUT1, LOW); digitalWrite(L_OUT2, LOW); digitalWrite(R_OUT1, LOW); digitalWrite(R_OUT2, HIGH); digitalWrite(L_OUT1, LOW); digitalWrite(L_OUT2, HIGH); break; default: break; } irrecv.resume(); // 受信機をリセットする(★これが無いと1回のみの制御となる) } }
※#include <IRremote.h>は表示の不具合で全角<>で記載しています。本当は半角<>ですのでご注意ください。
【動作確認】
早速、動かしてみます。
右/左と緩旋回もできています。動作の変化時のwaitも外したので、前回よりスムーズに動作してラジコンらしい動きになりました。直進でやや左に寄ってしまうのはおそらく車軸がずれているか?、それともVref電圧に少々の電圧差があるのかもしれません。真っ直ぐ走らせるためにはこのズレを補正する形でVref電圧を調整すればよいのですが、今回はやりません。(動けばOK!だったので。。。)
(2020.06.14 スケッチ修正)
#define SPEED_2 153 //0~255(MAX):Vref電圧を3Vまでに制限
SPEED_2が196だとVrefにかかる電圧が3.8Vとなり、モータへの電圧が高過ぎるはずなので、Vrefにかかる電圧を3Vにするために、MAXを255*(3[V]/5[V]) = 153
に修正する。
2019-10-20 23:36
nice!(0)
コメント(0)
コメント 0