FC2ブログ

ラズパイ4で初心者による初心者のためのLチカ(7)

前回、PythonのプログラムでGPIO制御をやってみようとしたら、そのための準備としての「RPi.GPIO」ライブラリのアップデートとアップグレードで終わってしまいました。

今回はLチカの Pythonプログラムで、ブレッドボード上に配置したLEDを点滅させます。

LEDと抵抗を配置した回路をラズパイ4に接続しました。

LED配線

そして、ネット上で探して見つけたLチカ Pythonプログラムをコピペして「Run」(実は、このプログラムをどうやって走らせれば良いかも分からなかった)。

そしてブレッドボード上のLEDが点滅するのを見ようとしたら、なんかエラーが。

エラー12
6行目の「RPi が定義されていない」って言われているらしい。

そんなこと言われてもなー。3行目で import しているんだから、これで定義されているんじゃないのって思いながら、ネットで検索みると、解決策を見つけました。

どうやら、3行目の「import RPi.GPIO as GPIO」で「GPIO=RPi.GPIO」ってしているのだから、6行目の()の中は(RPi.RPi.GPIO.BCM)ってことになると。

簡単に言えば、6行目の RPi は不要ってことなので、削除して再び Run。

が、また違うエラーが。

エラー22
今度は5行目の xrange が定義されていない、と。

いやいや、xrange って普通に Linux のコマンドじゃないの?

これまた検索してみると、Pythonのバージョン違いによるエラーらしい。

Python3からは、xrange関数が廃止され range になったため、古いプログラムを現在のPythonのバージョンで動かすとこのようなエラーが出るとのこと。

なるほど。xrange を range に書き換えて、今度こそって思いながら Run。

ふー。またエラー、かな。

エラー3
なるほど、このエラーは分かるよう気がします。

プログラム終了時の後始末として GPIO.cleanup() を実行する必要があって、これを怠ると次にプログラムを実行したときに失敗するらしい。

でも、最後の行に入れているんだけど? って思いながら、もう一度 Run してみると、今度は通りました。前に残っていたものが、前回の Run でリセットされたんでしょう。

ということで、GPIO18に接続されているLEDが点滅しています。

LED点灯

やっと最初の一歩、でした。


ラズパイ4で初心者による初心者のためのLチカ(6)

前回までは LXTerminal に直接コマンドを書き込んでGPIOの制御を行ってきましたが、今回から Python でプログラムを組んで制御してみようと思います。

Python で GPIO を制御するためには、「RPi.GPIO」というライブラリが必要とのことですが、元々標準インストールされているのでアップデートするだけでOKらしい。

そしてアップデートするためのコマンドが以下の2行。「apt-get update」と「apt-get upgrade」になっていますが、この2つはセットで使うらしい。

$ sudo apt-get update
$ sudo apt-get upgrade

先ずは「update」で、自分のローカルデータベースのパッケージ情報を取得し、インストール可能なパッケージの「一覧」を更新する。

続いて「upgrade」で、update で取得した自分のパッケージ情報を元に、システムにインストールされているパッケージを最新バージョンにする。

ということで、先ずはアップデートから。

sudo apt-get update
これは数秒で終わりました。

続いてアップグレード開始。

upgrade

なんか、色々とやってる。

sudo apt-get upgrade1

長い。結局、全て終了するまで1時間近くかかりました。

sudo apt-get upgrade4

数日後、今回の記事を書くために改めて「apt-get」コマンドに関して調べていたら、今は(1年以上前から?)「apt-get じゃなくて apt コマンドが推奨される」って記述を発見。

ほー、そうですか。試してみました。

apt update

普通に実行できました。そればかりか、「アップグレードできるパッケージが29個あります」と。つい数日前に上で書いた通りアップグレードしたばかりなのに。

やってみました。アップグレード。apt コマンドで。

apt upgrade

一番下に、前回のアップグレード作業の時には(多分)無かった「進捗」が表示されてる。

進捗

10分少しでアップグレード作業終了。今回は、パッケージ数が少なかったのでしょう。

ってことで、今後は apt-get コマンドの代わりに apt コマンドを使うことにします。

今回は事前準備のパッケージのアップグレードだけで終わってしまいましたが、次回は Python でのプログラム作り(いや、コピペかな)にトライする予定。


ラズパイ4で初心者による初心者のためのLチカ(5)

前回というか、このシリーズの第1回~4回で echo コマンドを使って仮想ファイルに書き込むことで、Raspberry PiのGPIO制御を行ってきましたが、今回は別の方法について。

それは、WiringPi というRaspberry Pi のGPIOを制御するためのライブラリを使う方法。

