この一連の記事は、サバフェス2016に参加した門外漢のいなばがいろいろやってみたメモを残し、「同じくらいに初心者」な方の何かの参考になれば、というスタンスで書いています。
昨日はサバフェス2016のハンズオンで、ESP8266を使ってイロイロ遊んできたわけですが、今日からは(というかできれば今日中に)ラズパイ2で課題を仕上げちゃいたい気持ちです。
てことで、初めて触るラズパイ2に慣れようということで、まずはLEDを光らせてみようと思います。
まずはLピカ
どうやらこの界隈では、Hello World的にLEDを光らせるのが流儀のようです。とは言え、LEDを「点けたり消したり」はある程度のプログラムが絡むので、まずはラズパイ2そのものに慣れるということで、Lピカ(LED点きっぱなし)を試してみます。
ラズパイ2のGPIO
ラズパイ2の基盤で存在感を放っている、黒いプラスチックから金色のピンがわさわさ生えている部分を、GPIOと言います。GPIOは「General Purpose Input/Output」の略で、日本語にするなら「汎用的に使える入出力」でしょうか。要は、ラズパイ2と外の世界をつなぐための口になっていて、ここにイロイロなものを繋げられるわけです。
上の写真(公式から拝借)に写っているのがGPIOです。なお、USBポートが右側に来る向きになっています。
GPIOは、Generalと名前がついていますが、それぞれのピンには、予め設定された役割があります。これを示したのが下の画像(こちらも公式から拝借)です。
初めて見るとなんのこっちゃいという感じですが、ピンの色で分けて考えます。
オレンジ色のピン(下段左端と、下段左から9番目)は、電源(プラス)だと思えば良さそうです。このピンからは、プログラムとは無関係に常時3.3vの電力が供給されています。なので、外部に接続するものにこれらのポートから繋いであげれば3.3vの電力を供給してやることが出来ます。
赤いピン(上段左側2列)は、オレンジのピンと同じような役割を果たしますが、こちらは出力しているのが5vになります。とりあえずここでは細かいこと考えずに「ラズパイ2からは電力を供給できるポートがあって、3.3vと5vがある」とだけ認識しておけばよいかと思います。
電力関係が続きます。黒いピン(場所は割愛。全部で8本)は、Groundと書いてあります。これは、オレンジのピン(3.3v)や赤いピン(5.5v)から供給した電力の終着地点(マイナス)になります。私自身電気関係弱いので、ザックリした説明になりますが、LEDを光らせたり、センサーを動かしたりする電力は、プラスから出て「お仕事するもの(LEDとかセンサーとか)」を通ってマイナスに入ってくる輪っかを形成します。
普段の生活の中で電気を使うときは「コンセントを差す」といった「電源をつなぐ」だけでその先の機械が使えるので、そことの考え方のギャップがありますが、「プラスから出てマイナスに入る輪っかの途中に仕事をする部分がある」という基本的な構成は覚えておく必要があります。
さて、ピンの話に戻ります。
一番たくさんある薄い黄色のピンはGPIOと書いてあります。これらのピンが、外部の機器との入出力を行うためのピンです。全部で26本あります。これらのピンに対して、プログラムから出力をしてあげると3.3vの電圧をかけることが出来ます。また、これらのピンに対して、外部の機器から、3.3vまでの電圧をかけてもらって情報を受け取ることも出来ます。
LEDを点けっぱなしにする
ようやく本題です。
LEDをチカチカするのは後でプログラムにやってもらうとして、ここでは「ラズパイ2から電力をもらってLEDを常時点灯する」事を考えます。
つまり、3.3vを出力するポートから電力供給を受けて、LEDを通ってGROUNDに戻ってくるような回路をブレッドボード上に作ってあげればいいわけです。
以下の様な感じになります。
電気は、ラズパイ2の3.3vの口から出て、ブレッドボードの最上段に入ります。これが抵抗を通り、LEDを通ってブレッドボードの最下段に入ってラズパイ2のGROUNDに戻っていきます。
これを組み立てるとLEDが常時点灯するはずです。うまくいったらおめでとうですが、この時点ではラズパイ2はただの電源に過ぎません。ここからが本題だ!
LEDをチカチカさせる
さて、LEDの常時点灯が出来たので、いよいよ本題の、Lチカです。
ラズパイ2につないだLEDをチカチカさせるには、以下の二つを満たす必要があります。
- 常時供給される電源ではなく、プログラムによって出力を制御できるポート(GPIOのピン)からLEDに電気を流す
- プログラムは、一定の間隔でポート(GPIOのピン)に電気を流したり止めたりする
配線する
まず、LEDが電気をもらう口を変えましょう。わかりやすく上段右端のポートを使うことにします。
つなぎ方はこんな感じになります。赤い一番長いケーブル以外は変更する必要はありません。
電力をもらっている線(赤くて長いやつ)の出所が変わっているのが分かるかと思います。
この時点では、このポートは電力を供給していないので、LEDは消えているはずです。
プログラムから制御する
このポートに電気を流したり止めたりするとLEDがチカチカするはずです。
ところで、先ほど繋いだポートは、プログラムからはどう扱うのでしょう。
先ほどの画像を再掲します。
今回は、上段右端のポートを使っています。ここは、21番という番号を持っています。これ、覚えておく必要があります。
プログラムは以下の様な感じになります。詳しい説明はここでは省きます。
(http://www.hiramine.com/physicalcomputing/raspberrypi/rpigpio_blink.html を参考にさせていただきました)
#!/usr/bin/python import RPi.GPIO as GPIO import time GPIO.setwarnings(False) GPIO.setmode(GPIO.BCM) GPIO.setup(21, GPIO.OUT) while 1: GPIO.output(21,True) time.sleep(1.0) GPIO.output(21,False) time.sleep(1.0)
一行ずつ説明します。
一番上の「#!/usr/bin/python」は、ラズパイ2に入っているpython処理系の場所を示しています。とりあえず深く考えなくていいです。
その下2行の「import 〜」は、ラズパイのGPIOを扱うライブラリと時間を扱うライブラリを読み込んでいます。
GPIO.setwarnings(False)は、以前に実行したGPIOポートの状態が残っていた時に出力される警告文を抑制するもので、ここでは深く考えなくて大丈夫です。
GPIO.setmode()は、プログラムからGPIOポートの特定のピンを指定するときにどのように指定するかを決める命令です。ここではGPIO.BCMになっているので、ポートの「役割の名前」で指定する命令を出しています。ここで言う「役割の名前」は先程の画像で、LEDに電力を供給するピンを「21番のピン」に挿したことと関連します。
GPIO.BCMを指定せずに、ピンの物理的な配置で指定することも出来ますがここでは割愛します。
GPIO.setup(21,GPIO.OUT)は、21番ピン(ほら、ここで「21番」でピンを指定しています)を、電力の出力用に設定するように指示しています。入力専用、入出力兼用も出来ますがここでは割愛します。
次の行からがループになっています。
while は、続く条件式が正である限り、ブロックの中の命令を繰り返します。ここでは条件式として 1 を指定しています。1は常に正と判定されるので、このプログラムを実行すると、このループの中をずーっと繰り返す事になります。
では、ブロックの中を見てみましょう。
わかりやすく行を空けていますが、2つずつの命令がセットになっています。
まず、GPIO.output(21,True)は、21番ピンに対して出力をTrueにしています。これはつまり、21番ピンに「電気を流す」ということです(おお!ついにLEDに電気が通る!)。
次の、time.sleep(1.0)は、ここで1秒休む、という意味になります。time.sleep()に数値を渡してやると、指定された秒数分だけプログラムがとまります。
GPIO.output(21,False)は、21番ピンに対して出力をFalseにしています。これはつまり、21番ピンに対して「電気を流さない」ということです。つまり、先ほどの「GPIO.output(21,True)」で電気を供給されて光っていたLEDが消えることになります。
そして、先程と同じく1秒休みます。
ここでループが終わるので、ループの先頭に戻り、21番ピンの出力がTrueになり、1秒休んで…となり、LEDがチカチカすることになります。
やってみる
上記のプログラムをコピペしてラズパイ2で実行します。
SSHで繋いで、
vim sample.py
としてコピーしたプログラムを貼り付け、「エスケープキー、コロン(:)、wq」として保存してやります。(viおよびvimの使い方については割愛します)
出来た sample.py はこのままでは実行できないので、
chmod a+x sample.py
として実行権限を付けてやります。
実行権限をつければ、
./sample.py
として実行すると、LEDがチカチカしだすはずです。
やったー\(^o^)/\(^o^)/\(^o^)/
あとは、time.sleep()の値を変えて、チカチカのスピードを変えたりして遊べます。
少しだけ抽象度を上げてみる
先ほどのプログラムでもひとまずLチカできたわけですが、ちょっと気になることがあります。
先ほどの書き方では、あとから何かの事情でLEDに電源供給するピンを21番以外にした場合、三箇所(直接「21」を指定している箇所)の修正が必要になります。
この程度であれば手作業で直してもいいのですが、プログラムが大きくなってきたらかなり厳しくなります。
そこで、「21番ピン」という具体的な指定ではなく、「LEDに電源供給するピン」という形で抽象化し、ピンの変更に簡単に対応できるようにします。
#!/usr/bin/python import RPi.GPIO as GPIO import time GPIO.setwarnings(False) GPIO.setmode(GPIO.BCM) LED_PIN = 21 GPIO.setup(LED_PIN, GPIO.OUT) while 1: GPIO.output(LED_PIN,True) time.sleep(1.0) GPIO.output(LED_PIN,False) time.sleep(1.0)
キモは、LED_PIN=21 という箇所、および、GPIO.setup()やGPIO.output()で「LED_PIN」という名前を使っている箇所になります。
上記の修正を加えると、別のピンにつなぎ変えた場合、「LED_PIN=21」の箇所だけ修正すればいいので非常にメンテナンスしやすくなります。
なお、LED_PIN=21の部分、左側の「LED_PIN」は単なる変数の名前なので、自由につけて構いません。
まとめ
さて、Lチカできて、なんとなくラズパイとも仲良くなれてきた気がします。次は、各種センサーを付けて、情報を受け取ってみたいと思います。
コメント