OrangePi ZERO Plus2 H3を使ってみる

GPIO入出力

OrangePi ZERO Plus2 H3は、OrangePi-ZERO から有線LANとUSBを取り除いて、代わりにHDMIポートとカメラI/Fを追加したモデルです。
左:OrangePi ZERO Plus2 H3
右:OrangePi ZERO


OrangePi ZERO Plus2 H3のピンヘッダーは、OrangePi ZEROと同じ26ピンです。
OrangePi ZERO Plus2 H3のピンアサインはこ ちらこ ちらで公開されていますが、一部ピンアサインがZEROとは違います。
この違いのため、GPIOの入出力に関してZERO専 用 のWiringライブラリでは全てのGPIOが使えません。
致命的なのは、ピン#11(PL00)とピン#13(PL01)で、PLポートはレジスタ開始アドレスが他のポートとは非連続なので、
単純なポートマッピングの変更では対応できず、ライブラリを相当いじらないと、このピンをライブラリ経由で使うことができません。

OrangePi ZERO Plus2のピンアサインこちらに も公開されていますが、正しくありません。

またデバッグポートに関するシルクがどこにもありません。
デバッグポートに関してはこちらに ピンアサインが紹介されていますが、
26ピンヘッダーの26番ピン側からGND RXD TXDの順に並んでいます。
OSインストール時にはUSB-TTL変換アダプターを使ってインストールする必要がありますが、
インストールが完了すると、USB OTG Consoleデバイスが使えるので、パソコンのUSBポートに刺すだけで
USBコンソールが使えるようになります。

[/etc/network/interfaces]は空っぽで、NetworkManageを使って無線LANの設定を行います。



こちら
で紹介している python-peripheryライブラリを使うことで、ピン#11(PL00)とピン#13(PL01)を含むすべての
ピンを使うことができました。
ピン番号には以下のGPIO番号を指定します。
GPIO番号 物理ピン番号 GPIO番号

1 2
12 3 4
11 5 6
6 7 8 0

9 10 1
352 11 12 107
353 13 14
3 15 16 19

17 18 18
15 19 20
16 21 22 2
14 23 24 13

25 26 110

以下のコードでPin#11とPin#13に接続したLEDが交互にLチカします。
#!/usr/bin/python
#-*- encoding: utf-8 -*-
from periphery import GPIO
import time
import signal
import sys


def handler(signal, frame):
  global flag
  flag = False


flag = True
signal.signal(signal.SIGINT, handler)
pin1 = 352
pin2 = 353
gpio1_out = GPIO(pin1, "out")
gpio2_out = GPIO(pin2, "out")


while flag:
  gpio1_out.write(False)
  gpio2_out.write(True)
  time.sleep(1.0)
  gpio1_out.write(True)
  gpio2_out.write(False)
  time.sleep(1.0)


gpio1_out.write(False)
gpio2_out.write(False)
gpio1_out.close()
gpio2_out.close()

デバイスファイルを使ってPin#11に接続したLEDをLチカする場合も、同じGPIO番号を使います。
$ sudo sh -c "echo 352 >/sys/class/gpio/export"
$ sudo sh -c "echo out >/sys/class/gpio/gpio352/direction"
$ sudo sh -c "echo 1 > /sys/class/gpio/gpio352/value"
$ sudo sh -c "echo 0 > /sys/class/gpio/gpio352/value"
$ sudo sh -c "echo 352 > /sys/class/gpio/unexport"



こちらに様々なボードに 対応したOPi.GPIOライブラリが公開されていますので、さっそく試してみました。
以下のコードでPin#11のLチカを確認しましたが、やはり動きません。
ソースを見てみましたが、 メモリマップ経由でポートを操作しています。
PLポートはレジスタ開始アドレスが他のポートとは非連続なので、簡単には動かないです。
import OPi.GPIO as GPIO
from time import sleep          # this lets us have a time delay
pin = 11

GPIO.setboard(GPIO.ZEROPLUS2H3) # Orange Pi ZERO Plus H3 board
GPIO.setmode(GPIO.BOARD)        # set up BOARD BCM numbering
GPIO.setup(pin, GPIO.OUT)       # set BCM7 (pin 26) as an output (LED)