前回、ラズパイでは1つのピンに3種類の呼称というか、ピン番号が振られているって話をしましたが、その一つがこの WiringPi のピン番号なんです。

因みに、これまた前回の話ですが、「gpio readall」を使おうとしたらエラーが出て、その際にアップデートしたライブラリもこの WiringPi ライブラリでした。

余談ですが、この前回のアップデート作業をしたからなのか、この後、特に何らかの作業をすることなく WiringPi ライブラリを使うことが出来ました。

その使い方ですが、「gpio」というコマンドがあり、これによって(echoコマンドと同様に)/sys/class/gpio/にある仮想ファイルにアクセスすることでGPIO制御を行います。

ただ、「echo」コマンドも「gpio」コマンドも同じように仮想ファイルにアクセスしますが、その記述フォーマットは「gpio」の方が断然スッキリしています。

実際に gpio コマンドを使う前に「gpio readall」でGPIOの状態を確認しておきます。

ここで物理番号(?)「16」と「33」に注目します。物理番号 16 のBCM番号は 23 で、wPi番号は4です。もう一方の物理番号 33 のピンのBCM番号は 13 で、wPi番号は 23。

wPiとBMC

さて、gpio コマンドの記述フォーマットは以下の様になります。

●GPIOピンのモード設定
gpio -g mode [GPIOピン番号] [モード]([モード]にはoutかinを指定)

●GPIOピンの出力制御(モード設定が out の時)
gpio -g write [GPIOピン番号] [値]([値]には0か1を指定)

具体的には下の様になります。

gpio -g

この結果を gpio readall で確認してみると、BCM番号 23 のピンが「OUT」で「1」に。

BCM23ピン

ここで、先の gpio コマンドの記述フォーマットを見てみると、gpio の後に「-g」という “オプション” が続いています。これで BCM を指定しているんです。

この「-g」オプションを外すと、wPi 指定になります。記述フォーマットは、

●WiringPiピンのモード設定
gpio mode [wPiピン番号] [モード]([モード]にはoutかinを指定)

●WiringPiピンの出力制御(モード設定が out の時)
gpio write [wPiピン番号] [値]([値]には0か1を指定)

具体的には下の様になります。

gpio オプション無し

ピン番号は同じ「23」ですが、「-g」オプションが無いとwPi番号 23 のピンが。

gpio オプション無しで

なるほど、なるほど。echo コマンドよりも gpio コマンドの方がスッキリしていて楽ですね。GPIOピン番号かwPiピン番号かは、GPIOピンの方が馴染み易いような気がする。

付け加えておくと、gpio コマンドの記述フォーマットで[モード]を[in]に設定すると、続く入出力制御は入力制御(read)となり、指定したピンの「値」が表示されます。

具体的にはこんな感じ(上の gpio readall で表示した状態を読み込んでいます)。

入力制御

Raspberry PiのGPIO制御に関し、だいぶ理解が深まった(ような気がする)。

次回は、Python でプログラムを組んでGPIOを制御することにトライしてみます。


ラズパイ4で初心者による初心者のためのLチカ(4)

前回、Linux(Raspbian)における「ディレクトリ」について学びましたが、「Linux のディレクトリはWindowsでいうフォルダと同じ」ということが分かりました。

そして、「/sys/class/gpio/gpio18/value」は「sysフォルダ」の中の「classフォルダ」の中の「gpioフォルダ」の中の「gpio18フォルダ」の中の「value」ファイルであると。

この「value」ファイルに「0 or 1」を書き込むことでGPIO18を制御できるのだけど、元々の状態ではこの「value」という(仮想)ファイルは存在していません。

というか、この「value」ファイルがあるべき「gpio18」というディレクリ(フォルダ)が存在していないんです。

それを「ls」コマンドで確認してみましょう。下のLXTerminalウィンドウの1行目で「/sys/class/gpio/」ディレクトリの中を見てみた結果が2行目。

そして、仮想ファイル「gpio18」を作成するためのコマンドが3行目。

gpio18の中

そして4行目で再び「/sys/class/gpio/」ディレクトリの中を見てみると、その結果を表す5行目に(2行目では無かった)「gpio18」というディレクトリが出来ています。

更にこの「gpio18」ディレクトリの中を確認したのが6行目ですが、7行目にはGPIO18を制御するのに必要な「direction」と「value」という2つのファイルがあります。

さて、この「direction」と「value」というファイルには現時点で何が書き込まれているのでしょうか。

「gpio readall」というコマンドで確認できるということなので実行してみると、「Oops - unable to determine ・・・・」って言われてしまった。

readall エラー

「どのボードなのか決められない」って、どゆこと?

