[動画]
今回のプログラムを書き込むとこのように動きます。
いよいよモータを制御します。
また関数の自作も行いコードをすっきりさせます。
const int LED1 = 14;
const int LED2 = 15;
const int BUZZ = 5;
const int Trig = 7;
const int AIN1 = 3;
const int AIN2 = 6;
const int BIN1 = 9;
const int BIN2 = 10;
const int VR = A0;
const int SW1 = A1;
const int SW2 = A2;
const int ECHO = 8;
//割愛
void setup() {
pinMode(AIN1, OUTPUT);
pinMode(AIN2, OUTPUT);
pinMode(BIN1, OUTPUT);
pinMode(BIN2, OUTPUT);
pinMode(SW1, INPUT);
pinMode(SW2, INPUT);
}
今回メインに使うのはAIN1,2 BIN1,2です。
void KTR_1_straight() {
digitalWrite(AIN1, LOW);
digitalWrite(AIN2, HIGH);
digitalWrite(BIN1, LOW);
digitalWrite(BIN2, HIGH);
}
ここから今まで見たことがないvoid KTR_1??が続きますが。こちらは自作の関数群になります。
関数はArduinoの場合、void loop,setupのカッコ外であればどこに宣言しても大丈夫です。
参考:https://docs.arduino.cc/learn/programming/functions
スケッチ中でKTR_1_straight();と呼ぶとここの中が実行されるイメージです。
今回は呼び出した際に関数中に値を渡したりしないためシンプルな作りになっています。
こうすることによってモータを制御するための4行をわざわざ記載しなくて済みます。
//1秒進んで止まる場合
//関数無し
digitalWrite(AIN1, LOW);//前進
digitalWrite(AIN2, HIGH);
digitalWrite(BIN1, LOW);
digitalWrite(BIN2, HIGH);
delay(1000);
digitalWrite(AIN1, HIGH);//ブレーキ
digitalWrite(AIN2, HIGH);
digitalWrite(BIN1, HIGH);
digitalWrite(BIN2, HIGH);
//関数あり
KTR_1_straight();
delay(1000);
KTR_1_brake();
分かりづらい場合関数無しで4行のdigitalWrite関数を普通に書いても同じことが起こります。
なぜこの四行でKTR-1のモータが制御できるのか軽く説明します。
モータに電池をつないで回した際時計回りだったとしたら、電池を逆に接続すれば逆回転することを知っている方は多いと思いますが、
それを回路で実現し集積回路(IC)にしたモータドライバICをKTR-1では2つ積んでいます。
詳しく回路を知りたい方はHブリッジ回路等で検索をかけてみてください。
これにより2つのモータを制御します。
このモータドライバICには2つの入力が存在します。
それぞれの入力にHIGHやLOWを入力することにより前進、後進、ブレーキ、惰性制御が可能で
これが2つ(2輪分)あるため左右の旋回も可能になっています。
KTR-1での前進、後進、左旋回、右旋回、ブレーキ、惰性を簡単に呼び出せるようにしたのが本関数群です。
従ってループ文内の記述はスッキリしています。
void loop() {
if (digitalRead(SW1) == HIGH && digitalRead(SW2) == HIGH ) {
KTR_1_brake();
while(true){
if (digitalRead(SW1) == LOW && digitalRead(SW2) == LOW ) break;
}
}else if (digitalRead(SW1) == HIGH && digitalRead(SW2) == LOW) {
KTR_1_straight();
}else if (digitalRead(SW1) == LOW && digitalRead(SW2) == HIGH) {
KTR_1_back();
}
}
if文の条件式で
(digitalRead(SW1) == HIGH && digitalRead(SW2) == HIGH )
「&&」という見慣れない記述がありますがこれはAND,両方の条件を満たす場合を指しています。
2つのボタンを同時押ししたらという意味合いです。
OR時は「||」と記載します。
......急にOR(オア)とかAND(アンド)とか言い出してスミマセン こういうのを論理回路と言います。
難しそうな名前ですが皆さんにイジワルをしたいわけではなく、いくつかの入力のパターンにより出力を決めるときに
ORとかANDとかNOT(ノット)とかいう言葉を使うと便利なのです。ちょっと解説します。
ANDはスイッチで表すと左図のようになります。
入力(スイッチ)が2つともONだと出力されるのがこれです。
記号は、かまぼこやビート板のような形で表します。
KTR-1でスイッチを2つとも押したら を条件式にする場合
(digitalRead(SW1) == HIGH && digitalRead(SW2) == HIGH )
となります。
スマブラで小ジャンプをしたかったり、マリオカートで方向転換したいときに同時押ししますよね。
ORはスイッチで表すと左図のようになります。
入力(スイッチ)が片方もしくは2つともONだと出力されるのがこれです。
記号は......とんがったビート板のような形で表します。
KTR-1でスイッチを片方、もしくは両方を条件式にする場合
(digitalRead(SW1) == HIGH || digitalRead(SW2) == HIGH )
となります。
ちなみに間違えやすいのですが論理回路のORは2つとも入力があるときでも
出力をします。
ビーフorチキン 的な意味合いでは無いということです。
論理回路でビーフorチキンを表現したい場合(?)
ビーフ EX-OR(エクスクルーシブ オア) チキン
となります。EX-OR(XOR)は排他的論理和と呼ばれ
入力が全点ある場合はOFFを出力します。が、
Arduinoの条件式にこれは書けません。要らないので。
ビット演算という 数字をEX-ORの計算で処理する際は^を使います。
最後にNOT(ノット)は図で表すと左図ですが逆にちょっと難しいので......
入力が反転された結果が出てくるイメージです。
天の邪鬼なヤツです。
Arduinoでの記号は!です。ちょっとトリッキーですがよく使われます。
EX-ORもそうですがAND、OR、NOTを組み合わせたNAND、NORなどもあります。 単語単体は聞いたことがあるかもしれませんね。
話をもとに戻します。
本ループ文では同時押しでブレーキ、SW1のみで前進、SW2のみで後進するようになっています。
ブレーキの後のwhile関数はブレーキ入力をしやすくするためにつけています。
while(ループ突入の条件式){
//内部でbreak;を宣言すると抜けられるループです。
}
コレが抜けていると、離すタイミングによって他の条件に入ってしまい、動きを止めたつもりがボタンを離した際に勝手に動き出す可能性があります。
同時にボタンを離すまでループが続き今回は1行で書いたifで抜けます。
本項ではモータ制御が中心でした。書いたはいいものの使用していない左右旋回等もあるので
KTRに狙った道順を走らせてみるのも大変ではありますが楽しいと思います。
ぜひ遊んでみてください。
ボタンが押されたら三三七拍子でLEDを光らせて光ると同時にビープ音が鳴って
最初の1・2・3で右旋回
停止
次の1・2・3で左旋回
停止
最後の次の1・2・3・4・5・6・7で右旋回させてみよう