
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
あたりを見てください。
上の例は上記文書を読みこなしていない状態で作成したものです。とりあえず動作する参考例にしてください。
Re: Raspberry Pi GPIO - SHIRAISHI Kazuo
2025/08/31 (Sun) 18:37:35
Raspberry PI OSで動くBASICAcc,ParactBASICでASSIGN文とCALLBACK関数が使えるようにしました。
ParactBASICのテスト用のプログラムを作成しました。
「シグナル」の部分は対応する英単語(Full BASICの機能語)に置き換えてください。そのままだと掲示板の禁止ワードに引っかかって書き込めませんでした。
100 DECLARE STRUCTURE struct1: 1 OF NUMERIC
110 DECLARE STRUCTURE struct2: 1 OF string
120 DECLARE SHARED share1 OF struct1
130 DECLARE SHARED share2 OF struct2
140 !
1000 PARACT part1
1010 DECLARE EXTERNAL FUNCTION GPIOD_CHIP_OPEN_LOOKUP
1020 DECLARE EXTERNAL FUNCTION gpiod_chip_get_line
1030 LET GChip=GPIOD_CHIP_OPEN_LOOKUP(STR$(0))
1040 LET gpio4 = gpiod_chip_get_line(GChip, 4)
1050 CALL gpiod_line_request_output(gpio4, "LED", 0)
1060 PUT TO share1 FROM GChip
1070 PUT TO share2 FROM ""
1080 START part2
1090 シグナル ready
1100 REM
1110 FOR i=1 TO 10
1120 WAIT EVENT go
1130 CALL gpiod_line_set_value(gpio4, MOD(i,2))
1140 シグナル ready
1150 NEXT i
1160 PUT TO share2 FROM "end"
1170 END PARACT
1180 !
2000 PARACT part2
2010 DECLARE EXTERNAL FUNCTION gpiod_chip_get_line
2020 DECLARE EXTERNAL FUNCTION gpiod_line_get_value
2030 GET FROM share1 TO GChip
2040 LET gpio5 = gpiod_chip_get_line(GChip, 5)
2050 CALL gpiod_line_request_input(gpio5,"Switch")
2060 DO
2070 GET FROM share2 TO fin$
2080 IF fin$<>"" THEN EXIT DO
2090 IF gpiod_line_get_value(gpio5)=0 THEN !Switchが押された
2100 WAIT EVENT ready
2110 シグナル go
2120 WAIT DELAY 0.25
2130 END IF
2140 LOOP
2150 CALL gpiod_chip_close(GChip)
2160 END PARACT
2170 !
3000 EXTERNAL FUNCTION GPIOD_CHIP_OPEN_LOOKUP(s$)
3010 ASSIGN "libgpiod.so","gpiod_chip_open_lookup"
3020 END FUNCTION
3030 !
3100 EXTERNAL FUNCTION gpiod_chip_get_line(n,t)
3110 ASSIGN "libgpiod.so","gpiod_chip_get_line"
3120 END FUNCTION
3130 !
3200 EXTERNAL SUB gpiod_line_request_output(n,s$,t)
3210 ASSIGN "libgpiod.so","gpiod_line_request_output"
3220 END SUB
3230 !
3300 EXTERNAL SUB gpiod_line_set_value(gpio, x)
3310 ASSIGN "libgpiod.so","gpiod_line_set_value"
3320 END SUB
3330 !
3400 EXTERNAL SUB gpiod_line_request_input(n,s$)
3410 ASSIGN "libgpiod.so","gpiod_line_request_input"
3420 END SUB
3430 !
3500 EXTERNAL FUNCTION gpiod_line_get_value(gpio)
3510 ASSIGN "libgpiod.so","gpiod_line_get_value"
3520 END FUNCTION
3530 !
3600 EXTERNAL SUB gpiod_chip_close(gchip)
3610 ASSIGN "libgpiod.so","gpiod_chip_close"
3620 END SUB
スイッチを押すごとにLEDのON,OFFを反転し,スイッチを10回押すと終了します。
Full BASICでは,まだ受け取られていないシグナルを重複して発出すると例外状態になります。
それを避けるため,並列単位Part1はシグナルgoを受け取るとシグナルreadyを発行してシグナルgoが発出可能になったことを知らせます。
なお,シグナルの名称は機能語ではありません。任意に名付けることができます。
Re: Raspberry Pi GPIO - SHIRAISHI Kazuo
2025/09/05 (Fri) 18:07:58
CallBack関数のテストです。
GPIODのgpiod_ctxless_event_monitorは,イベントが発生するとCallBack関数を呼び出します。
CallBack関数の形式は
https://libgpiod-dlang.dpldocs.info/gpiod.gpiod_ctxless_event_handle_cb.html
int function(int uint const(timespec)* void*)
となっているので,
はじめの2個が数値,後の2個が文字列型の引数を取る関数として用意します。(次プログラムの1180行)
ここでは,スイッチを押すごとにLEDのOn,Offを交替さています。
10回押すと終了するようにします。
CallBack関数が1を返すとgpiod_ctxless_event_monitorは終了します。
最初の引数のevtypeがイベントの種類で,スイッチを押したとき2, 戻ったとき3,Time Outのとき1です。
gpiod_ctxless_event_monitorの形式は
https://libgpiod-dlang.dpldocs.info/gpiod.gpiod_ctxless_event_monitor.html
int gpiod_ctxless_event_monitor(const(char)* device, int event_type, uint offset, bool active_low, const(char)* consumer,
const(timespec)* timeout, gpiod_ctxless_event_poll_cb poll_cb, gpiod_ctxless_event_handle_cb event_cb, void* data)
poll_cbはnilでいいのですが,厄介なのがtimeout でtimespec構造体へのポインタの形で用意しないといけません。
正確にはよくわからないのですが,1120行のようにしたら動きました。指定した秒数経過するとtimeoutでCallBackが発生します。
1番はじめの引数deviceでハマりました。結局,
https://note.com/bsoft/n/n66a5cf9c4910
https://qiita.com/jamjam/items/79f6561490d05afcd8aa
に倣って1110行,1130行のようにしています。
BASICAccでCallBack関数に指定できるのは外部手続きのみです。
そのため,モジュールを利用しているのですが,結果として,主プログラムがEND行のみになっています。
100 END
110 !
1000 MODULE GPIO
1010 MODULE OPTION ARITHMETIC NATIVE
1020 SHARE FUNCTION GPIOD_CHIP_OPEN_LOOKUP, gpiod_chip_get_line, gpiod_ctxless_event_monitor
1030 SHARE SUB gpiod_line_request_output, gpiod_line_set_value, gpiod_chip_close
1050 SHARE NUMERIC count,gchip,gpio4
1060 ! GPIO4の初期化
1070 LET GChip=GPIOD_CHIP_OPEN_LOOKUP(CHR$(0))
1080 LET gpio4 = gpiod_chip_get_line(GChip, 4)
1090 CALL gpiod_line_request_output(gpio4, "LED", 0)
1100 ! GPIO5をモニターする
1110 LET ChipName$="gpiochip4"
1120 LET timeout$=DWORD$(2)&DWORD$(0)&DWORD$(0)&DWORD$(0) ! Time out 2秒
1130 LET ret=gpiod_ctxless_event_monitor(chipname$, 3, 5, 1, "callback test", timeout$, 0, callbackadr(4), "")
1140 PRINT ret
1150 ! GPIO4の終了処理
1160 CALL gpiod_chip_close(GChip)
1170 !
1180 EXTERNAL FUNCTION cb(evtype, offset, ts$, data$), callback 4
1190 LET cb=0
1200 PRINT evtype
1210 IF evtype=2 THEN
1220 LET count=count+1
1230 CALL gpiod_line_set_value(gpio4, MOD(count,2))
1240 IF count=10 THEN LET cb=1
1250 ELSEIF evtype=3 then
1260 WAIT DELAY 0.5
1270 END IF
1280 END FUNCTION
1290 !
1300 EXTERNAL FUNCTION GPIOD_CHIP_OPEN_LOOKUP(s$)
1310 ASSIGN "libgpiod.so","gpiod_chip_open_lookup"
1320 END FUNCTION
1330 EXTERNAL FUNCTION gpiod_chip_get_line(n,t)
1340 ASSIGN "libgpiod.so","gpiod_chip_get_line"
1350 END FUNCTION
1360 EXTERNAL SUB gpiod_line_request_output(n,s$,t)
1370 ASSIGN "libgpiod.so","gpiod_line_request_output"
1380 END SUB
1390 EXTERNAL SUB gpiod_line_set_value(gpio, x)
1400 ASSIGN "libgpiod.so","gpiod_line_set_value"
1410 END SUB
1420 EXTERNAL SUB gpiod_chip_close(gchip)
1430 ASSIGN "libgpiod.so","gpiod_chip_close"
1440 END SUB
1450 EXTERNAL FUNCTION gpiod_ctxless_event_monitor(device$, event_type, offset, active_low, consumer$, timeout$, poll_cb, event_cb, data$)
1460 ASSIGN "libgpiod.so","gpiod_ctxless_event_monitor"
1470 END FUNCTION
1480 END MODULE
はじめ,1240 行を IF count=10 THEN LET cb=-1 としていましたが,それは,エラーを伝えるものでした。
そのため,64ビット環境で動かすと,1130行で得られる数が32ビットで-1を表す数になっていました。
64ビットOSのときは,BASICAcc,Decimal BASIC Ver.0.9のいずれでも動作します。
32ビットOSのときは,未確認ですが,BASICAccで動作すると思います。Decimal BASIC Ver.0.9ではCallBack関数が使えません。
Re: Raspberry Pi GPIO - SHIRAISHI Kazuo
2025/09/06 (Sat) 13:44:05
CallBack利用の改訂版です。
メインの処理を主プログラムに移動させました。
また,GPIOの出力にgpiod_ctxless_set_valueを使ってみることにしました。
https://libgpiod-dlang.dpldocs.info/gpiod.gpiod_ctxless_set_value.html
Raspberry Pi OS (Bookworm) 32bit上のBASICAcc1.2.2.4での動作も確認しています。
100 OPTION ARITHMETIC NATIVE
110 DECLARE EXTERNAL FUNCTION GPIO.gpiod_ctxless_event_monitor
120 LET timeout$=DWORD$(2)&DWORD$(0)&DWORD$(0)&DWORD$(0) ! Time out 2秒
130 LET ret=GPIO.gpiod_ctxless_event_monitor("gpiochip4", 3, 5, 1, "callback test", timeout$, 0, callbackadr(4), "")
140 PRINT ret
150 END
160 !
1000 MODULE GPIO
1010 MODULE OPTION ARITHMETIC NATIVE
1020 PUBLIC FUNCTION gpiod_ctxless_event_monitor
1030 SHARE SUB gpiod_ctxless_set_value
1050 SHARE NUMERIC count
1060 LET count=0
1170 !
1180 EXTERNAL FUNCTION cb(evtype, offset, ts$, data$), callback 4
1190 LET cb=0
1200 PRINT evtype
1210 IF evtype=2 THEN
1220 LET count=count+1
1230 CALL gpiod_ctxless_set_value("gpiochip4", 4, MOD(count,2), 0, "LED", 0, "")
1240 IF count=10 THEN LET cb=1
1250 ELSEIF evtype=3 then
1260 WAIT DELAY 0.5
1270 END IF
1280 END FUNCTION
1290 !
1300 EXTERNAL SUB gpiod_ctxless_set_value(device$,offset, value, active_low, consumer$, cb, data$)
1310 ASSIGN "libgpiod.so","gpiod_ctxless_set_value"
1320 END SUB
1450 EXTERNAL FUNCTION gpiod_ctxless_event_monitor(device$, event_type, offset, active_low, consumer$, timeout$, poll_cb, event_cb, data$)
1460 ASSIGN "libgpiod.so","gpiod_ctxless_event_monitor"
1470 END FUNCTION
1480 END MODULE
スイッチの押し方によっては期待通りに動作しないこともあるので,実用にするには,もう少し手を入れる必要があります。
Re: Raspberry Pi GPIO - SHIRAISHI Kazuo
2025/09/08 (Mon) 10:26:26
Ver. 0.9.2.6 ARM32ビット版は,ASSIGN文で定義するDLLの引数の個数に4個以下の制限があります。(Ver. 0.9.2.6 ARM64ビット版は10個以下)
(引数の個数の制限は,将来のバージョンで変更になる可能性もあります)
gpiod_ctxless_set_valueは7個の引数が必要ですが,はじめの4個のみを与えて残りはdefault値であることを受け入れてもらえるのかという少し乱暴なテストです。
gpiod_ctxless_get_valueは,引数4個なので問題はありません。
100 DECLARE EXTERNAL FUNCTION gpiod_ctxless_get_value
110 DECLARE EXTERNAL SUB gpiod_ctxless_set_value
120 FOR i=1 TO 10
130 DO WHILE gpiod_ctxless_get_value("gpiochip4", 5, 1, "")=0
140 LOOP
150 CALL gpiod_ctxless_set_value("gpiochip4", 4, mod(i,2), 0)
160 WAIT DELAY 0.5
170 NEXT i
180 END
1300 EXTERNAL SUB gpiod_ctxless_set_value(device$, offset, value, active_low)
1310 ASSIGN "libgpiod.so","gpiod_ctxless_set_value"
1320 END SUB
1400 EXTERNAL FUNCTION gpiod_ctxless_get_value(device$, offset, active_low, cosumer$)
1410 ASSIGN "libgpiod.so","gpiod_ctxless_get_value"
1420 END FUNCTION
スイッチを押すごとにLEDのON,OFFを切り替えます。10回押すと終了します。
Raspberry OS(bookworm)32ビットでの動作は安定しています。
Re: Raspberry Pi GPIO - SHIRAISHI Kazuo
2025/09/08 (Mon) 18:36:56
上掲のプログラムをBASICAccで実行するとAccess violationになります。
7個の引数が可能な環境では,素直に,以下のように記述する必要があります。
100 DECLARE EXTERNAL FUNCTION gpiod_ctxless_get_value
110 DECLARE EXTERNAL SUB gpiod_ctxless_set_value
120 FOR i=1 TO 10
130 DO WHILE gpiod_ctxless_get_value("gpiochip4", 5, 1, "")=0
140 LOOP
150 CALL gpiod_ctxless_set_value("gpiochip4", 4, mod(i,2), 0, "", 0, "")
160 WAIT DELAY 0.5
170 NEXT i
180 END
1300 EXTERNAL SUB gpiod_ctxless_set_value(device$, offset, value, active_low, consumer$, cb, data$)
1310 ASSIGN "libgpiod.so","gpiod_ctxless_set_value"
1320 END SUB
1400 EXTERNAL FUNCTION gpiod_ctxless_get_value(device$, offset, active_low, cosumer$)
1410 ASSIGN "libgpiod.so","gpiod_ctxless_get_value"
1420 END FUNCTION
Raspberry Pi OS (Trixie) - SHIRAISHI Kazuo
2026/01/26 (Mon) 10:30:11
Raspberry Pi OS (Trixie)では,libgpiod3が標準となって,libgpiod2はインストールができないようです。
sudo apt install libgpiod3 libgpiod-dev libgpiod-doc
を実行して /usr/share/doc/libgpiod-dev/html/ を探してもこのライブラリをどう使えばよいかの解説が見当たりません。
ねっちゅう工房 ラズパイ5(Raspberry Pi 5)でLチカ https://nettyukobo.com/raspberrypi5_start_2/
で公開されている「C言語でLED点灯」の移植を試みました。
移植に必要な情報は /usr/share/doc/libgpiod-dev/html/gpiod_8h_source.html にあるgpoid.h から得られます。
バージョンが一致しない可能性がありますが,githubにある https://github.com/brgl/libgpiod/blob/master/include/gpiod.h も同じものです。
移植にあたって留意することはポインタ引数の扱いです。十進BASICではポインタは数値として処理します。
250行,270行,300行,350行にある chip, settings,line_cfg,requestとして得られる値はポインタです。
なので,それを引数に持つ手続きgpiod_line_settings_set_directionなどが持つポインタ型の引数は数値です。
一方で,gpiod_line_config_add_line_settingsが持つポインタ型の引数は,他のポインタを代入するのではなくて,不定個数の整数値の配列の先頭を指すものです。
なので,gpiod_line_config_add_line_settingsが持つポインタ型の引数は文字列で定義します。
以下に示すプログラムは素直に移植しただけです。私はLEDをGPIO4に接続しているので,190行のline_offsetを4にしています。
難解なのは,GPIOチップの名称で,Raspberry Pi OS (Bookworm)ではgpiochip4だったのですが,今度はgpiochip0です。
それは,ターミナルで,gpioinfo を実行すると確認できますが,GPIOチップの名称はどのようにして決まるのでしょうか?
100 REM ねっちゅう工房 ラズパイ5(Raspberry Pi 5)でLチカ
110 REM https://nettyukobo.com/raspberrypi5_start_2/
120 REM C言語でLED点灯
130 ! sudo apt install libgpiod3 libgpiod-dev libgpiod-doc
140 ! /usr/share/doc/libgpiod-dev/html/gpiod_8h_source.html
150 OPTION ARITHMETIC NATIVE
160 DECLARE EXTERNAL FUNCTION gpiod_chip_open, gpiod_line_settings_new, gpiod_line_config_new
170 DECLARE EXTERNAL FUNCTION gpiod_request_config_new, gpiod_chip_request_lines
180 !
190 LET line_offset=4
200 LET GPIOD_LINE_VALUE_INACTIVE = 0
210 LET GPIOD_LINE_VALUE_ACTIVE = 1
220 LET GPIOD_LINE_DIRECTION_INPUT = 2
230 LET GPIOD_LINE_DIRECTION_OUTPUT = 3
240 ! /* --- 1. GPIO チップを開く --- */
250 LET chip=gpiod_chip_open("/dev/gpiochip0")
260 ! /* --- 2. ライン設定を作る --- */
270 LET settings = gpiod_line_settings_new
280 CALL gpiod_line_settings_set_direction(settings, GPIOD_LINE_DIRECTION_OUTPUT)
290 CALL gpiod_line_settings_set_output_value(settings, GPIOD_LINE_VALUE_INACTIVE)
300 LET line_cfg = gpiod_line_config_new
310 CALL gpiod_line_config_add_line_settings(line_cfg, DWORD$(line_offset), 1, settings)
320 ! /* --- 3. ライン要求設定 --- */
330 LET req_cfg = gpiod_request_config_new
340 CALL gpiod_request_config_set_consumer(req_cfg, "blink")
350 LET request = gpiod_chip_request_lines(chip, req_cfg, line_cfg)
360 ! /* --- 4. Lチカループ --- */
370 FOR i=1 TO 10
380 CALL gpiod_line_request_set_value(request, line_offset, GPIOD_LINE_VALUE_ACTIVE)
390 WAIT DELAY 0.25
400 CALL gpiod_line_request_set_value(request, line_offset, GPIOD_LINE_VALUE_INACTIVE)
410 WAIT DELAY 0.25
420 NEXT i
430 ! /* --- 5. 後始末 --- */
440 CALL gpiod_line_request_release(request)
450 CALL gpiod_line_settings_free(settings)
460 CALL gpiod_line_config_free(line_cfg)
470 CALL gpiod_request_config_free(req_cfg)
480 CALL gpiod_chip_close(chip)
490 END
1000 !
1010 EXTERNAL FUNCTION gpiod_chip_open(s$)
1020 ASSIGN "libgpiod.so","gpiod_chip_open"
1030 END FUNCTION
1040 EXTERNAL FUNCTION gpiod_line_settings_new
1050 assign "libgpiod.so","gpiod_line_settings_new"
1060 END FUNCTION
1070 EXTERNAL SUB gpiod_line_settings_set_direction(settings,direction)
1080 ASSIGN "libgpiod.so","gpiod_line_settings_set_direction"
1090 END SUB
1100 EXTERNAL SUB gpiod_line_settings_set_output_value(settings,line_value)
1110 ASSIGN "libgpiod.so","gpiod_line_settings_set_output_value"
1120 END SUB
1130 EXTERNAL FUNCTION gpiod_line_config_new
1140 ASSIGN "libgpiod.so","gpiod_line_config_new"
1150 END FUNCTION
1160 EXTERNAL SUB gpiod_line_config_add_line_settings(config,offsets$,num_offsets,settings)
1170 ASSIGN "libgpiod.so", "gpiod_line_config_add_line_settings"
1180 END SUB
1190 EXTERNAL FUNCTION gpiod_request_config_new
1200 ASSIGN "libgpiod.so", "gpiod_request_config_new"
1210 END FUNCTION
1220 EXTERNAL SUB gpiod_request_config_set_consumer(config,consumer$)
1230 ASSIGN "libgpiod.so","gpiod_request_config_set_consumer"
1240 END SUB
1250 EXTERNAL FUNCTION gpiod_chip_request_lines(chip, req_cfg, line_cfg)
1260 ASSIGN "libgpiod.so","gpiod_chip_request_lines"
1270 END FUNCTION
1280 EXTERNAL SUB gpiod_line_request_set_value(request,offset,value)
1290 ASSIGN "libgpiod.so","gpiod_line_request_set_value"
1300 END SUB
1310 EXTERNAL SUB gpiod_line_request_release(request)
1320 ASSIGN "libgpiod.so","gpiod_line_request_release"
1330 END SUB
1340 EXTERNAL SUB gpiod_line_settings_free(settings)
1350 ASSIGN "libgpiod.so", "gpiod_line_settings_free"
1360 END SUB
1370 EXTERNAL SUB gpiod_line_config_free(line_cfg)
1380 ASSIGN "libgpiod.so","gpiod_line_config_free"
1390 END SUB
1400 EXTERNAL SUB gpiod_request_config_free(req_cfg)
1410 ASSIGN "libgpiod.so","gpiod_request_config_free"
1420 END SUB
1430 EXTERNAL SUB gpiod_chip_close(chip)
1440 ASSIGN "libgpiod.so","gpiod_chip_close"
1450 END SUB
Raspberry Pi (Trixie) GPIO 入力と出力 - SHIRAISHI Kazuo
2026/01/26 (Mon) 20:32:15
GPIO4にLED,GPIO5にスイッチを接続しているので,入力と出力の双方に対応させました。
スイッチを押すごとにLEDの点灯,消灯を反転し,10回押すと終了です。終了するとLEDが点滅します。
GPIOの処理はmoduleにまとめています。
GPIOの初期化はGPIO.init_beginで開始し,GPIO_init_finishで完了します。その間で,ポートごとの入力,出力の別を設定します。
GPIOチップの名称"/dev/gpiochip0"はmodule内で設定していますが,変更が必要であれば,GPIO.init_beginの引数にして,その都度,設定するものにもできます。
最後に,GPIO.closeを実行して終了です。
なお,APIの組み立て方に関するマニュアルを探し出して作ったものではないので,不適切な構成になっている可能性があります。
(正式なドキュメントは,https://libgpiod.readthedocs.io/en/latest/ にあって,個別の説明はありますが,それをどう組み立てて使うかの説明が見当たりません。)
100 OPTION ARITHMETIC NATIVE
110 DECLARE EXTERNAL SUB GPIO.init_begin, GPIO.set_input, GPIO.set_output, GPIO.init_finish
120 DECLARE EXTERNAL FUNCTION GPIO.read
130 DECLARE EXTERNAL SUB GPIO.write, GPIO.close
140 DECLARE NUMERIC gpin, gpout
150 LET gpout = 4
160 LET gpin = 5
170 !
180 CALL GPIO.init_begin
190 CALL GPIO.set_output(gpout)
200 CALL GPIO.set_input(gpin)
210 CALL GPIO.init_finish
220 !
230 DECLARE NUMERIC i
240 FOR i=1 TO 10
250 CALL GPIO.write(gpout, MOD(i,2))
260 DO UNTIL GPIO.read(gpin)=0
270 LOOP
280 WAIT DELAY 0.25
290 NEXT i
300 !
310 FOR i=1 TO 10
320 CALL GPIO.write(gpout, MOD(i,2))
330 WAIT DELAY 0.1
340 NEXT i
350 !
360 CALL GPIO.close
370 END
1000 !
1010 MODULE GPIO
1020 MODULE OPTION ARITHMETIC NATIVE
1030 PUBLIC SUB init_begin, set_input, set_output, init_finish
1040 PUBLIC SUB write, close
1050 PUBLIC FUNCTION read
1060 SHARE NUMERIC chip, request
1070 SHARE FUNCTION gpiod_chip_open, gpiod_line_settings_new, gpiod_line_config_new
1080 SHARE FUNCTION gpiod_request_config_new, gpiod_chip_request_lines, gpiod_line_request_get_value
1090 ! 定数の初期化
1100 SHARE NUMERIC GPIOD_LINE_DIRECTION_INPUT, GPIOD_LINE_DIRECTION_OUTPUT
1110 LET GPIOD_LINE_DIRECTION_INPUT = 2
1120 LET GPIOD_LINE_DIRECTION_OUTPUT = 3
1130 SHARE STRING consumer$
1140 LET consumer$="Decimal BASIC"
1150 !
1159 SHARE NUMERIC line_cfg ! init_beginで初期化され,init_finishでお役御免
1160 EXTERNAL SUB init_begin
1170 LET chip = gpiod_chip_open("/dev/gpiochip0")
1180 LET line_cfg = gpiod_line_config_new
1190 END SUB
1200 !
1210 EXTERNAL SUB set_input(offset)
1220 DECLARE NUMERIC settings
1230 LET settings = gpiod_line_settings_new
1240 CALL gpiod_line_settings_set_direction(settings, GPIOD_LINE_DIRECTION_INPUT)
1250 CALL gpiod_line_config_add_line_settings(line_cfg, DWORD$(offset), 1, settings)
1260 CALL gpiod_line_settings_free(settings)
1270 END SUB
1280 !
1290 EXTERNAL SUB set_output(offset)
1300 DECLARE NUMERIC settings
1310 LET settings = gpiod_line_settings_new
1320 CALL gpiod_line_settings_set_direction(settings, GPIOD_LINE_DIRECTION_OUTPUT)
1330 CALL gpiod_line_settings_set_output_value(settings, 0)
1340 CALL gpiod_line_config_add_line_settings(line_cfg, DWORD$(offset), 1, settings)
1350 CALL gpiod_line_settings_free(settings)
1360 END SUB
1370 !
1380 EXTERNAL SUB Init_finish
1390 DECLARE NUMERIC req_cfg
1400 LET req_cfg = gpiod_request_config_new
1410 CALL gpiod_request_config_set_consumer(req_cfg, consumer$)
1420 LET request = gpiod_chip_request_lines(chip, req_cfg, line_cfg)
1430 CALL gpiod_request_config_free(req_cfg)
1440 CALL gpiod_line_config_free(line_cfg) ! 以降,line_cfgは無効
1450 END SUB
1460 !
1470 EXTERNAL SUB write(offset, n)
1480 CALL gpiod_line_request_set_value(request, offset, n)
1490 END SUB
1500 !
1510 EXTERNAL FUNCTION read(offset)
1520 LET read=gpiod_line_request_get_value(request, offset)
1530 END FUNCTION
1540 !
1550 EXTERNAL SUB CLOSE
1560 CALL gpiod_line_request_release(request)
1570 CALL gpiod_chip_close(chip)
1580 END SUB
1590 !
1600 EXTERNAL FUNCTION gpiod_chip_open(s$)
1610 ASSIGN "libgpiod.so","gpiod_chip_open"
1620 END FUNCTION
1630 EXTERNAL FUNCTION gpiod_line_settings_new
1640 assign "libgpiod.so","gpiod_line_settings_new"
1650 END FUNCTION
1660 EXTERNAL SUB gpiod_line_settings_set_direction(settings,direction)
1670 ASSIGN "libgpiod.so","gpiod_line_settings_set_direction"
1680 END SUB
1690 EXTERNAL SUB gpiod_line_settings_set_output_value(settings,line_value)
1700 ASSIGN "libgpiod.so","gpiod_line_settings_set_output_value"
1710 END SUB
1720 EXTERNAL FUNCTION gpiod_line_config_new
1730 ASSIGN "libgpiod.so","gpiod_line_config_new"
1740 END FUNCTION
1750 EXTERNAL SUB gpiod_line_config_add_line_settings(config,offsets$,num_offsets,settings)
1760 ASSIGN "libgpiod.so", "gpiod_line_config_add_line_settings"
1770 END SUB
1780 EXTERNAL FUNCTION gpiod_request_config_new
1790 ASSIGN "libgpiod.so", "gpiod_request_config_new"
1800 END FUNCTION
1810 EXTERNAL SUB gpiod_request_config_set_consumer(config,consumer$)
1820 ASSIGN "libgpiod.so","gpiod_request_config_set_consumer"
1830 END SUB
1840 EXTERNAL FUNCTION gpiod_chip_request_lines(chip, req_cfg, line_cfg)
1850 ASSIGN "libgpiod.so","gpiod_chip_request_lines"
1860 END FUNCTION
1870 EXTERNAL SUB gpiod_line_request_set_value(request,offset,value)
1880 ASSIGN "libgpiod.so","gpiod_line_request_set_value"
1890 END SUB
1900 EXTERNAL FUNCTION gpiod_line_request_get_value(request, offset)
1910 ASSIGN "libgpiod.so","gpiod_line_request_get_value"
1920 END FUNCTION
1930 EXTERNAL SUB gpiod_line_request_release(request)
1940 ASSIGN "libgpiod.so","gpiod_line_request_release"
1950 END SUB
1960 EXTERNAL SUB gpiod_line_settings_free(settings)
1970 ASSIGN "libgpiod.so", "gpiod_line_settings_free"
1980 END SUB
1990 EXTERNAL SUB gpiod_line_config_free(line_cfg)
2000 ASSIGN "libgpiod.so","gpiod_line_config_free"
2010 END SUB
2020 EXTERNAL SUB gpiod_request_config_free(req_cfg)
2030 ASSIGN "libgpiod.so","gpiod_request_config_free"
2040 END SUB
2050 EXTERNAL SUB gpiod_chip_close(chip)
2060 ASSIGN "libgpiod.so","gpiod_chip_close"
2070 END SUB
2080 END MODULE
Raspberry Pi (Trixie) GPIO 補遺 - SHIRAISHI Kazuo
2026/01/29 (Thu) 09:30:50
プログラム実行中に別のBASICを起動してプログラムを実行すると,後から起動したBASICが異常終了します。
他のプログラムがGPIOポートを使用中に実行しようとするとエラーになるように,1421~1426行を追加しました。
gpioinfoに /dev/gpiochip4 は現れないのですが, /dev/gpiochip4 がシンボリックリンクとして登録されていて,/dev/gpiochip4 を指定しても動作しました。
1130行でGchip$とconsuner$をPUBLICに指定し,default値を,それぞれ,"/dev/gpiochi4",ログインユーザ名としました。
136行,137行のREMを取り除いて修正すれば,他の値を用いることができます。
なお,環境変数"HOME"は"/home/"で始まる文字列であることを前提としていますが,そうでない環境では1141行の修正が必要です。
100 OPTION ARITHMETIC NATIVE
110 DECLARE EXTERNAL SUB GPIO.init_begin, GPIO.set_input, GPIO.set_output, GPIO.init_finish
120 DECLARE EXTERNAL FUNCTION GPIO.read
130 DECLARE EXTERNAL SUB GPIO.write, GPIO.close
135 DECLARE EXTERNAL STRING GPIO.GChip$, GPIO.consumer$
136 REM LET GPIO.GChip$="/dev/gpiochip0"
137 REM LET GPIO.consumer$="Decimal BASIC"
140 DECLARE NUMERIC gpin, gpout
150 LET gpout = 4
160 LET gpin = 5
170 !
180 CALL GPIO.init_begin
190 CALL GPIO.set_output(gpout)
200 CALL GPIO.set_input(gpin)
210 CALL GPIO.init_finish
220 !
230 DECLARE NUMERIC i
240 FOR i=1 TO 10
250 CALL GPIO.write(gpout, MOD(i,2))
260 DO UNTIL GPIO.read(gpin)=0
270 LOOP
280 WAIT DELAY 0.25
290 NEXT i
300 !
310 FOR i=1 TO 10
320 CALL GPIO.write(gpout, MOD(i,2))
330 WAIT DELAY 0.1
340 NEXT i
350 !
360 CALL GPIO.close
370 END
1000 !
1010 MODULE GPIO
1020 MODULE OPTION ARITHMETIC NATIVE
1030 PUBLIC SUB init_begin, set_input, set_output, init_finish
1040 PUBLIC SUB write, close
1050 PUBLIC FUNCTION read
1060 SHARE NUMERIC chip, request
1070 SHARE FUNCTION gpiod_chip_open, gpiod_line_settings_new, gpiod_line_config_new
1080 SHARE FUNCTION gpiod_request_config_new, gpiod_chip_request_lines, gpiod_line_request_get_value
1090 ! 定数の初期化
1100 SHARE NUMERIC GPIOD_LINE_DIRECTION_INPUT, GPIOD_LINE_DIRECTION_OUTPUT
1110 LET GPIOD_LINE_DIRECTION_INPUT = 2
1120 LET GPIOD_LINE_DIRECTION_OUTPUT = 3
1130 PUBLIC STRING GChip$, consumer$
1135 LET GChip$="/dev/gpiochip4"
1140 ASK EnvironmentVariable("HOME") consumer$
1141 LET consumer$=consumer$(LEN("/home/")+1 : 255)
1150 !
1159 SHARE NUMERIC line_cfg ! init_beginで初期化され,init_finishでお役御免
1160 EXTERNAL SUB init_begin
1170 LET chip = gpiod_chip_open(GChip$)
1180 LET line_cfg = gpiod_line_config_new
1190 END SUB
1200 !
1210 EXTERNAL SUB set_input(offset)
1220 DECLARE NUMERIC settings
1230 LET settings = gpiod_line_settings_new
1240 CALL gpiod_line_settings_set_direction(settings, GPIOD_LINE_DIRECTION_INPUT)
1250 CALL gpiod_line_config_add_line_settings(line_cfg, DWORD$(offset), 1, settings)
1260 CALL gpiod_line_settings_free(settings)
1270 END SUB
1280 !
1290 EXTERNAL SUB set_output(offset)
1300 DECLARE NUMERIC settings
1310 LET settings = gpiod_line_settings_new
1320 CALL gpiod_line_settings_set_direction(settings, GPIOD_LINE_DIRECTION_OUTPUT)
1330 CALL gpiod_line_settings_set_output_value(settings, 0)
1340 CALL gpiod_line_config_add_line_settings(line_cfg, DWORD$(offset), 1, settings)
1350 CALL gpiod_line_settings_free(settings)
1360 END SUB
1370 !
1380 EXTERNAL SUB Init_finish
1390 DECLARE NUMERIC req_cfg
1400 LET req_cfg = gpiod_request_config_new
1410 CALL gpiod_request_config_set_consumer(req_cfg, consumer$)
1420 LET request = gpiod_chip_request_lines(chip, req_cfg, line_cfg)
1421 IF request=0 THEN
1422 PRINT "GPIO Initialization failed"
1423 CALL close
1425 STOP
1426 END IF
1430 CALL gpiod_request_config_free(req_cfg)
1440 CALL gpiod_line_config_free(line_cfg)
1450 END SUB
1460 !
1470 EXTERNAL SUB write(offset, n)
1480 CALL gpiod_line_request_set_value(request, offset, n)
1490 END SUB
1500 !
1510 EXTERNAL FUNCTION read(offset)
1520 LET read=gpiod_line_request_get_value(request, offset)
1530 END FUNCTION
1540 !
1550 EXTERNAL SUB CLOSE
1560 CALL gpiod_line_request_release(request)
1570 CALL gpiod_chip_close(chip)
1580 END SUB
1590 !
1600 EXTERNAL FUNCTION gpiod_chip_open(s$)
1610 ASSIGN "libgpiod.so","gpiod_chip_open"
1620 END FUNCTION
1630 EXTERNAL FUNCTION gpiod_line_settings_new
1640 assign "libgpiod.so","gpiod_line_settings_new"
1650 END FUNCTION
1660 EXTERNAL SUB gpiod_line_settings_set_direction(settings,direction)
1670 ASSIGN "libgpiod.so","gpiod_line_settings_set_direction"
1680 END SUB
1690 EXTERNAL SUB gpiod_line_settings_set_output_value(settings,line_value)
1700 ASSIGN "libgpiod.so","gpiod_line_settings_set_output_value"
1710 END SUB
1720 EXTERNAL FUNCTION gpiod_line_config_new
1730 ASSIGN "libgpiod.so","gpiod_line_config_new"
1740 END FUNCTION
1750 EXTERNAL SUB gpiod_line_config_add_line_settings(config,offsets$,num_offsets,settings)
1760 ASSIGN "libgpiod.so", "gpiod_line_config_add_line_settings"
1770 END SUB
1780 EXTERNAL FUNCTION gpiod_request_config_new
1790 ASSIGN "libgpiod.so", "gpiod_request_config_new"
1800 END FUNCTION
1810 EXTERNAL SUB gpiod_request_config_set_consumer(config,consumer$)
1820 ASSIGN "libgpiod.so","gpiod_request_config_set_consumer"
1830 END SUB
1840 EXTERNAL FUNCTION gpiod_chip_request_lines(chip, req_cfg, line_cfg)
1850 ASSIGN "libgpiod.so","gpiod_chip_request_lines"
1860 END FUNCTION
1870 EXTERNAL SUB gpiod_line_request_set_value(request,offset,value)
1880 ASSIGN "libgpiod.so","gpiod_line_request_set_value"
1890 END SUB
1900 EXTERNAL FUNCTION gpiod_line_request_get_value(request, offset)
1910 ASSIGN "libgpiod.so","gpiod_line_request_get_value"
1920 END FUNCTION
1930 EXTERNAL SUB gpiod_line_request_release(request)
1940 ASSIGN "libgpiod.so","gpiod_line_request_release"
1950 END SUB
1960 EXTERNAL SUB gpiod_line_settings_free(settings)
1970 ASSIGN "libgpiod.so", "gpiod_line_settings_free"
1980 END SUB
1990 EXTERNAL SUB gpiod_line_config_free(line_cfg)
2000 ASSIGN "libgpiod.so","gpiod_line_config_free"
2010 END SUB
2020 EXTERNAL SUB gpiod_request_config_free(req_cfg)
2030 ASSIGN "libgpiod.so","gpiod_request_config_free"
2040 END SUB
2050 EXTERNAL SUB gpiod_chip_close(chip)
2060 ASSIGN "libgpiod.so","gpiod_chip_close"
2070 END SUB
2080 END MODULE
Re: Raspberry Pi LGPIO - SHIRAISHI Kazuo
2026/02/01 (Sun) 09:03:17
libgpiodに代わるものとしてLGPIOをテストしてみました。
インストール方法は
https://pimylifeup.com/raspberry-pi-install-lgpio/
ライブラリの説明は
https://abyz.me.uk/lg/lgpio.html#lgI2cReadByte
にあります。
Ver. 0.9.4.0だと実行はできるのですが,実行後にBASIC本体に障害が発生し,フリーズするか異常終了します。
Ver. 0.9のときは,Ver. 0.9.4.1以降を使用してください。
BASICAccとParactBASICでは問題ありません。
Bookworm 64ビット,Trixie 64ビットでテストしています。
310行の引数 0 はgpiochip0を意味します。gpiochip4だったら 4 を指定してください。
320行以降の引数にある 4,5 は,GPIOの番号です。
100 OPTION ARITHMETIC NATIVE
110 FUNCTION lgGpiochipOpen(gpioDev)
120 ASSIGN "liblgpio.so", "lgGpiochipOpen"
130 END FUNCTION
140 SUB lgGpiochipClose(handle)
150 ASSIGN "liblgpio.so", "lgGpiochipClose"
160 END SUB
170 FUNCTION lgGpioClaimOutput(handle,flags,gpio,level)
180 ASSIGN "liblgpio.so", "lgGpioClaimOutput"
190 END FUNCTION
200 SUB lgGpioWrite(handle,gpio,level)
210 ASSIGN "liblgpio.so", "lgGpioWrite"
220 END SUB
230 FUNCTION lgGpioClaimInput(handle,flags,gpio)
240 ASSIGN "liblgpio.so", "lgGpioClaimInput"
250 END FUNCTION
260 FUNCTION lgGpioRead(hnadle, gpio)
270 ASSIGN "liblgpio.so", "lgGpioRead"
280 END FUNCTION
290 !
300 DECLARE NUMERIC h ! handle
310 LET h=lgGpiochipOpen(0)
320 IF lgGpioClaimOutput(h,0,4,0)=0 AND lgGpioClaimInput(h,0,5)=0 THEN
330 DECLARE NUMERIC i
340 FOR i=1 TO 10
350 CALL lgGpioWrite(h,4,MOD(i,2))
360 DO UNTIL lgGpioRead(h, 5)=0
370 LOOP
380 WAIT DELAY 0.25
390 NEXT i
400 FOR i=1 TO 10
410 CALL lgGpioWrite(h,4,MOD(i,2))
420 WAIT DELAY 0.1
430 NEXT i
440 END if
450 CALL lgGpiochipClose(h)
460 END
Note.
LGPIOでは,関数値が負のとき失敗を意味するが,ASSIGN文ではその値を64ビット整数として評価するので,負数になるべきとき,その値は2^31以上の数になる。
(32ビットの値を出力するとき,64ビットレジスタの上位32ビットは0に固定されているように思われる‥‥‥ただし,すべての場合に成立するか不明)