調べてみると、これはgpioコマンドがラズパイ4Bを認識していないってことのようです。原因は、WiringPiライブラリが古いかららしい。

さっそく、WiringPiライブラリをアップデート(wiringpi latest.deb)してみました。

WiringPi更新

そして再び「gpio readall」してみると、今度は各GPIOピンの状態が表示されました。

部分表示ですが、上段の「Physical」、「wPi」、「BCM」は、全てGPIOピンの呼称。そう、同じピンに3種類の名称があるんです(これについては、また別の機会に)。

そして、ここでは「BCM」欄が「18」となっている行の、「V」と「Mode」に注目。これが、GPIO18の「value」と「direction」に書かれている内容。「0」で「IN」ですね。

gpio18の変更前2

さて、この仮想ファイルに書き込みをしてみましょう。

1行目は、冒頭のLXTerminalウィンドウの3行目と同じ。

一連の流れ途中

2行目で「out」を書き込み、3行目で「1」を書き込んでいます。

その結果を、再度「gpio readall」で確認。

gpio18の変更後

「1」で「OUT」に書き換わっているのが分かります。

次回は、「BCM」の代わりに途中で出てきたGPIOピンの別の呼び方である「wPi」を使って、同じようなこと(GPIOの制御)にトライしてみようと思います。


ラズパイ4で初心者による初心者のためのLチカ(3)

前回、Raspberry PiのGPIOを制御するためには、「/sys/class/gpio/gpio18/value」という仮想ファイルにechoコマンドで(0 or 1を)書き込めば良いってことを学びました。

が、この「/sys/class/gpio/gpio18/value」というのが良く分からない。なんでこんなに長いのか? これすべてが “ファイル名” なのか?

これを調べていくと、Linux(Raspbian)における「ディレクトリ」という概念がベースにあるようなので、今回はこのディレクトリのお話。

そもそもこの「ディレクトリ」って何だろ?

これまでにも頻繁に出会っていて、何となく理解しているような気がしているけど、でも突き詰めていくと曖昧で、よく分かっていなかった。

で、改めて確認してみると、Linux のディレクトリというのは、Windowsでいう「フォルダ」と同じものらしい。ま、習慣として Linux ではディレクトリと呼ぶと。

ここでLXTerminal ウィンドウを開き、カレントディレクトリ内にあるファイルの一覧を表示してくれる「ls」コマンドを実行してみます。

lsコマンドで

今度はラズパイのデスクトップでタスクバーを見ると、2つのフォルダが重なっているようなアイコンがあります。

フォルダマーク

このアイコンをクリックすると、Windowsで見慣れているフォルダが表示されます。

ファイルシステム

ここに表示されているフォルダの名称を、最初のLXTerminal ウィンドウに表示されているディレクトリの名称と比較してみると、それぞれ同じ名称だということが分かります。

この両者を見ていると、「Linux のディレクトリは、Windowsでいうフォルダと同じもの」ということが腑に落ちてきました。

そして、フォルダの中にフォルダがあって、その中にまたフォルダが・・・・という階層も同じように、ディレクトリの中に(下に)別のディレクトリがあって・・・・ということ。

ということを念頭に、「/sys/class/gpio/gpio18/value」を眺めてみましょう。

この中で「/」は、ディレクトリの “区切り” らしい。ということは、この「/」で階層になっている(下位階層へと続いている)ということなのでしょう。

“フォルダ” で言い換えると、「sysフォルダ」の中の「classフォルダ」の中の「gpioフォルダ」の中の「gpio18フォルダ」の中の「value」というファイル、で正しい理解?

さてここで、前回登場したechoコマンドの復習。echoコマンドをリダイレクトという機能と組み合わせると、ファイルに書き込みをすることが出来ました。

例えば、下のLXTerminal 1行目のコマンドを実行すると、「1」が書き込まれた「value」というファイルがカレントディレクトリの中に作られます。

(元々「value」ファイルが存在している場合は、そこに「1」が書き込まれる)

その「value」ファイルの中身を catコマンドで表示するように命じたのが2行目。

catで中身確認

3行目で、キチンと「1」が「value」ファイルの中に書き込まれていたことが分かります。

以上のことを統合して考えると、前回のLXTerminal 3行目の

echo "1" > /sys/class/gpio/gpio18/value

とは、カレントディレクトリから「/sys」→「/class」→「/gpio」と階層を下りて行き、「/gpio18」ディレクトリの中にある「value」ファイルに「1」を書き込むってこと。

といった感じの理解の仕方をしてみたけど、これで正しいのかな?

次回、もう少しこのディレクトリの話を続けます。


<< topページへこのページの先頭へ >> 次のページへ >>