第26回 Raspberry PiのGPIOを制御する (Python編)

今回はPythonを使ってLEDの制御やスイッチの読み取りを行ってみます。PythonにはRPi.GPIOというGPIO制御用のパッケージが用意されていますので、それを使用してGPIOの制御をしてみます。

今回の説明内容

今回はPythonを使ってRaspberry PiのGPIOピン制御をしてみます。PythonでRaspberry PiのGPIOを制御するには、Python Software FoundationからリリースされているRPi.GPIOという制御パッケージを利用します。

このパッケージですが、以前のRaspbianディストリビューションでは別途インストールする必要がありましたが、Jessiのリリースからデフォルトでインストールされているようです。ということでPythonのプログラムの最初でこのパッケージをインポートすればすぐに使えます。

なお前回も書きましたが、プログラミングの基本的な説明はしませんのでご了承ください。また、Pythonについては一部簡単に説明しますが、詳細については書籍などを参照いただければと思います。

今回の説明内容は以下になります。

  • 前提とする知識
  • Pythonを実行する方法
  • PythonでGPIOを制御する
  • PythonでLEDを制御する
  • Pythonでスイッチ状態を読み取る
  • LEDの点灯とスイッチのテストプログラム

 

前提とする知識

これからPythonでプログラムを作成してRaspberry PiのGPIOを制御していきますが、いずれかのプログラミング言語でプログラムを作成したことがあることを前提としています。

前回はPHP、今回はPythonを使用しますが、どのプログラミング言語でもでてくる、変数、型、配列、条件判断文、繰り返し構文、関数などについて、一つのプログラミング言語で理解できていれば、PHPやPythonもいけると思います。

前回も書きましたが、実は自分はPHPとPythonの経験がほとんどないんです。PHPは、このサイトをWordPressで構築している関係で、必要に迫られて必要なところを勉強した程度、PythonはRaspberry Piの標準言語となっていることもあり、サンプルがPythonのものが多いので、それを見たことがある程度、って感じです。

ってことで、今回もお読みいただいている方々を不安に陥れたところで、説明を始めましょう!

 

Pythonを実行する方法

Pythonはインタープリタ型と呼ばれるプログラミング言語で、プログラム、つまりソースコードをそのまま実行していきます。例えばPHPで「Hello, world!」と画面に表示するプログラムを作成した場合、以下のようにソースコードがそのまま実行されます。

インタープリタ型に対して、コンパイラ型がありますが、これらの用語は前回の説明をご確認いただければと思います。

インタープリタ型のPythonは、プログラムを入力してすぐに実行結果を確認することができます。まずはその動作確認をしてみましょう。

Raspberry Piにssh接続したら、コマンドプロンプトから python と入力します。

