前回シフトインジケーター部のプログラムのさわりに取り掛かっていた。ギアポジションの信号線をSeeeduino XIAOに接続し、そのいずれかが導通すれば、その配線のギアが現在のポジションであるという判断ができる。というところまで理解できたいたはずだ。
今回は4本の配線の状態をまとめて監視し、現在ギアが何速に入っているのか、というまさにシフトインジケーターのプログラム部分を完成しよう。
4本のピンの状態を知る
前回の内容からピンの状態を知るためには以下のようなプログラムを書けばいいことがわかった。
前回のプログラムをもう一度見てみよう。
void setup() {
// put your setup code here, to run once:
Serial.begin(9600); // シリアルモニタのスタート
pinMode(2, INPUT_PULLUP); // ピンに電圧をかける
}
void loop() {
// put your main code here, to run repeatedly:
Serial.print(digitalRead(2)); // 電圧をかけたピンの状態を表示
Serial.println(); // 改行
delay(1000); // 1000ms待機
}
このプログラムの中の5行目に次のような記述がある。
pinMode(2, INPUT_PULLUP);
この記述の意味は「2番ピンにあらかじめ電圧をかけておいてね(そして、その状態をモニターしますよ)」という意味だ。
この段階ではあくまでもピンの状態を定義するのみで実際にピンの状態はモニターしていない。実際に状態をモニターしている部分は11行目の
digitalRead(2)
という部分で「2番ピンの状態を読み取る」という命令になる。
ちなみに複数記述のある「Serial.」という文句は僕達人間にわかるように画面に表示させるための命令なので、マイコン的には特に必要ない文である(もちろんこの文がないと僕達にはマイコンがおこなっている事がさっぱりわからない)。
前回は1つのピンの状態だけをモニターしたが、これを4つのピンすべてについて記述すれば全部のピン状態をモニターできる。
次のようなプログラムを書いてみよう。
void setup() {
// put your setup code here, to run once:
Serial.begin(9600); // シリアルモニタのスタート
// ピンに電圧をかける
pinMode(2, INPUT_PULLUP);
pinMode(3, INPUT_PULLUP);
pinMode(4, INPUT_PULLUP);
pinMode(5, INPUT_PULLUP);
}
void loop() {
// put your main code here, to run repeatedly:
// 電圧をかけたピンの状態を表示
Serial.print("Pin 2 : ");
Serial.print(digitalRead(2));
Serial.println();
Serial.print("Pin 3 : ");
Serial.print(digitalRead(3));
Serial.println();
Serial.print("Pin 4 : ");
Serial.print(digitalRead(4));
Serial.println();
Serial.print("Pin 5 : ");
Serial.print(digitalRead(5));
Serial.println();
Serial.println();
delay(1000); // 1000ms待機
}
書いたらマイコンに書き込んで動作を確認してみよう。次のスクリーンショットのような実行結果になっただろうか。
シリアルモニタに2番〜5番までのピンの状態が表示されている。ここでおもむろに前回同様に4本のジャンパ線をGNDピンに順番に差し込んでいってみよう。
すると、挿したジャンパ線に応じて1の表示が0になるはずだ。
ポジション信号を取り出す機構の話
ところでスーパーカブでポジション信号を取り出すと言ってきたけれど、実際にその機構はどうなっているのかご存じだろうか。
前回は言葉だけで少し説明したけれど百聞は一見にしかず。その部分の部品を見た方がイメージしやすいかもしれない。
これがギヤチェンジするところについている。
ペダルを足でガチャコンと踏むと軸が回転してニュートラルから1速に変わる。そうするとプラス信号を配線された接点の位置がずれる。その接点が接する場所が変わることで、この部品についている配線のいずれかに電気が流れるようになっている。
これを見てわかることは、機構的に2つの場所に同時に電気が流れることは多分なさそうだ。つまり僕達が今作っているプログラムで言えば、例えば2番ピンと3番ピンが同時に「0」を返すことはなさそうだということになる。常にどこか一つしか「0」を返さない。
ただしすべてが「1」になる時がある。
上の写真では接点が5つある。僕達が配線してるのは4本だ。そう、ニュートラルにも配線があるのだ。しかしニュートラルの配線はすでにメーターパネルに結線されている。ニュートラルランプを点灯させなければいけないから。なのでニュートラルの信号は取り出せないが、「すべてが1になる時はニュートラル」という判断ができるので、このプログラムではひとまず問題なさそうである。
(2=1)+(3=1)+(4=0)+(5=1)は何速?
なんとなくどういった感じでプログラムを組めばいいのかわかってきたような気がする。
4つの配線の電圧の状態の組み合わせで何速かを判断すればいい。
ギア\ピン | 2番ピン | 3番ピン | 4番ピン | 5番ピン |
ニュートラル | 1 | 1 | 1 | 1 |
1速 | 0 | 1 | 1 | 1 |
2速 | 1 | 0 | 1 | 1 |
3速 | 1 | 1 | 0 | 1 |
4速 | 1 | 1 | 1 | 0 |
これらの判断をするためにプログラムでは次のように書くことができる。例えば1速を判定するにはこうだ。
if (digitalRead(2) == 0 && digitalRead(3) == 1 && digitalRead(4) == 1 && digitalRead(5) == 1)
{
Serial.print("1速");
Serial.println();
}
「2番ピンの状態が0で、かつ、3番ピンの状態が1で、かつ4番ピンの状態が1で、かつ、5番ピンの状態が1」ならば「1速」とシリアルモニタに表示する。
という意味になる。
長い…。しかもこれで1速だけだ。これで4速書くのはたまらない。
そこでもう少し簡単になるように工夫して…
void setup() {
Serial.begin(9600); // シリアルモニタのスタート
// ピンに電圧をかける
pinMode(2, INPUT_PULLUP);
pinMode(3, INPUT_PULLUP);
pinMode(4, INPUT_PULLUP);
pinMode(5, INPUT_PULLUP);
}
void loop() {
// ピンの状態を変数に代入する
int s1 = digitalRead(2);
int s2 = digitalRead(3);
int s3 = digitalRead(4);
int s4 = digitalRead(5);
// ギアポジションの文字を変数に代入する
String gear = "N";
// 条件判断:条件によってギアポジの変数gearの内容を変更する
if (s1 == LOW && s2 == HIGH && s3 == HIGH && s4 == HIGH) {
gear = "1";
}
else if (s1 == HIGH && s2 == LOW && s3 == HIGH && s4 == HIGH) {
gear = "2";
}
else if (s1 == HIGH && s2 == HIGH && s3 == LOW && s4 == HIGH) {
gear = "3";
}
else if (s1 == HIGH && s2 == HIGH && s3 == HIGH && s4 == LOW) {
gear = "4";
}
else
{
gear = "N";
}
Serial.print(gear); // 変数ギアの内容を表示
Serial.println(); // 改行
delay(1000); // 1000ms待機
}
少々プログラム的な難易度が飛躍したかもしれないがお許しいただきたい。
とりあえず
- 「digitalRead(x)」をたくさん書くのが嫌なので、ピン状態は変数に代入して簡潔にする
- 「Serial.print」をたくさん書くのも嫌なので、ギアの状態を変数に代入して、最後に1度だけ書けばいいようにする
- ピン状態の0や1は「LOW」と「HIGH」と置き換えることができる(あらかじめプログラムのお約束としてLOW=0、HIGH=1と定義されている)ので、0や1の意味のよくわからない数字ではなく、意味のある言葉として書く(可読性を高める)
というところをポイントにまとめた。
愛車のギアチェンジを想像しながら
プログラムを書いたらもちろんマイコンに書き込んで実験です。
一つずつジャンパ線をGNDピンに接続して、シリアルモニタの表示が1、2、3、4そしてNと変化することを楽しんでみよう。
なんと簡単なことに、これでシフトインジケーターの基本部分は完成してしまったのだ!
次回は日付、時間、気温の表示に取り掛かろう。
コメント
[…] Arduino互換機を使ったマルチメーターの制作〜その2〜シフトインジケーター […]
[…] Arduino互換機を使ったマルチメーターの制作〜その2〜シフトインジケーター […]