Armbian上のPythonでRPi.GPIOもどきを使う方法

RPi.GPIOはラズパイ用のGPIO操作Pythonライブラリ。そしてOPi.GPIOはOrange Pi用のRPi.GPIO互換Pythonライブラリであり、OPi.GPIOを使うことによってOrange Pi上のPythonで簡単にGPIOを扱えるようになる他、RPi.GPIOに依存するライブラリがOrange Piでも動かせるようになる。

このOPi.GPIOは、ピン番号とGPIO番号のマッピングが簡単に変えられるので、少し手を加えるだけで別のシングルボードコンピュータ用のRPi.GPIO互換ライブラリに仕立てることが出来る。

今回は、OPi.GPIOををNano Pi Neo用にカスタマイズして、Nano Pi NeoのArmbianでRPi.GPIOを動かす方法を試した。

スポンサーリンク

OPi.GPIOのインストール

pip一発でインストール出来る。GPIO操作は要root権限であり、sudoを付けてシステム全体へのインストールが必要なので注意。

sudo pip install OPi.GPIO

RPi.GPIOを使ったPythonコードの例

RPi.GPIOを使ってGPIO操作するための典型的なPythonプログラムは以下のような物。

import RPi.GPIO as GPIO
PIN_NUM = 7

GPIO.setmode(GPIO.BOARD)
GPIO.setup(PIN_NUM,GPIO.OUT)

GPIO.output(PIN_NUM,GPIO.HIGH)

プログラムの解説をすると、

  • 2行目: GPIO操作を行うボードのピン番号を変数PIN_NUMに指定している
  • 4行明: ボードのピン番号指定するモードを指定
  • 5行目: PIN_NUM指定のピンを出力に設定
  • 6行目: PIN_NUM指定のピンからHighを出力

Nano Pi Neoのピン番号とGPIO番号の対応を確認する

下記リンクのページにある表にNano Pi Neoボード上のピン番号とLinux OSが管理するGPIO番号との対応が書かれている。

NanoPi NEO - FriendlyELEC WiKi

例えば、上のサンプルプログラムではsetmodeにGPIO.BOARDを指定しピン番号7を操作しているので、ボードのピン番号7、つまりSoC呼称G11でLinux GPIO番号203に該当する。

表にまとめると以下のようになる。

SoC呼称ボードのピン番号(GPIO.BOARD指定時)Linux GPIO番号
PG117203
PG68198
PG710199
PA0110
PA6126
PA2132
PA3153
PG816200
PG918201
PC01920
PC12165
PA1221
PC22366
PC32467

NPi.GPIO互換ライブラリにカスタマイズする

とりあえず、カレントディレクトリの下にRPiディレクトリを掘り、GPIO.pyを作成する。

mkdir RPi
edit GPIO.py

GPIO.pyの中身は以下のようにした。BOARDとCUSTOMという変数名の辞書型で、物理ピン番号とシステムのGPIO番号との対応関係を定義している。このBOARDやCUSTOMで定義された対応関係を、RPi.GPIOのsetup関数に渡すことによって、ボード固有のピン番号<–>GPIO番号のマッピングを実現している。

BOARDの方はNano Pi Neoのボードのピン番号との対応を定義し、CUSTOMの方には前回記事で取り上げたPCF8574で増やしたGPIOとの対応関係を定義してみた。

from OPi.GPIO import *

BOARD = {
    7:    203,   # PG11
    8:    198,   # PG6
    10:   199,   # PG7
    11:   0,     # PA0
    12:   6,     # PA6
    13:   2,     # PA2
    15:   3,     # PA3
    16:   200,   # PG8
    18:   201,   # PG9
    19:   20,    # PC0
    21:   65,    # PC1
    22:    1,    # PA1
    23:   66,    # PC2
    24:   67     # PC3
}

# BCMはBroadCom(=ラズパイのSoC)の事で何の意味も無いが…互換性のために定義
BCM = BOARD

# PCF8574のGPIOをCUSTOMとして定義しておこう
CUSTOM = {
    0:    504,    # P0
    1:    505,    # P1
    2:    506,    # P2
    3:    507,    # P3
    4:    508,    # P4
    5:    509,    # P5
    6:    510,    # P6
    7:    511     # P7
}

PythonコードでGPIO操作してみる

上のサンプルプログラムと同様の内容を対話型でGPIO操作を行った例。sysfsを触るのでPythonをroot権限で動かす必要がある点に注意。

$ ls RPi/GPIO.py
RPi/GPIO.py
$ sudo python
Python 3.10.4 (main, Apr  2 2022, 09:04:19) [GCC 11.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import RPi.GPIO as GPIO
>>> PIN_NUM = 3
>>> GPIO.setmode(GPIO.CUSTOM)
>>> GPIO.setup(PIN_NUM,GPIO.OUT)
>>> GPIO.output(PIN_NUM,GPIO.HIGH)

GPIO.CUSTOMを指定することで、PythonでI2C接続のIOエキスパンダPCF8574のポート番号3(P3)を操作しLチカ出来ることが確認出来た。

TinyConsole

GPIO.pyをPythonのサーチパスが通っている場所にコピーする

とりあえずカレントディレクトリに置いてテストを行ったが、Pythonのパスが通っている場所にコピーしておけばライブラリとして利用可能となる。root権限で実行したいので、以下のようにしてsudoを付けてPythonを実行した時のサーチパスを確認する。

$ sudo python
Python 3.10.4 (main, Apr  2 2022, 09:04:19) [GCC 11.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> sys.path
['', '/usr/lib/python310.zip', '/usr/lib/python3.10', '/usr/lib/python3.10/lib-dynload', '/usr/local/lib/python3.10/dist-packages', '/usr/lib/python3/dist-packages']

sys.pathに含まれている場所であればどこでも良いのだが、/usr/local/lib/python3.10/dist-packagesに置くことにする。

sudo mkdir /usr/local/lib/python3.10/dist-packages/RPi
sudo cp RPi/GPIO.py /usr/local/lib/python3.10/dist-packages/RPi

まとめ

OPi.GPIOを使うことによって、辞書型でピン番号とGPIOの対応関係を記述するだけで簡単にRPi.GPIO互換ライブラリ化をすることが出来た。今回の方法はsysfs経由のGPIO操作に対応していれば応用可能なので、Armbianだけでなく、少し前の記事で取り上げたBuildrootベースのシステムでも使える筈。いずれ記事にしてみたいと思う。

コメント