try:
    print ("Press CTRL+C to exit")
    while True:
        GPIO.output(pin, 1)     # set port/pin value to 1/HIGH/True
        sleep(0.1)
        GPIO.output(pin, 0)     # set port/pin value to 0/LOW/False
        sleep(0.1)

        GPIO.output(pin, 1)     # set port/pin value to 1/HIGH/True
        sleep(0.1)
        GPIO.output(pin, 0)     # set port/pin value to 0/LOW/False
        sleep(0.1)

        sleep(0.5)

except KeyboardInterrupt:
    GPIO.output(pin, 0)         # set port/pin value to 0/LOW/False
    GPIO.cleanup()              # Clean GPIO
    print ("Bye.")



こちら
にもRPi.GPIOのOrangePi版が公開されています。
最初はOrangePi-ZEROだけに対応していたのですが、いつの間にか様々なボードに対応していました。
インストールは以下の手順です。
$ sudo apt-get install python-setuptools
$ sudo easy_install pip
$ sudo pip install --upgrade OPi.GPIO

ソースを見たい場合は以下の手順です。
$ sudo apt-get install python-setuptools
$ git clone https://github.com/rm-hull/OPi.GPIO
$ cd OPi.GPIO
$ sudo python setup.py install

RPi.GPIOは物理ピン番号(GPIO.BOARD)と、BCM番号(GPIO.BCM)でポートを指定することができますが、
このライブラリも物理ピン番号(orangepi.zeroplus2.BOARD)と、BCM番号 (orangepi.zeroplus2.BCM)でポートを指定することができます。
この部分を変えることで、様々なボードに対応しています。
BCM番号 物理ピン番号 BCM番号

1 2
2
3 4
3
5 6
4
7 8 14

9 10 15
17
11 12 18
27
13 14
22
15 16 23

17 18 24
10 19 20
9 21 22 25
11 23 24 8

25 26 7

以下のコードで物理ピン番号の動作を確認することができます。Pin#11とPin#13に接続したLEDが交互にLチカします。
HIGH/LOWの反転はものすごくスマートです。
ソースを見てみましたが、 python-peripheryライブラリと同様に、直接デバイスファイルを操作しています。
#!/bin/python
#-*- encoding: utf-8 -*-
import orangepi.zeroplus2
from OPi import GPIO

import time
import signal
import sys

flag = True

def handler(signal, frame):
  global flag
  flag = False

signal.signal(signal.SIGINT, handler)
pin1 = 11
pin2 = 13
GPIO.setmode(orangepi.zeroplus2.BOARD)
GPIO.setup(pin1, GPIO.OUT)
GPIO.setup(pin2, GPIO.OUT)
GPIO.output(pin2, GPIO.HIGH)

while flag:
  GPIO.output(pin1, not GPIO.input(pin1))
  GPIO.output(pin2, not GPIO.input(pin2))
  time.sleep(1.0)

GPIO.output(pin1, GPIO.LOW)
GPIO.output(pin2, GPIO.LOW)
GPIO.cleanup()

以下のコードでBCM番号の動作を確認することができます。Pin#11とPin#13に接続したLEDが交互にLチカします。
python-peripheryライブラリの様にGPIO番号で指定するか、RPiと同様にBCM番号で指定するか、好みが分かれるところで す。
#!/bin/python
#-*- encoding: utf-8 -*-
import orangepi.zeroplus2
from OPi import GPIO

import time
import signal
import sys

flag = True

def handler(signal, frame):
  global flag
  flag = False


signal.signal(signal.SIGINT, handler)
pin1 = 17
pin2 = 27
GPIO.setmode(orangepi.zeroplus2.BCM)
GPIO.setup(pin1, GPIO.OUT)
GPIO.setup(pin2, GPIO.OUT)
GPIO.output(pin2, GPIO.HIGH)

while flag:
  GPIO.output(pin1, not GPIO.input(pin1))
  GPIO.output(pin2, not GPIO.input(pin2))
  time.sleep(1.0)

GPIO.output(pin1, GPIO.LOW)
GPIO.output(pin2, GPIO.LOW)
GPIO.cleanup()

次回はi2c通信を紹介します。