pi@raspberrypi ~ $ python
Python 2.7.9 (default, Mar  8 2015, 00:52:26) 
[GCC 4.9.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> 

というように >>> と表示されて入力待ちの状態となります。ここにPythonのコードを入力してリターンキーを押すと、すぐに実行されて結果が表示されるものはその結果が表示されます。お決まりという感じですが、Hello, world! と表示させてみましょう。何か表示する場合は「print」を使用します。

pi@raspberrypi ~ $ python
Python 2.7.9 (default, Mar  8 2015, 00:52:26) 
[GCC 4.9.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> print "Hello, world!"
Hello, world!
>>>

終了するには exit() と入力するか、Controlキー + Dを押します(Control + DはLinuxでは入力の終了を意味します)。

これでPythonの動作確認はできましたが、実際にはPythonでソースコードを書いてそれを実行することになります。Pythonのソースコードのファイル名は、拡張子が py とするのが一般的ですので、例えば test.py というファイル名でプログラムファイルを作成します。

それでは、動作確認用に「Hello, world!」と表示するPythonのソースコードファイルを作成します。エディタで以下の内容の、ファイル名が test.py というファイルを作成します。

print "Hello, world!"

ファイルを作成したら保存します。

作成したソースコードファイルの実行方法は2通りあります。

ひとつはpythonコマンドを使う方法で、test.pyを実行したい場合は、

pi@raspberrypi ~ $ python test.py

と入力して実行します。それでは実際に試してみましょう。

pi@raspberrypi ~ $ python test.py
Hello, world!
pi@raspberrypi ~ $ 

Hello, world!と表示されましたか。何かエラーになったり表示されない場合はもう一度ソースコードを確認してみてください。

プログラムを実行するもうひとつの方法は、test.py自体を実行するというものです。test.py自体を実行する、というのはちょっとわかりづらいかもしれませんが、例えばディレクトリの内容を表示する「ls」コマンドは「ls」というファイルを実行しています。この「ls」と同様に「test.py」を直接実行しよう、というわけです。

test.pyを直接実行するには、以下の知識が必要になります。ここの部分は前回のPHPの説明と同じですので、読み飛ばして頂いて問題あまりせん。なお、読み飛ばす場合、最初の行はPythonの場合、

#!/usr/bin/python

になる点にご注意ください。

(2016年6月11日追記)

ソースコードが正しくてもエラーになる報告をコメントでいただきました。エラーは以下のような内容です。

-bash: ./test.php: /usr/bin/php^M: 誤ったインタプリタです: そのようなファイルやディレクトリはありません

このエラーが発生した場合は、エディタの設定を確認してみてください。確認方法は以下の補足記事で説明しています。

第25回補足 「/usr/bin/php/^M: 誤ったインタプリタです」の対策

(2016年6月11日追記ここまで)

  • 起動コマンドの設定
  • ファイルの実行権限
  • .と..
  • ユーザディレクトリの実行ファイルの実行方法

それではひとつずつ説明していきます。

Linuxでは先ほど作成したPythonなどのソースコードのファイル(スクリプトファイルとも呼びます)そのものを実行する場合、そのファイルをどのコマンドで実行するか指定しておく必要があります。test.py は python コマンドで実行しますので、ファイルの先頭に「pythonコマンドで実行してください」って書いておく必要があります。この書き方は、先頭は「#!」ではじめ、その後にコマンドを書きます。Raspbianではpythonは /usr/bin/ディレクトリにありますので、以下のように書くことになります。

#!/usr/bin/python

print "Hello, world!"

これでファイルの起動コマンドの設定が終わりました。なおこのような記述を追加しても python test.py というようにpythonコマンドでも実行できます。

次にファイルの実行権限です。

かなり前の説明なので忘れてしまったかもしれませんが、ファイルのアクセス権について復習します。詳しくは第11回の説明をご確認いただくことにして、ここでは簡単に復習しておきます。

ファイルのアクセス権ですが、ls -l コマンドで確認することができます。このアクセス権は以下のような意味を持っていることを説明しました。

Access rights

それでは、先ほど作成した test.py のアクセス権を確認してみましょう。

pi@raspberrypi ~ $ ls -l test.py
-rw-r--r-- 1 pi pi 23 12月 20 08:01 test.py

ということで、このファイルは実行権限がないですよね。このファイルを直接実行するには実行権限をつけてしまえばOKです。

ファイルのアクセス権を設定するには、chmod (Change Mode)コマンドを使用します。chmodコマンドのパラメータはたくさんあるのでここでは最低限のものを説明します。

何か権限を追加する場合は「+」、削除する場合は「-」を指定し、その後に読み取り(r)、書き込み(w)、実行(x)などの種類を指定します。ここでは実行権限を追加しますので、バラメータは「+x」となります。test.py に実行権限を追加するには以下のようにします。

pi@raspberrypi ~ $ chmod +x test.py

実行権限が追加されたか確認してみましょう。

pi@raspberrypi ~ $ ls -l test.py
-rwxr-xr-x 1 pi pi 23 12月 20 08:01 test.py

「x」がついて実行権限がつきましたよね。それでは「ls」コマンドのように実行してみましょう!

pi@raspberrypi ~ $ test.py
-bash: test.py: コマンドが見つかりません

ファイルの実行権限が付いているのに実行できないとはどういうことなんでしょうか。この原因を理解するには、コマンドの「パス」という概念を理解する必要があります。今まで「ls」とコマンドを入力してディレクトリの内容を確認していましたが、lsコマンドは実際には /binディレクトリにあります。正確には「/bin/ls」と入力する必要がありますが、毎回「/bin/ls」と入力するのも面倒ですし、そもそもどのコマンドがどのディレクトリにあるかなんて覚えてられないですよね。ということで、ユーザがコマンドを入力した時、どのディレクトリを探すか、というコマンドを検索するパスの設定がされています。ではRaspbianではどのディレクトリがコマンドのパスになっているのでしょうか。このコマンドのパスは「$PATH」という変数に格納されていて、echoコマンドで内容を確認することができます。以下のように入力してみてください。

pi@raspberrypi ~ $ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/games:/usr/games

こんな感じで表示されましたでしょうか。パスは複数設定されていて「:」(コロン)で区切られています。test.pyはどこにあるかというと、ホームディレクトリに作成したと思いますので、「/home/pi」ディレクトリにあります(pwdコマンドで確認できますよね)。でも/home/piディレクトリはこのパスのリストにはありませんよね。

ということで、test.pyに実行権限を設定しても、このtest.pyがコマンドパスにはないので「コマンドが見つかりません」といってきたわけです。

解決方法としては、/home/piをコマンドパスに追加する方法がありますが、これはLinuxでは避けるようになっています。理由としてはセキュリティの問題からこのようになっています。

例えば、悪意のあるユーザやウェブサイトが、ユーザのホームディレクトリに、すべてのファイルを削除する「ls」というコマンドを仕込んだとします。コマンドパスにユーザディレクトリがあり、それが優先されるようになっていると、ユーザがディレクトリの内容を確認しようとして「ls」と入力しただけで、先ほどのすべてのファイルを削除する「ls」が実行されてしまい、すべてのファイルが削除されてしまいます。このような状況を避けるためにユーザディレクトリはコマンドパスに含まれていませんので、ユーザディレクトリにある実行ファイルを実行するには、パスを指定する必要があります。

ホームディレクトリは「/home/pi」ですので、以下のように入力すればtest.pyが実行できます。

pi@raspberrypi ~ $ /home/pi/test.py
Hello, world!

でもこれだとパスの入力が面倒ですよね。そこでもうちょっとだけ入力を簡略化する方法があります。lsコマンドで「-l」オプションを指定すると不可視ファイルなども見ることができます。「ls -l」と入力してみましょう。

pi@raspberrypi ~ $ ls -l
.	     .anthy	    .bashrc.bak  .gconf	   .scratch		 Desktop    Public	 ledpanel
..	     .asoundrc	    .cache	 .gstreamer-0.10  .themes		 Documents  Scratch	 python_games
.DS_Store   .bash_history  .config	 .local	   .vnc		 Downloads  Templates  test.php
.Xauthority  .bash_logout   .dbus	 .php_history	   .xsession-errors	 Music      Videos
._.DS_Store  .bashrc	    .emacs.d	 .profile	   .xsession-errors.old  Pictures   dev

表示内容は異なると思いますが、左上の方に「.」と「..」というものがありますよね。設定によっては「./」や「../」と表示されているかもしれません。/はディレクトリであることを意味しています。

この「.」と「..」ですが、これは以下を意味しています。

記号 意味
. 現在のディレクトリ
.. 一つ上のディレクトリ
(親ディレクトリ)

「.」は今いるディレクトリを意味していますので、test.pyを実行するには、「今いるディレクトリのtest.py」という意味で、以下のように実行すればよいことになります。

pi@raspberrypi ~ $ ./test.py
Hello, world!

Linuxでは、一般的にユーザが作成したプログラムは、「./ファイル名」と入力して実行しますので、このシリーズでもこの慣例に従うことにします。

これでPythonのプログラムファイルを実行する準備ができました。

 

PythonでGPIOを制御する

PythonでRaspberry PiのGPIOを制御するには、最初に説明しましたが「RPi.GPIO」というパッケージを使用します。使用するには、Pythonのプログラムの先頭で、このパッケージを使用します、っていう宣言をすればOKです。以下のようなコードです。

import RPi.GPIO as GPIO

このコードについて説明します。

importはパッケージ(モジュール・ライブラリ)を読み込む命令で、

import RPi.GPIO

と書くと、RPi.GPIOパッケージを読み込みます。

RPi.GPIOには、例えば、GPIOの入出力を設定するための「setup()」という関数がありますが、この関数を使用するには、

RPi.GPIO.setup()

というようにドット(.)で呼び出します。ただ、毎回 RPi.GPIO と書くのは長くなりますので、importする際に別名をつけておきます。別名は「as 別名」で指定します。

import RPi.GPIO as GPIO

このように書くと、RPi.GPIO.setup()の代わりに

GPIO.setup()

で呼び出すことが可能になります。

それではGPIO制御に必要な、以下のRPi.GPIOの関数を確認します。

  • GPIO番号指定モードの設定
    今まで何度も出てきましたが、GPIOを指定するにはGPIO番号やボードのピン番号など複数あります。この番号指定方法を設定します。
  • GPIOの入出力の設定
    GPIOを入力にするのか出力にするのか、またプルアップ、プルダウン抵抗の設定もできます。
  • GPIOの出力制御
    GPIOピンを出力モードに設定したら、出力を0か1を指定することにより、0V、3.3Vに制御できます。
  • GPIOの入力読み取り
    GPIOピンを入力モードに設定したら、ピンの電圧状態を0か1で読み取ることができます。
  • GPIOの設定リセット
    GPIOを使い終わったら、GPIOの設定をリセットできます。

GPIO番号指定モードの設定

GPIO番号の指定方法を2通り設定できます。一つはGPIO番号(つまり今まで使ってきましたBroadcomプロセッサのGPIOピン番号)と、もう一つはボードのピン番号です。それぞれ以下のように設定します(importはRPi.GPIO as GPIOで指定したものとします)。なお「#」以降、行末まではコメントになります。

GPIO.setmode(GPIO.BCM)   # GPIO番号指定
GPIO.setmode(GPIO.BOARD)   # ボードピン番号指定

GPIOの入出力の設定

GPIOピンを制御する前に、出力ピンなのか入力ピンなのか指定する必要があります。指定方法は以下のフォーマットです。

GPIO.setup(ピン番号, GPIO.OUT)   # 出力指定
GPIO.setup(ピン番号, GPIO.IN)   # 入力指定

例えば、GPIO21ピンを出力に指定するには以下のよう書きます。

GPIO.setup(21, GPIO.OUT)   # GPIO21番ピンを出力指定

GPIOの出力制御

GPIOピンの入出力モードを設定した後、ピンの制御を行うことができます。出力の制御は以下のフォーマットになります。

GPIO.output(ピン番号, 1)   # ピンの出力を3.3Vにする
GPIO.output(ピン番号, 0)   # ピンの出力を0Vにする

例えば、GPIO21ピンを3.3V出力に指定するには以下のよう書きます。

GPIO.output(21, 1)   # GPIO21番ピンを3.3V出力にする

GPIOの入力読み取り

GPIOピンの電圧状態を読み取る場合、以下のフォーマットとなります。

GPIO.input(ピン番号)   # ピンの電圧状態読み取る

実際にはピンの電圧状態が返ってきますので、結果を変数に入れたり表示します。

print GPIO.input(ピン番号)   # ピンの電圧状態を表示する

GPIOの設定リセット

GPIOを使い終わったらGPIO設定をリセットします。以下のフォーマットになります。

GPIO.cleanup()   # GPIO設定をリセット

それではこれらのRPi.GPIOパッケージを使ってGPIO制御をしてみましょう。

 

PythonでLEDを制御する

これからプログラムを作成していきますが、前回のPHPの時と同様に、第13回で開発用にディレクトリを作成しましたので、「dev」ディレクトリを使用します。ディレクトリを作成していない場合は、mkdirコマンドで作成します。devディレクトリを作成する場合は、「mkdir dev」です。

それではdevディレクトリに移動しましょう。

pi@raspberrypi ~ $ cd dev
pi@raspberrypi ~/dev $ 

まず、GPIO21に接続しているLEDを1秒間点灯させてみます。なお、一定時間待つには、timeモジュールのsleep()関数を使用しますので、RPi.GPIOとtimeをインポートしています。sleep()関数の引数は秒で、time.sleep()で呼び出します。

また、プログラムファイルに日本語でコメントを書きます。この場合、エディタでエンコーディングをUTF-8にする以外に、プログラムでもUTF-8を使ってます、って宣言する必要があります。「# coding: utf-8」と記述します。

#!/usr/bin/python
# coding: utf-8

# モジュールをインポートする
import RPi.GPIO as GPIO
import time

# GPIO指定をGPIO番号で行う
GPIO.setmode(GPIO.BCM)

# GPIO21ピンを出力モードに設定
GPIO.setup(21, GPIO.OUT)

# GPIO21番ピンを3.3Vに設定
GPIO.output(21, 1)

# 1秒待つ
time.sleep(1)

# GPIO21番ピンを0Vに設定
GPIO.output(21, 0)

# GPIO設定をリセット
GPIO.cleanup()

これがLED点滅制御の基本プログラムとなります。

 

Pythonでスイッチ状態を読み取る

GPIOピンのスイッチの状態は、ピンの入力状態を調べるGPIO.input()関数でわかります。GPIO.input()の値を表示すれば良いので、先ほど説明しました通り、print GPIO.input()でOKです。

スイッチのテストをするために別のファイル、例えば switch.py などの名前でファイルを作成します。

#!/usr/bin/python
# coding: utf-8

# モジュールをインポートする
import RPi.GPIO as GPIO
import time

# GPIO指定をGPIO番号で行う
GPIO.setmode(GPIO.BCM)

# GPIO18ピンを入力モードに設定
GPIO.setup(18, GPIO.IN)

# GPIO18ピンの入力状態を表示する
print GPIO.input(18)

# GPIOピンをリセット
GPIO.cleanup()

先ほどと同様に、switch.pyに実行権限を追加して「./switch.py」で実行します。実行するとき、スイッチを放した状態にしたり、押した状態にしたりして値を確認してみてください。

これで、スイッチの状態を読み取る事ができるようになりました。

 

LEDの点灯とスイッチのテストプログラム

それでは、全LEDの点灯テストとスイッチの状態を読み取るテストプログラムを作成してみましょう。テスト内容ですが、最初にLEDを順番に1秒間ずつ点灯させていき、最後にスイッチを1秒ごとに3回読み取る、ということにしたいと思います。

なお、Pythonで指定回数、処理を繰り返すには、以下の構文を使用します。

for 変数 in range(範囲):
    処理

このfor構文について補足しておきます。

Pythonでは、for文やwhile文などで処理するコードの書き方が他の言語とはちょっと違います。CやPHPなどでは

for(i=0; i<3; i++) {
   処理1;
   処理2;
}

のように、forやwhileで処理するコードは{ }などで囲っています。Pythonでは、処理するコードをインデントするだけです。以下のコードでは、

for 変数 in range(範囲):
    処理1
    処理2
処理3

for文で処理されるのは処理1と処理2で、処理3はfor文処理の後に実行されます。

また、範囲は以下のように書きます。

range(開始, 回数)

例えば、

range(0, 3)

と書けば、0から開始して3回、つまり0, 1, 2という範囲になります。

まとめると、

for num in range(0, 3)

と書くと、numに0, 1, 2と代入して3回繰り返しとなります。PHPで同じ処理を書くと、

for($num=0, $num<3; $num++)

となります。

それでは、最初は素直にプログラムを書いてみます。

#!/usr/bin/python
# coding: utf-8
 
# モジュール使用宣言
# GPIOモジュールとtimeモジュールをimport
import RPi.GPIO as GPIO
import time
 
# GPIO番号指定をBCM(GPIO番号)に設定
GPIO.setmode(GPIO.BCM)
 
# GPIOの初期化(LED)
GPIO.setup(21, GPIO.OUT)
GPIO.setup(20, GPIO.OUT)
GPIO.setup(16, GPIO.OUT)
GPIO.setup(12, GPIO.OUT)
GPIO.setup(25, GPIO.OUT)
GPIO.setup(24, GPIO.OUT)
GPIO.setup(23, GPIO.OUT)

# GPIOの初期化(スイッチ)
GPIO.setup(18, GPIO.IN)
 

try:
    # LEDを順番に点灯させる
    # 晴れ用LED
    GPIO.output(21, 1)
    time.sleep(1)
    GPIO.output(21, 0)

    # 曇り用LED 
    GPIO.output(20, 1)
    time.sleep(1)
    GPIO.output(20, 0)

    # 雨用LED
    GPIO.output(16, 1)
    time.sleep(1)
    GPIO.output(16, 0)

    # 雪用LED
    GPIO.output(12, 1)
    time.sleep(1)
    GPIO.output(12, 0)

    # 鉄道運行表示用 緑LED
    GPIO.output(25, 1)
    time.sleep(1)
    GPIO.output(25, 0)

    # 鉄道運行表示用 青LED
    GPIO.output(24, 1)
    time.sleep(1)
    GPIO.output(24, 0)

    # 鉄道運行表示用 赤LED
    GPIO.output(23, 1)
    time.sleep(1)
    GPIO.output(23, 0)

    # GPIO18ピンのスイッチ状態を表示
    for num in range(0, 3):
        print GPIO.input(18)
        time.sleep(1)

finally:
    # GPIOピン設定リセット
    GPIO.cleanup()

ほとんど解説するところはないと思います。一点、今まで出てこなかった、25行目のtry:と67行目のfinallyを簡単に説明しておきます。

try:とfinally:は対になっています。

25行目のtry:は次の行以降、インデント部分が対象になります。具体的には26行目から65行目までがインデントされていますので、try:はこれらの行が対象になります。同様にfinally:は68行目と69行目が対象になります。

ではtry:とfinally:は何をするかというと、try:の対象部分を実行中、何か例外処理が発生した場合、finally:の処理を行います。例えば、try:の対象部分を実行中に、Control+C(処理中断)が押された場合、処理を中断してfinally:の処理を行います。なお、finally:の対象部分はtry:の処理が何事もなく終わった場合でも処理されます。

ところで、前回のPHPと同様、このプログラムはメンテが大変ですよね。LEDの位置が変わったり、個数が変わったり、LEDの点灯順番を変えたりすると結構いろいろ変更するところが出てきてしまいます。そこで、GPIO番号は最初に変数(LEDはリスト)として定義して、その変数を使用して制御するように書き換えました。コードの後に説明が必要な行について解説してあります。

またコメントの書き方は、本来でしたら ”’ (シングルクウォート3個)を使ったほうがよさそうですが、前回のPHPのプログラムを一部コピペしたのでこのようになっています。

#!/usr/bin/python
# coding: utf-8
 
# ------------------------
#   モジュールインポート
# ------------------------
# GPIOモジュールインポート
import RPi.GPIO as GPIO
# timeモジュールインポート
import time
 
# ----------------------------
#   GPIO番号の定義(GPIO番号)
# ----------------------------
# GPIOの番号の定義(LED)
gpioLed = (21, 20, 16, 12, 25, 24, 23)

# GPIOの番号の定義(スイッチ)
gpioSwitch = 18

# ------------------
#   GPIOモード設定
# ------------------
# GPIO番号指定をBCM(GPIO番号)に設定
# ボードピン番号に設定する場合は GPIO.setmode(GPIO.BOARD)にする
GPIO.setmode(GPIO.BCM)
 
# GPIOの初期化(LED)
GPIO.setup(gpioLed, GPIO.OUT)

# GPIOの初期化(スイッチ)
GPIO.setup(gpioSwitch, GPIO.IN)
 

# -------------------------
#   LEDを配列の順番で点灯
# -------------------------
try:
    # 最初のLEDのGPIO番号を配列から取得して点灯させる
    # 点灯後は1秒間そのままにする
    currentLed = gpioLed[0]
    GPIO.output(currentLed, 1)
    time.sleep(1)

    # gpioLed配列の残りの要素を取得する
    restGpioLed = gpioLed[1:]

    # 残りの要素について順次点滅制御する
    for nextLed in restGpioLed:
        # 現在点灯しているLEDを消灯させる
        GPIO.output(currentLed, 0)
        # 次のLEDを点灯させる
        GPIO.output(nextLed, 1)
        # 点灯させたLEDのGPIO番号を現在のLED番号にする
        currentLed = nextLed
        # 1秒間そのままにする
        time.sleep(1)

    # 最後のLEDを消灯する
    GPIO.output(currentLed, 0)


    # ------------------------------------
    #   スイッチの状態を1秒ごとに3回表示
    # ------------------------------------
    for num in range(0, 3):
        print GPIO.input(gpioSwitch)
        time.sleep(1)

# ---------------
#   GPIOリセット
# ---------------
finally:
    GPIO.cleanup()

16行目
LEDを接続しているGPIO番号をリスト(配列)に入れておきます。GPIOの初期化や出力制御はこのリストを使って行います。順番が変わった場合やLEDを増やした場合はこのリストのみを編集すればいいようにしておきます。

19行目
スイッチは一つしかありませんので、変数に入れておくだけにします。

29行目
GPIO.setupでGPIO番号を指定しますが、リストを指定することも可能です。このように書くとプログラムがすっきりしますね。

46行目
PHPのプログラムでは、配列の次の要素をnextで取り出していましたが、Pythonではリストの次の要素を取り出す仕組みが見当たらなかったので、gpioLedのリストの残りの要素を取り出し、それを処理していことにしました。

これでPytonでのLEDの点滅制御、スイッチ状態の読み取りができるようになりました。

« »

  • Greg Sanders

    winのTeraPadでPythonのコード作成して、CyberduckでPIにアップして、TeraTermで実行すると、

    #!/usr/bin/python: そのようなファイルやディレクトリはありません
    Error: no such file “Hello, world!”

    この様なエラーが出ました。
    色々調べると、文字コードをUTF-8Nで保存しアップしたら、
    エラーが出ずに実行できました。

    UTF-8はBOM付でUTF-8NはBOM無しみたいです。

    • claynets

      Greg Sandersさん、
      コメントどうもありがとうございました!

      TeraPadでUTF-8で保存するとBOMありになるんですね。すみません、第25回の説明で、TeraPadではUTF-8を選択するような説明をしていますが、これは間違いですね。失礼しました。

      BOM無しにするためにUTF-8Nを選択する必要がある、ということで記事を修正しておこうと思います。スクショ撮り直しなので時間があるときに修正いたします。

      ご指摘いただきどうもありがとうございました!

  • kazuooooo

    RasberryPiを始めるにあたり説明がとてもわかり易く、非常に参考になっています。ありがとうございます!(特に電気回路周りの説明は自分が中学校のころに丸暗記していたところが腹落ちしました^^)

    今回の内容で少しコードの方で気になったのですがループ処理の箇所ですが特に理由が無ければ

    ```
    try:
    for currentLed in gpioLed:
    GPIO.output(currentLed, 1)
    time.sleep(1)
    GPIO.output(currentLed, 0)

    for num in range(0, 3):
    print GPIO.input(gpioSwitch)
    time.sleep(1)
    ```

    のほうがシンプルでよいかと思いました。

    また沢山投稿していただけるのを楽しみにしています!

    • claynets

      kazuoooooさん、コメントどうもありがとうございました。

      この記事はかなり前に書いたので、いただいたコメントのプログラムと自分のプログラムを比べて見ましたが、コメントいただいたプログラムの方が全然素直でシンプルですし、こうすべきだと思います。

      自分のプログラムを見てみると、なんでこんな複雑な書き方してるんだろう、って思いました…笑

      このRaspberry Pi電子工作入門ですが、Raspberry Pi本体の説明や、Raspbianのインストールあたりはかなり古い内容になっていますので、更新しなければ、、、と思いつつ時間ばかり過ぎてしまっています。

      時間を見つけて古い内容は更新いたしますので、今後ともよろしくお願いいたします。