もくじ
●1.はじめに
●2.環境
●3.構成
●4.準備 ~Linux 環境作成~
●5.準備 ~Linux 上で GPIO の制御方法の確認~
●6.準備 ~LINE の送信~
●7.Python コード
●8.実行結果
●9.おわり
1.はじめに
以前、Intel® Cyclone V SoC のキット(Atlas)と PC を LAN ケーブルで繋ぎ、Python で UDP パケット通信させてみた の記事を作成した際、SoC FPGA を Python で動かすことができれば、色々面白そうと思いました。
センサーで取得したデータや FPGA 側のデータを、Python の豊富なライブラリで扱えると、夢が広がりますよね。
今回はまず手始めとして、プッシュボタンが押されたら、LINE へ通知 & LED の点灯、という Python アプリを作成してみました。
まずは成果物を見たい方は、下記リンクで飛んでみてください。
8.実行結果
ぜひ、最後まで読んでみてください!
2.環境
-
使用ボード
Terasic 社 DE0-nano-SoC(Atlas)
※Intel® Cyclone V SoC が搭載されています。 -
Linux 環境
Rootfile System -> Poky
Linux Kernel version -> 5.15.70 -
Python
Python version -> 3.10.7
3. 構成 & 動作手順
■構成
HPS 内の CPU(Cortex-A9)に Linux を実装し、こちらの環境で Python プログラムを実行します。
使用するインターフェースは、GPIO、UART、LAN ケーブルです。
■動作手順
手順は大まかに図の中に示した ① ~ ③ です。
①. プッシュボタンを押す
②. LED を点灯
③. LINE にプッシュボタンが押されたことを通知
4. 準備 ~Linux 環境作成~
下記資料を参考に Linux が起動するまでの環境を作成しました。
Building Bootloader for Cyclone V and Arria 10
5. 準備 ~Linux 上で GPIO の制御方法の確認~
Atlas に Linux 環境を実装し、下記フローで GPIO は制御できるのを確認しました。
~
a. /sys/class/gpio/ へ移動
b. 使用したい GPIO の番号を export に書き込み
c. /sys/class/gpio/ 下に gpio<番号> のディレクトリが作成されていることを確認
d. /gpio<番号>/direction で、入出力設定
e. /gpio<番号>/value で、入力なら値を確認、出力なら値を設定
f. 使用し終わったら、GPIO の番号を unexport に書き込み
g. gpio<番号> ディレクトリが削除されていることを確認
~
実際に GPIO を制御したログを以下に記載します。
■LEDの GPIO 動作確認
root@cyclone5:/sys/class/gpio#
root@cyclone5:/sys/class/gpio# ls
export gpiochip1963 gpiochip1990 gpiochip2019 unexport
root@cyclone5:/sys/class/gpio# echo 2014 > export
root@cyclone5:/sys/class/gpio# ls
export gpio2014 gpiochip1963 gpiochip1990 gpiochip2019 unexport
root@cyclone5:/sys/class/gpio# echo out > gpio2014/direction
root@cyclone5:/sys/class/gpio# echo 1 > gpio2014/value
root@cyclone5:/sys/class/gpio# echo 0 > gpio2014/value
root@cyclone5:/sys/class/gpio# echo 2014 > unexport
root@cyclone5:/sys/class/gpio# ls
export gpiochip1963 gpiochip1990 gpiochip2019 unexport
■プッシュボタンの GPIO 動作確認
root@cyclone5:/sys/class/gpio# ls
export gpiochip1963 gpiochip1990 gpiochip2019 unexport
root@cyclone5:/sys/class/gpio# echo 2015 > export
root@cyclone5:/sys/class/gpio# ls
export gpio2015 gpiochip1963 gpiochip1990 gpiochip2019 unexport
root@cyclone5:/sys/class/gpio# echo in > gpio2015/direction
root@cyclone5:/sys/class/gpio# cat gpio2015/value
1
root@cyclone5:/sys/class/gpio# cat gpio2015/value
0
root@cyclone5:/sys/class/gpio# echo 2015 > unexport
root@cyclone5:/sys/class/gpio#
root@cyclone5:/sys/class/gpio# ls
export gpiochip1963 gpiochip1990 gpiochip2019 unexport
root@cyclone5:/sys/class/gpio#
※export に登録する GPIO の番号の補足
使用したい GPIO の番号を export に書き込みますが、
その際、GPIO の番号にオフセットを足す必要があります。
本来、プッシュボタンと LED の GPIO の番号は下記です。
(export に登録するオフセットを足した値は()の中に記載しています)
- プッシュボタンの GPIO: 54(export に登録する値 -> 2015)
- LED の GPIO: 53(export に登録する値 -> 2014)
オフセットの求め方を以下に記載していますが、
特に興味が無ければ、6. 準備 ~LINE の送信~ まで読み飛ばして大丈夫です。
■オフセットの求め方
トータル 85 本の GPIO は 3 グループに分かれています。
GPIO | Pin Number | Address |
---|---|---|
gpio0 | [28:0] | 0xFF70_8000 |
gpio1 | [57:29] | 0xFF70_9000 |
gpio2 | [84:58] | 0xFF70_A000 |
/sys/class/gpio/ 下の、それぞれの gpiochipXXX 内の label を確認すると、
下記のようになっていました。
gpiochip2019/label: ff708000.gpio
gpiochip1990/label: ff709000.gpio
gpiochip1963/label: ff70a000.gpio
gpiochip2019 は gpio0、gpiochip1990 は gpio1、gpiochip1963 は gpio2 を表しているのかと思います。
gpiochip"xxx" の xxx を各 gpio0~2 のそれぞれのオフセットとします。
gpio0: 1963、gpio1: 1990、gpio2: 2019
例えば、今回の LED の GPIO[53] の場合、
gpio1 に含まれるので、gpio1[24]となります(53-29(gpio0))。
24 に gpio1 のオフセットを足しますので、
24 + 1990 = 2014
となります。
(下記 label の値を確認したときのログ)
root@cyclone5:/sys/class/gpio# ls
export gpiochip1963 gpiochip1990 gpiochip2019 unexport
root@cyclone5:/sys/class/gpio# cat gpiochip1963/label
ff70a000.gpio
root@cyclone5:/sys/class/gpio# cat gpiochip1990/label
ff709000.gpio
root@cyclone5:/sys/class/gpio# cat gpiochip2019/label
ff708000.gpio
root@cyclone5:/sys/class/gpio#
6. 準備 ~LINE の送信~
LINE へメッセージを送る際には、LINE notify を使用しています。
LINE notify については、下記記事で紹介されていましたので、こちらを参考にしてみてください。
PythonでLINE Notifyへ通知を送る
下記コードを使用し、LINE へメッセージ(Hello!)が送れることを確認しました。
import requests
def send_line_notify(notification_message, package_id, sticker_id):
line_notify_token = <LINE notify のトークン>
line_notify_api = 'https://notify-api.line.me/api/notify'
headers = {'Authorization': f'Bearer {line_notify_token}'}
data = {'message': f'{notification_message}', 'stickerPackageId': package_id, 'stickerId': sticker_id}
requests.post(line_notify_api, headers = headers, data = data)
send_line_notify('Hello!', 4, 303)
7. Python コード
GPIO の制御と LINE へのメッセージ通知を合わせ、最終的なコードは下記のようになりました。
import subprocess
import requests
import datetime
print('=====Start!=====')
print('Open GPIO')
subprocess.run('echo 2015 > /sys/class/gpio/export', shell=True)
subprocess.run('echo in > /sys/class/gpio/gpio2015/direction', shell=True)
subprocess.run('echo 2014 > /sys/class/gpio/export', shell=True)
subprocess.run('echo out > /sys/class/gpio/gpio2014/direction', shell=True)
print('Wait Push the KEY...')
def send_line_notify(notification_message, package_id, sticker_id):
line_notify_token = <LINE notify のトークン>
line_notify_api = 'https://notify-api.line.me/api/notify'
headers = {'Authorization': f'Bearer {line_notify_token}'}
data = {'message': f'{notification_message}', 'stickerPackageId': package_id, 'stickerId': sticker_id}
requests.post(line_notify_api, headers = headers, data = data)
while True:
result=subprocess.run('cat /sys/class/gpio/gpio2015/value', shell=True, capture_output=True)
if result.stdout == b'0\n':
print('----------')
t=datetime.datetime.now()
print(t)
print('Pushed the KEY!')
print('LED ON!')
subprocess.run('echo out > /sys/class/gpio/gpio2014/direction', shell=True)
subprocess.run('echo 1 > /sys/class/gpio/gpio2014/value', shell=True)
print('Send the LINE!')
send_line_notify('Pushed the KEY!', 3, 222)
print('----------')
break;
elif result.stdout == b'1\n':
pass
else:
print('unknow')
print('Close GPIO')
subprocess.run('echo 2015 > /sys/class/gpio/unexport', shell=True)
subprocess.run('echo 2014 > /sys/class/gpio/unexport', shell=True)
print('=====Finish!=====')
8. 実行結果
届いた LINE メッセージと LED の点灯は以下の通りです。
簡単に LINE にメッセージが送れたり、LED の制御ができると、なんだか楽しいですね!
9. おわりに
手始めとして作成したプログラムですが、LINE へのメッセージや GPIO の制御など、簡単にできて楽しかったです。
やはり、Python のライブラリを活用し何か物を作成することは、とても夢があると感じます!
今後も、Python を用いて色々なことに挑戦してみたいと思いました。