
NanoPi NEO (LTS) の FriendlyCore で GPIO を操作する内容となっています。
LTS とは、Long Term Support の頭文字です。
長期的にサポートします?とのことなので組み込み機器のリリース向きとなっています。
はじめに
NanoPi NEO の GPIO について
勉強不足もありまして、かなりハマりました。w
NanoPi NEO の FriendlyCore につきましては、FriendlyCore Focal (Base on Ubuntu 20.04) からダウンロードしてインストールしました。
詳細は、5 Get Startedを参照してください。
基本的には、OS イメージをダウンロードして解凍後、イメージファイルを MicroSD へ焼いて MicroSD からブートする流れです。
ちなみに私は、SanDisk Extreme 64G の SDカードを使っています。
32G や 16G でも十分だと思います。
注意事項としまして
NanoPi NEO の本体基盤には、HDMI 出力がありません。
なので原則、有線 LAN ケーブルがないと初期のセットアップができません。
私の場合、自宅のルーター(LAN 環境)に NanoPi NEO を有線でつないで DHCP にて ip アドレスを割り当てました。
公式のドキュメントにあります Angry IP Scanner というオープンソースのフリーソフトを使って NanoPi NEO に割り当てられた LAN の ip アドレスを調べます。
Tera Term 等のターミナルから ssh で接続します。
初回、pi のパスワードは、pi です。
pi のパスワードの変更を聞かれたら任意のパスワードへ変更してください。
root の初期パスワードは、fa です。
基本設定は、npi-config から設定できます。
注意事項
npi-config にて設定した後は、必ず認識されるまで再起動を繰り返ししたほうがよいです。
また、手動でシステム系の設定を行った後は、npi-config を起動しないほうがよいかもしれません。
設定内容が変わってしまう場合や起動しなくなることが何度かありました。
MicroSD から起動しています。
USB Wifi の設定に関しては、Set up the USB Wi-fi ELECOM WDC-150SU2MBK on Ubuntu 18.04 for LAN を参考にしてください。
NanoPi NEO には、tp-link の TL-WN725N 無線LAN子機を使用していますが初期認識されています。
GPIO の環境構築
FriendlyCore のインストールおよび OS 基本設定が終わりましたら、GPIO のインターフェース、ライブラリ等をインストールします。
$ sudo apt install gpiod libgpiod-dev libgpiod2 python3-libgpiod python3-pigpio
Raspberry pi 用ライブラリ以外の GPIO(Python)関連をインストールしています。
※libgpiod-doc は、お好みで
GPIO ピン番号の関連確認
ここが肝心要または、ハマりどころw です。
NanoPi NEO の GPIO 関連資料は、pin out diagram または、NanoPi-NEO-1606-Schematic.pdf です。
資料からは、物理的にコネクタのピンの位置と何の役割(予約)かわかります。
Linux では、sysfs から GPIO を操作するとのこと。
Linux:sysfs ⇔ GPIO インターフェース・ライブラリ ⇔ GPIO デバイス ⇔ Soc:CPU (Allwinner H3) GPIO チップ ⇔ GPIO ピン(コネクタ)
との流れ?になるそうです。
なので GPIO デバイスと GPIO ピン(pin)を番号で指定するのですが、このピン番号がややこしいw
GPIO は、GPIO 番号と GPIO 名、ピン番号があります。
GPIO 番号と GPIO 名は、先ほどの pin out diagram でわかるのですが対応するピン番号がわかりません。
そこで Linux カーネル内部のデバッグに関する情報を参照するためのファイルから調べることができます。
$ sudo cat /sys/kernel/debug/gpio gpiochip0: GPIOs 0-223, parent: platform/1c20800.pinctrl, 1c20800.pinctrl: gpio-110 ( |onewire@0 ) out lo gpio-166 ( |cd ) in lo ACTIVE LOW gpio-204 ( |usb0_id_det ) in hi IRQ gpiochip1: GPIOs 352-383, parent: platform/1f02c00.pinctrl, 1f02c00.pinctrl: gpio-355 ( |k1 ) in hi IRQ ACTIVE LOW gpio-358 ( |vdd-cpux ) out hi
この gpio-XXX にある後ろの 3桁の番号がピン番号となります。
ん!?すっ少なくね!???
パッと見、GPIO で使えそうなピンが少ないのですが、調べてみると
NanoPi NEO – FriendlyELEC WiKi の Diagram, Layout and Dimension → GPIO Pin Description 表に Linux gpio の番号が記載されています。
そもそも pin に重複して役割があるらしいので使えそうな GPIO ピンが限られるとのこと
それにしても カーネルのデバック情報と wiki の情報が違いますよね?w
pin 名から pin の 番号を割り出す計算式
だそうです。
(position of letter in alphabet – 1) * 32 + pin number
式中の 32 は、NanoPi NEO(ARM Cortex-A7 MPCore)が 32 bit だから 32 だそうです。
pin 名:GPIOA0 の場合、アルファベットの A が 1 番(1 から数える)なので
ここで言う pin number は、GPIOA0 の後ろの数字 0 です。
(1 – 1) * 32 + 0 = 0
pin 名:GPIOG11 の場合、アルファベットの G が 7 番なので
ここで言う pin number は、GPIOG11 の後ろの数字 11 です。
(7 – 1) * 32 + 11 = 6 * 32 + 11 = 192 + 11 = 203
この番号が後述する「GPIO デバイスの設定」で必要になります。
むずかしいw
とりま進めます。(๑•̀д•́๑)キリッ
gpio グループとルールの作成
root の権限で、このピン番号をデバイス登録すれば、すぐに使用できるのですが、その前に
後ほど、一般ユーザーから使えるように gpio グループ(グループ名は、てきとうです)を作成して権限、ルールを作成して環境を整えます。
$ sudo su - # addgroup gpio Adding group `gpio' (GID 1001) ... Done. # usermod -aG gpio user
この gpio グループに対してデバイス管理ツール(udev rules)を作成します。
sudo vi /etc/udev/rules.d/60-gpio-group.rules # gpiochip は、0 と 1 という意味です。 SUBSYSTEM=="gpio", KERNEL=="gpiochip[01]", GROUP="gpio", MODE="0660" # Group gpio chown オーナー、グループの変更 SUBSYSTEM=="gpio", PROGRAM="/usr/bin/bash -c '/usr/bin/chown -R root:gpio /sys/class/gpio/gpio*/*'" # Group gpio chmod ユーザー、グループへ読み取り、書き込み権限を追加 SUBSYSTEM=="gpio", PROGRAM="/usr/bin/bash -c '/usr/bin/chmod -R ug+rw /sys/class/gpio*/*'"
PATH のワイルドカード(*)の書き方がポイントです。
ルールができましたら OS へ反映するため NanoPi NEO を再起動します。
gpiochip の番号?を調べるには、gpiodetect コマンドを使います。
$ sudo gpiodetect gpiochip0 [1c20800.pinctrl] (224 lines) gpiochip1 [1f02c00.pinctrl] (32 lines)
gpiochip に続く 0,1 が先ほどの udev ルールに使用した番号となります。
GPIO デバイスの設定
先ほどの wiki にある表で Linux gpio の番号が判明しているものを GPIO デバイスに設定します。
ここでは、GPIOG11 の pin 番号 203 を信号送信で使用します。
$ echo 203 | sudo tee /sys/class/gpio/export
tee コマンドで export へ登録します。
作成されたか確認する
$ ls -l /sys/class/gpio/gpio203/ total 0 -rw-rw-r-- 1 root gpio 4096 Mar 18 21:59 active_low lrwxrwxrwx 1 root gpio 0 Mar 18 21:59 device -> ../../../gpiochip0 -rw-rw-r-- 1 root gpio 4096 Mar 18 21:59 direction -rw-rw-r-- 1 root gpio 4096 Mar 18 21:59 edge drwxrwxr-x 2 root gpio 0 Mar 18 21:59 power lrwxrwxrwx 1 root gpio 0 Mar 18 21:59 subsystem -> ../../../../../../../class/gpio -rw-rw-r-- 1 root gpio 4096 Mar 18 21:59 uevent -rw-rw-r-- 1 root gpio 4096 Mar 18 21:59 value
グループもパーミッションも OK ですね
GPIO の制御
最後にコマンドから簡単な GPIO 制御でテストします。
今回は、ARCELI Mosfet IRF520 モジュールを使って LED 点灯確認を行います。
他のブランドからも同じような Mosfet IRF520 モジュールが多数、出ていますのでお好みやLED照明に対応する規格で選択してください。
ARCELI MOSFET IRF520 モジュール
Amazon で探す
回路図も勉強中でして・・・まだ書けないので簡単な取付配線図で説明します。
先ほどの Pin 203 番の GPIOG11 へ ON/OFF の信号を送ります。
LED 照明の電源は、基盤と別に 12V2A アダプターから引いてます。
LED の配線とアダプターからの配線を IRF520 モジュールへ接続します。
モジュールの SIG と GPIOG11 をジャンパー線でつなぎます。
モジュールの GND と基盤のピンの GND(6 pin など)へつなぎます。
配線が正しいのかわかりません。m(_ _)m
それと抵抗器は、たぶん MOSFES モジュールに着いている?気がするので直結してます。
この辺、ツッコミ、ご教授いただけるとありがたいです。
それでは、C ライブラリ(gpiod)制御のテストです。
LED 照明が点灯、消灯すれば成功です。
# まず、ピンのタイプの初期値は、入力用(in)になっているので出力用(out)に変更します。 $ echo out > /sys/class/gpio/gpio203/direction # ピンの初期値は、0 です。 $ cat /sys/class/gpio/gpio203/value 0 # LED は、まだ点灯していない状態なので ON(1) にします。 $ echo 1 > /sys/class/gpio/gpio203/value # LED は、点灯されましたか? おめでとうございます! # 私は、はじめての制御で LED が点灯した時に凄く感動しました。!(^^)! # LED を OFF(0)消灯してみます。 $ echo 0 > /sys/class/gpio/gpio203/value # GPIO の使用後、開放(unexport)します。 $ echo 203 | sudo tee /sys/class/gpio/unexport
テストは、完了です。
Python から GPIO の操作
公式では、WiringNP RPi.GPIO_NP を推奨しています。
WiringNP のインストール手順は、後日公開予定です。
apt でのパッケージ管理が希望なのですが、ベストなライブラリが見当たりません。
pypi や git からも色々な gpio ライブラリを試したのですが、RPi.GPIO_NP が最短で実装できそうです。
公式マニュアル通りに git clone でダウンロードして python setup.py install するのですが、権限エラーなどが出てインストールすることができませんでした。
追記(2022-04-18):
やっと気づきました。(´;ω;`)ウゥゥ
RPi.GPIO_NP に関しては、Python3.8 対応で Python3.9 は、インストールエラーが起こるということですね
Debian 11 Bullseye だと現時点では、Python3.9 なので実質、Python からの GPIO 操作が困難になる落ち
RPi.GPIO_NP を Python3.9 以降も使えるように更新してくれないかな?
たまたま gpio で grep 検索したところ /usr/bin/install_RPiGPIO.sh ファイルなるものを発見しました。
$ cat /usr/bin/install_RPiGPIO.sh #!/bin/bash apt-get --yes install python-dev cd /root/Python/RPi.GPIO_NP python setup.py install
ファイルの中身は、上記の通りですので /root/ 直下に Python ディレクトリを作って root で git clone しました。
追記(2022-04-25):
python3.5 では、そのまま一般ユーザーで git から setup install まで出来ました。
なので python2 の環境は、必要ありません。
python3 venv 環境がスッキリします。
$ sudo su - # mkdir Python # cd Python/ # git clone https://github.com/friendlyarm/RPi.GPIO_NP Cloning into 'RPi.GPIO_NP'... remote: Enumerating objects: 89, done. remote: Counting objects: 100% (89/89), done. remote: Compressing objects: 100% (44/44), done. remote: Total 89 (delta 44), reused 88 (delta 43), pack-reused 0 Unpacking objects: 100% (89/89), 45.52 KiB | 134.00 KiB/s, done. # /usr/bin/install_RPiGPIO.sh パッケージリストを読み込んでいます... 完了 依存関係ツリーを作成しています 状態情報を読み取っています... 完了 注意、'python-dev' の代わりに 'python-dev-is-python2' を選択します python-dev-is-python2 はすでに最新バージョン (2.7.17-4) です。 アップグレード: 0 個、新規インストール: 0 個、削除: 0 個、保留: 0 個。 running install running build running build_py creating build creating build/lib.linux-armv7l-2.7 creating build/lib.linux-armv7l-2.7/RPi copying RPi/__init__.py -> build/lib.linux-armv7l-2.7/RPi running build_ext building 'RPi.GPIO' extension ~~~ 省略 ~~~ running install_egg_info Writing /usr/local/lib/python2.7/dist-packages/RPi.GPIO-0.5.8.egg-info # cd Python/RPi.GPIO_NP/ # python3 setup.py install running install running build running build_py creating build/lib.linux-armv7l-3.8 creating build/lib.linux-armv7l-3.8/RPi copying RPi/__init__.py -> build/lib.linux-armv7l-3.8/RPi running build_ext building 'RPi.GPIO' extension ~~~ 省略 ~~~ running install_lib creating /usr/local/lib/python3.8/dist-packages/RPi copying build/lib.linux-armv7l-3.8/RPi/__init__.py -> /usr/local/lib/python3.8/dist-packages/RPi copying build/lib.linux-armv7l-3.8/RPi/GPIO.cpython-38-arm-linux-gnueabihf.so -> /usr/local/lib/python3.8/dist-packages/RPi byte-compiling /usr/local/lib/python3.8/dist-packages/RPi/__init__.py to __init__.cpython-38.pyc running install_egg_info Writing /usr/local/lib/python3.8/dist-packages/RPi.GPIO-0.5.8.egg-info # exit ログアウト $ pip list Package Version ---------------------- -------------------- RPi.GPIO 0.5.8 $ python Python 3.8.10 (default, Mar 15 2022, 12:22:08) [GCC 9.4.0] on linux Type "help", "copyright", "credits" or "license" for more information. >>> import RPi.GPIO as GPIO >>> ctl+d
流れ的には、公式にも説明?があるのですが python2 で setup.py install してから python3 でもう一度、setup.py install しましょう!みたいな感じです。
一般ユーザーでセットアップすると権限エラーになるので root 権限で実行したところエラーは、なくなりインストールできました。
追記(2022-04-18):
ゴメンナサイ、ちゃんと Python の仮想環境を用意した方が良いですね
RPi.GPIO のバージョン特有のエラーらしいのですが公式なら問題なくインストールさせてほしいです。グチです。
テスト環境は、先ほどの「GPIO の制御」と同じです。
Python3 によるソフトウェア PWM で LED の光をフェードイン、フェードアウトさせてみます。
ソースコードのサンプル(example)
#!/usr/bin/env python3 import RPi.GPIO as GPIO import sys import time PIN_NUM = 7 # Pin Number FREQ = 800 # Hz var_interval = 2.0 var_duty = 0.0 # Duty Cycle GPIO.setmode(GPIO.BOARD) GPIO.setup(PIN_NUM, GPIO.OUT) LED = GPIO.PWM(PIN_NUM, FREQ) LED.start(var_duty) var_duty = 0.0 for i in range(0, 1): print("Fade in") while var_duty < 100: var_duty += 1.0 LED.ChangeDutyCycle(var_duty) time.sleep(var_interval) print("Fade out") while var_duty > 0: var_duty -= 1.0 LED.ChangeDutyCycle(var_duty) time.sleep(var_interval) LED.stop() GPIO.cleanup()
権限が間違っているようで一般ユーザーで実行できません。
$ ./test.py Traceback (most recent call last): File "./test.py", line 13, in <module> GPIO.setup(PIN_NUM, GPIO.OUT) RuntimeError: No access to /dev/mem. Try running as root!
しかたがないので sudo します。
デバイスメモリーのアクセス権を変更したりする解決策もありましたが、私は、root 権限で実行する対策を選択しました。
$ sudo ./test.py
LED は、点灯されましたでしょうか?
実行時間が長く感じる場合は、var_interval の sleep 時間を短くしてみてください。
チラつきを抑えたかったので FREQ は、800Hz に設定してます。お好みで変更してください。
ここまでくるのに 2週間ほどかかった(-_-;)
お疲れさまでした。m(_ _)m
Was this helpful?
1 / 0