Raspberry Pi GPIO - SHIRAISHI Kazuo
2025/08/14 (Thu) 10:55:55
Raspberry Pi OS のRaspbianでGPIOを仮想ファイルとして扱うので試してみました。
https://tool-lab.com/raspi-gpio-controlling-command-1/
を参考にしました。
GPIO4にLEDを,GPIO5にスイッチを接続しています。
/sys/class/gpio/exportに4を書き込みとGPIO4が使用可能となるので,
OPEN #1:NAME "/sys/class/gpio/export",ACCESS OUTPUT
PRINT #1:4
CLOSE #1
としてみたのですが,機能しませんでした。
100行のようにechoコマンドを実行することで済ませています。
echoコマンドはbashの内部コマンドなので,echoをEXECUTE文で呼び出すことはできません。
100 EXECUTE "/bin/bash" WITH ("-c", "echo 4 >/sys/class/gpio/export")
110 EXECUTE "/bin/bash" WITH ("-c", "echo 5 >/sys/class/gpio/export")
120 WAIT DELAY 0.1
130 EXECUTE "/bin/bash" WITH ("-c", "echo out >/sys/class/gpio/gpio4/direction")
140 EXECUTE "/bin/bash" WITH ("-c", "echo in >/sys/class/gpio/gpio5/direction")
150 OPEN #4:NAME "/sys/class/gpio/gpio4/value", ACCESS OUTPUT
160 FOR i=1 TO 20
170 PRINT #4:STR$(MOD(i,2))
180 OPEN #5:NAME "/sys/class/gpio/gpio5/value", ACCESS INPUT
190 INPUT #5:s$
200 CLOSE #5
210 PRINT s$
220 WAIT DELAY 0.5
230 NEXT I
240 CLOSE #4
250 EXECUTE "/bin/bash" WITH ("-c", "echo 4 >/sys/class/gpio/unexport")
260 EXECUTE "/bin/bash" WITH ("-c", "echo 5 >/sys/class/gpio/unexport")
270 END
130行,140行は,
OPEN #2:NAME "/sys/class/gpio/gpio4/direction", ACCESS OUTPUT
PRINT #2:"out"
CLOSE #2
OPEN #3:NAME "/sys/class/gpio/gpio5/direction", ACCESS OUTPUT
PRINT #3:"in"
CLOSE #3
のようにしても大丈夫でした。
出力は/sys/class/gpio/gpio4/valueに"0"または"1"を書き込むのですが,それは,150行,170行のように実行可能でした。
入力は,180~200行のように毎度OPEN~CLOSEを実行しないと読み込めませんでした。
Re: Raspberry Pi GPIO Raspberry PI OS Bookworm - SHIRAISHI Kazuo
2025/08/14 (Thu) 11:11:15
Raspberry Pi OS Bookwormだと,GPIOの番号が変わってしまうそうです。
https://xtech.nikkei.com/atcl/nxt/column/18/01109/040700054/?P=2
に従って,
cat /sys/kernel/debug/gpio
を実行して調べてみると,私のRaspberry Piでは,GPIO4,5の番号は,それぞれ,516,517に変更されていました。
次のように書き換えると実行可能でした。
100 EXECUTE "/bin/bash" WITH ("-c", "echo 516 >/sys/class/gpio/export")
110 EXECUTE "/bin/bash" WITH ("-c", "echo 517 >/sys/class/gpio/export")
120 WAIT DELAY 0.1
130 EXECUTE "/bin/bash" WITH ("-c", "echo out >/sys/class/gpio/gpio516/direction")
140 EXECUTE "/bin/bash" WITH ("-c", "echo in >/sys/class/gpio/gpio517/direction")
150 OPEN #4:NAME "/sys/class/gpio/gpio516/value", ACCESS OUTPUT
160 FOR i=1 TO 20
170 PRINT #4:STR$(MOD(i,2))
180 OPEN #5:NAME "/sys/class/gpio/gpio517/value", ACCESS INPUT
190 INPUT #5:s$
200 CLOSE #5
210 PRINT s$
220 WAIT DELAY 0.5
230 NEXT I
240 CLOSE #4
250 EXECUTE "/bin/bash" WITH ("-c", "echo 516 >/sys/class/gpio/unexport")
260 EXECUTE "/bin/bash" WITH ("-c", "echo 517 >/sys/class/gpio/unexport")
270 END
Re: Raspberry Pi GPIO - SHIRAISHI Kazuo
2025/08/14 (Thu) 13:23:01
https://pip.raspberrypi.com/categories/685-whitepapers-app-notes/documents/RP-006553-WP/A-history-of-GPIO-usage-on-Raspberry-Pi-devices-and-current-best-practices.pdf
によると,/sys/class/gpio/は廃止予定で,替わりにlibgpiodを使えという。
Intel CPU版で利用可能なDLL呼び出し
https://decimalbasic.web.fc2.com/ExtDLL.htm
をARM64でも実行できるように準備中ですが,とりあえず,
https://qiita.com/ma2shita/items/d745a8f89c673fd74a5e
を参考にpinctrlコマンドでアクセスするプログラムを作ってみました。
100 EXECUTE "/bin/bash" WITH ("-c", "pinctrl set 5 ip pd") !gpio5を入力に変更
110 FOR i=1 TO 20
120 IF MOD(i,2)=1 THEN
130 EXECUTE "/bin/bash" WITH ("-c", "pinctrl set 4 op dh")
140 ELSE
150 EXECUTE "/bin/bash" WITH ("-c", "pinctrl set 4 op dl")
160 END IF
170 EXECUTE "/bin/bash" WITH ("-c", "pinctrl get 5 >gpio5.txt")
180 WAIT DELAY 0.25
190 OPEN #1:NAME "gpio5.txt"
200 LINE INPUT #1:s$
210 PRINT s$
220 !ERASE #1
230 CLOSE #1
240 WAIT DELAY 0.25
250 NEXT i
260 END
pinctrlは独立コマンドなのでEXECUTE文で直接実行可能ですが,データ入力にはコマンドからの返答を取り込む必要があるので,
170行のようにファイル(gpio5.txt)を介してデータを受け取ることにします。そのため,bashを介しての実行になっています。
220行のERASE文は不要だったようです(追記されるのでなく,書き込み時毎度リセットされる)。
受け取ったデータは,次のようになっています。
5: ip -- | hi // GPIO5 = input
5: ip -- | hi // GPIO5 = input
5: ip -- | hi // GPIO5 = input
5: ip -- | hi // GPIO5 = input
5: ip -- | hi // GPIO5 = input
5: ip -- | hi // GPIO5 = input
5: ip -- | hi // GPIO5 = input
5: ip -- | hi // GPIO5 = input
5: ip -- | lo // GPIO5 = input
5: ip -- | lo // GPIO5 = input
5: ip -- | hi // GPIO5 = input
5: ip -- | lo // GPIO5 = input
5: ip -- | lo // GPIO5 = input
5: ip -- | hi // GPIO5 = input
5: ip -- | hi // GPIO5 = input
5: ip -- | hi // GPIO5 = input
5: ip -- | hi // GPIO5 = input
5: ip -- | hi // GPIO5 = input
5: ip -- | hi // GPIO5 = input
5: ip -- | hi // GPIO5 = input
スイッチの操作でhiとloが切り替わっています。
Re: Raspberry Pi GPIO - SHIRAISHI Kazuo
2025/08/18 (Mon) 15:16:25
DLL呼び出しが可能になるように拡張しました(Ver.0.7.6.2,および Ver.0.9.2.6)。
Qiitaの記事
https://qiita.com/wancom/items/b041ee7408a87fabf48e
を参考にlibgpiod呼び出しに書き換えてみました。
事前に
sudo apt install libgpiod2 libgpiod-dev libgpiod-doc
を実行して,libgpiodをインストールしておいてください。
100 ! sudo apt install libgpiod2 libgpiod-dev libgpiod-doc
110 ! /usr/share/doc/libgpiod-dev/html
120 OPTION ARITHMETIC NATIVE
130 FUNCTION GPIOD_CHIP_OPEN_LOOKUP(s$)
140 ASSIGN "libgpiod.so","gpiod_chip_open_lookup"
150 END FUNCTION
160 FUNCTION gpiod_chip_get_line(n,t)
170 ASSIGN "libgpiod.so","gpiod_chip_get_line"
180 END FUNCTION
190 SUB gpiod_line_request_output(n,s$,t)
200 ASSIGN "libgpiod.so","gpiod_line_request_output"
210 END SUB
220 SUB gpiod_line_request_input(n,s$)
230 ASSIGN "libgpiod.so","gpiod_line_request_input"
240 END SUB
250 SUB gpiod_line_set_value(gpio, x)
260 ASSIGN "libgpiod.so","gpiod_line_set_value"
270 END SUB
280 FUNCTION gpiod_line_get_value(gpio)
290 ASSIGN "libgpiod.so","gpiod_line_get_value"
300 END FUNCTION
310 SUB ppiod_chip_close(gchip)
320 ASSIGN "libgpiod.so","gpiod_chip_close"
330 END SUB
340 LET GChip=GPIOD_CHIP_OPEN_LOOKUP(STR$(0))
350 ! PRINT GChip
360 LET gpio4 = gpiod_chip_get_line(GChip, 4)
370 ! PRINT gpio4
380 LET gpio5 = gpiod_chip_get_line(GChip, 5)
390 ! PRINT gpio5
400 CALL gpiod_line_request_output(gpio4, "LED", 0)
410 CALL gpiod_line_request_input(gpio5,"Switch")
420 FOR i=1 TO 20
430 CALL gpiod_line_set_value(gpio4, MOD(i,2))
440 WAIT DELAY 0.25
450 PRINT gpiod_line_get_value(gpio5)
460 WAIT DELAY 0.25
470 NEXT i
480 CALL ppiod_chip_close(GChip)
490 END
参考例(Qiitaの記事)では gpiod_chip_open_lookup の引数が""になっていますが,ASSIGN文で定義されるDLLに空文字列を指定するとヌルポインタが渡されるので,
空文字列への(ヌルでない)ポインタを渡すために340行ではchr$(0)を指定します。
"/dev/gpiochip4"のようなデバイス名を指定すべきところだと思いますが,OSがBullseyeだと/devにそれらしきデバイス名が出て来ないのですが,chr$(0)を指定すると動作します。
また,gpiod_chip_open_lookup が返す値はポインタですが,十進BASICでは2進モードでも53ビットの精度しかないので,64ビット環境だと使えない可能性があります。
350行の ! を削除してその値が53ビットの範囲にあることの確認が必要です。
ただし,64ビットのポインタは下位3ビットが0であるのが普通なので,2^56以下であれば可かも知れません。
400行,410行の"LED","Switch"は,使い道が不明ですが,適当に付けた名前です。
libgpoidの詳細は,
/usr/share/doc/libgpiod-dev/html/modules.html
にあります。とりあえず
/usr/share/doc/libgpiod-dev/html/group__line__request.html
/usr/share/doc/libgpiod-dev/html/group__line__value.html
あたりを見てください。
上の例は上記文書を読みこなしていない状態で作成したものです。とりあえず動作する参考例にしてください。