こんにちは、NABEです。すっかり夏が来て猛暑日続きですね…
少し間が空いてしまいましたが、前回は開発用のノートPCで開発環境構築を行いました。
今回からは、いよいよトレーニングトレーサーにプログラムを書き込んで動かしていきます。
トレーニングトレーサーには、ArduinoIDE用のサンプルプログラムと解説が付属しているため※、プログラムを1から書けない初心者でも、それらを活用して制御することが出来るんです!
サンプルプログラムを書き込みながら、プログラミングの基礎や用語についても勉強していこうと思います。
※ArduinoIDEだけでなく、STM32CubeIDE用のサンプル&解説もあります。
ArduinoIDEのサンプルプログラムはSTEP1、2、3…と進んでいきます。
まずはプログラミングの基礎をさらって、その後STEP1を使ってLEDを点滅させる、通称「Lチカ」をやっていきます。
プログラミング 基礎の基礎
プログラミングと言語
簡単に言うと、コンピュータを動かすための命令(プログラム)を作る作業を「プログラミング」といいます。
コンピュータは機械語(0と1を並べたビット列)しか認識できないため、機械語で命令をしなければいけません。
しかし、0101010111110011…と書かれていても、人間がその意味を理解するのは大変困難です。
そのため、プログラミングではまず高級言語といわれる比較的人間が使う言語に近く分かりやすい言語を使ってプログラムを書き、コンパイラ(変換ソフトウェア)で機械言語に翻訳してから命令を送ります。
代表的な高級言語の種類としては、BASIC、FORTRAN、C言語、C++、Javaなどがあります。
今回はArduinoIDEを使った開発なので、Arduino言語というC言語に似た言語を使います。
どんな命令を送っているの?
さて、トレーニングトレーサーを制御して走らせるにはどんな命令を送ればいいのでしょう?
「とりあえずまっすぐ走ってみて!」
と命令することはできません。
「右タイヤのモータを時計回り&~~くらいの力で回転させて」
「左タイヤのモータを反時計回り&~~くらいの力で回転させて」
ざっくりと書きましたが、このように命令してやっと左右のタイヤについたモータが前進の向きに回転するようになり、左右同じ力がかかることでまっすぐ進みます。
回転の向きを指示できるところと、回転する力を指示できるところがあり、それぞれに細かく命令をする必要があります。
これを知ると、複雑な動きをするロボットのことを考えるだけでも、プログラミングとは途方もない作業なのだと分かります。
制御する命令は、モータやセンサ、LEDなどのそれぞれの機能に繋がっているコンピュータに対して送ります。
今回はNUCLEO-F303K8のマイコンに命令を送ることでトレーニングトレーサーを制御できるというわけです。
LEDを点滅させてみる
まずはLEDの点滅、通称「Lチカ」からやってみます!
LチカはLEDチカチカの略です。
サンプルプログラムを開いて書き込む
まずはトレーニングトレーサーを開発用PCと接続させ、電源を入れます。
電源が入っていないとその後の書き込みが上手くいかないので注意しましょう。
ArduinoIDEのスケッチでサンプルプログラムSTEP1を開きます。
ファイル→環境設定から「行番号を表示する」にチェックを入れるとプログラムの左側に行番号が表示されて便利です。
12~26行目がSTEP1の内容です。
これをトレーニングトレーサーに書き込むには画面左上にある「→」マークを押します。
すると…
LD3と書かれた場所のLED(緑)が1秒間隔で点滅しました!
Lチカ!!!
STEP1の内容
プログラムの内容を見ていきましょう。
12 int LED_Pin= D13;
13
14 void setup() {
15 // put your setup code here, to run once:
16 pinMode(LED_Pin,OUTPUT);
17
18 }
19
20 void loop() {
21 // put your main code here, to run repeatedly:
22 digitalWrite(LED_Pin,HIGH); //LEDを点灯
23 delay(1000); //1秒待つ
24 digitalWrite(LED_Pin,LOW); //LED消灯
25 delay(1000); //1秒待つ
26 }
一目見て分かったのは、22~25行目でLEDを点灯→1秒待つ→消灯→1秒待つとさせていることです。
なぜなら日本語で書いてあるから!
(//と入力すると、その後に書いたものはコンピュータ側に認識されないのでメモとして使えるそうです。改行すると効果が切れます。)
それ以外のところはさっぱりなので、上から順番に解説を見ながら勉強していきます。
12 int LED_Pin= D13;
まず12行目はint型と言われる変数の型で、数値の記憶に使われます。
変数はプログラミングにおける数値を入れておく箱のようなもので、値を入れたり取り出したり出来ます。数学のx,yと考え方は同じです。
int型について詳しくはArduinoのリファレンスやこちらの用語辞典をご覧ください。用語辞典はとてもかみ砕いて書いてあるので分かりやすいです。
今回使っているNUCLEO-F303K8に載っているのは32ビットマイコンなので、4Byteまで(-2,147,483,648~2,147,483,647)の整数を記録できます。
簡単に言えば、intって書いたらその次の情報を記憶の箱(最大4Byteまで)に入れて覚えてね!ということですね。
12行目ではこのint型を使って変数を定義しています。
つまり、箱の中に「LED_Pin=D13だよ!」と記憶させています。
「LED_Pin」はこのあと指示を出しやすくするために付けた名前です。
書き方は分かれば何でもOK。
「D13」は先ほど点滅させたLED(緑)に繋がっているピンの場所を指定しています。
こちらはD13と決められています。
※ピンについては後半で説明します。
14 void setup() {
15 // put your setup code here, to run once: 説明文
16 pinMode(LED_Pin,OUTPUT);
17
18 }
14~18行目はボードの電源を入れたときやプログラムを実行したときに最初の1回だけやってほしいことを書いています。
setup()はArduinoIDEにおいてデフォルトで設定される関数です。設定の初期化や通信速度の設定などに使います。
こちらはvoid型といって、戻り値の型が無いことを示す型で書かれています。
intは箱のサイズを指定して覚えてね!という型でしたが、voidは何も覚えないでただ実行してね!という型です。
ここではpinMode()という関数で先ほど定義したLED_PinをOUTPUT(出力モード)に設定しています。
OUTPUTにすることで、回路に電流を流すことができるようになります。
ちなみにINPUTにすると回路に流れた電流量を計れるようになります。
20 void loop() {
21 // put your main code here, to run repeatedly: 説明文
22 digitalWrite(LED_Pin,HIGH); //LEDを点灯
23 delay(1000); //1秒待つ
24 digitalWrite(LED_Pin,LOW); //LED消灯
25 delay(1000); //1秒待つ
26 }
最後はメインの関数に入ります。実行したい内容をここに書きます。
loop()はsetup()と同じくデフォルトで設定される関数です。
名前の通りこの部分は繰り返し実行されるため、loop()内に特に条件指定がない限り、電源を切るまでずっと繰り返されます。
digitalWrite()は指定したピンにHIGHかLOWを出力します。
HIGH=あり(今回は3.3V)
LOW=なし(0V)
なので、HIGHにした場合は3.3Vの電流が流れます。
LEDの回路であれば、電流が流れてLEDが点灯するということです。
22行目でLED_PinにHIGHを出力し、LED点灯
24行目でLED_PinにLOWを出力し、LED消灯
となっています。
delay()は括弧の中に書いた秒数分待機させる関数です。
単位はマイクロ秒なので、1000マイクロ秒→1秒待機ということになります。
まとめると
・1秒間点灯
・1秒間消灯
これらをloop()で繰り替えすことで、LEDを点滅させていたと分かりました。
LEDを点滅させるときに、どれくらい点いてどれくらい消えるのかという時間も指定しなければいけないというのはよくよく考えたら当たり前なのですが、
自分の中ではなんとなくONとOFFを指示すればチカチカすると思っていたので驚きでした。
これからは家電やスマホのLEDを見るだけでもどんな命令をされているのか考えてしまいそうです。
最後に、今回LED_Pinと定義したD13とは何なのか、簡単にご説明します。
プログラミングとピンの関係
最初に書いた通り、マイコンに命令を送ることでトレーニングトレーサーを制御しています。
ピンの定義をして、pinMode()でピンのモードを設定したり、digitalWrite()でピンにHIGHを出力して電流を流したりします。
ピンとは一体どこを指しているのでしょうか?
ピンというのは、マイコンの周辺から出ている小さな銀色の部分を指します。
これがマイコンボードの回路を通り、多くはピンヘッダを通じてLEDやモータ、スイッチなどの周辺機器が繋がれています。
開発用PCからマイコンのピンを指定し、入出力や電流の扱いを命令することで、その先に繋がれた周辺機器を操作できるという仕組みです。
つまりボードによってピンの名称や役割は違います。
例えばNUCLEO-F303K8であれば、mbedという開発環境の公式サイトでピン配置図が公開されているので気になった方は見てみてください。
それぞれのピンがどのピンヘッダ等に繋がっているか分かります。
また、開発環境によってピンの呼び方も変わることもあります。
NucleoボードをArduinoIDEで扱うときには、ArduinoIDEに対応した名称で指定します。
マイコンについているピン自体の名称ではなく、ピンに繋がっているピンヘッダの名称を使います。
(名称をArduinoIDEに覚えてもらうために開発環境の構築で色々インストールしました)
例えばSTEP1のLEDの点滅は……
マイコンのPB3という場所のピンからD13のピンヘッダに繋がり、LD3と書かれたLED(緑)にも繋がっています。※線はイメージ
PB3からD13へ電流が流れるとLE3のLEDが光る仕組みです。
STEP1のはじめにint型で定義していた「D13」はピンヘッダの番号を示していました。
プログラムにおいて正確には「PB3」ピンの入出力などを決めているのですが、見かけ上は「D13」を指定して命令を出しています。
ちょっとややこしくて難しいですね。
マイコンのピン名称はぱっと見で分かりませんが、D13はボードに書いてあるので開発のときにイメージしやすいのかもしれません。
ピンやピンヘッダについてちゃんと理解するには電子回路の勉強が必要そうなので、今回はここまでにしておきます。
***
プログラミングとは何ぞや?という状態から始まりましたが、
寄り道しつつ、なんとか書いてあることを理解することが出来ました。
読み取るのが精一杯で、プログラムを1から書いている人は本当にすごいなと思います。
果たして私のトレーニングトレーサーはトレースできるようになるのか…!?
次回もサンプルプログラムのお世話になり、ブザーを鳴らしたり、スイッチを活用していきます。
Part.7へつづく