Raspberry PiをFirewall/NAT越しにWebアプリケーションを公開する【ngrok】

Raspberry PiをFirewall/NAT越しにWebアプリケーションを公開する【ngrok】

RaspberryPiなどでWebアプリケーションを使用しているとルータなどの環境ではネットワークのポート開放などをしないとWebアプリケーションの公開ができないというのがちょっと残念なことが多くあります。

以前もSlackのWebhookを使用したbotの作成時にはルータのポート開放をやるのが非常に手間だったという印象です。

先日行った勉強会でngrokというものを教えていただき、この悩みが解決しましたのでメモとしておいておきます。

ngrok.com

Secure tunnels to localhost

簡単にいうとプログラムを起動すると、ngrok.com側に登録し、更にローカルホスト側にサービス経由でトンネルを開けてくれるサービスになります。

インストールの準備

インストールは簡単でバイナリをダウンロードするだけです。RaspberryPiの場合にはLinux ARMをダウンロードすることになります。

上記のリンクにバイナリのダウンロードリンクがあります。

ページにアクセスして

f:id:ueponx:20170708160038p:plain

下にスクロールすると出てきます。

f:id:ueponx:20170708152221p:plain

ダウンロードが終わったら、unzipして展開します。基本的にはこれだけで終了です。Pathの通ったところにコピーするなどすれば便利かと思います。

$ ls
ngrok-stable-linux-arm.zip
$ unzip ngrok-stable-linux-arm.zip
Archive:  ngrok-stable-linux-arm.zip
  inflating: ngrok

起動するかを実験してみます。

$ ./ngrok help
NAME:
   ngrok - tunnel local ports to public URLs and inspect traffic

DESCRIPTION:
    ngrok exposes local networked services behinds NATs and firewalls to the
    public internet over a secure tunnel. Share local websites, build/test
    webhook consumers and self-host personal services.
    Detailed help for each command is available with 'ngrok help <command>'.
    Open http://localhost:4040 for ngrok's web interface to inspect traffic.

EXAMPLES:
    ngrok http 80                    # secure public URL for port 80 web server
    ngrok http -subdomain=baz 8080   # port 8080 available at baz.ngrok.io
    ngrok http foo.dev:80            # tunnel to host:port instead of localhost
    ngrok tcp 22                     # tunnel arbitrary TCP traffic to port 22
    ngrok tls -hostname=foo.com 443  # TLS traffic for foo.com to port 443
    ngrok start foo bar baz          # start tunnels from the configuration file

VERSION:
   2.2.6

AUTHOR:
  inconshreveable - <alan@ngrok.com>

COMMANDS:
   authtoken    save authtoken to configuration file
   credits      prints author and licensing information
   http         start an HTTP tunnel
   start        start tunnels by name from the configuration file
   tcp          start a TCP tunnel
   tls          start a TLS tunnel
   update       update ngrok to the latest version
   version      print the version string
   help         Shows a list of commands or help for one command

実験してみる

基本的には

ngrok 【プロトコル】 【portナンバー】

と実行すれば大丈夫です。 例えば、httpをポート80で公開するのであれば

$ ngrok http 80

となります。実行してみます。

今回は次の様に実行してみます。

$ ngrok http 8080

f:id:ueponx:20170708153553j:plain

実行するとこのような画面になります。赤く四角のある部分にはランダムな文字列がngrok側から発行されます。このURLにアクセスを行うと公開ができるようになります。(もちろん、8080ポートに対応したプログラムがないと失敗しますので注意です)

では、アクセスの実験を行います。 サーバとしてはpythonのSimpleHTTPServerモジュールを使用します。

ngrokを起動したコンソールとは別のものを開いて以下の様に起動します。(-mはモジュール起動の際に必要になります)

$ python -m SimpleHTTPServer 8080

これで準備OKです。あとはクライアント側からアクセスを行います。まずはローカル環境からのアクセスを行ってみます。更にクライアント用のコンソールを開きcurlコマンドを使用してアクセスしてみます。実行すると以下の様になると思います。(実行するとサーバ側のカレントディレクトリ一覧が表示されるます。)

$ curl http://localhost:8080
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"><html>
<title>Directory listing for /</title>
<body>
<h2>Directory listing for /</h2>
<hr>
<ul>
<li><a href=".bash_history">.bash_history</a>
<li><a href=".bash_logout">.bash_logout</a>
<li><a href=".bashrc">.bashrc</a>
<li><a href=".cache/">.cache/</a>
<li><a href=".config/">.config/</a>
【中略】
</ul>
<hr>
</body>
</html>

【実行画面】 f:id:ueponx:20170708155249j:plain

ローカルでのテストがうまくいったので、今度はngrok経由でアクセスを行います。ngrok起動時に表示されたURLに対してアクセスを行います。(*********はランダムな文字列です)

$ curl http://********.ngrok.io
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"><html>
<title>Directory listing for /</title>
<body>
<h2>Directory listing for /</h2>
<hr>
<ul>
<li><a href=".bash_history">.bash_history</a>
<li><a href=".bash_logout">.bash_logout</a>
<li><a href=".bashrc">.bashrc</a>
<li><a href=".cache/">.cache/</a>
<li><a href=".config/">.config/</a>
【中略】
</ul>
<hr>
</body>
</html>

【実行画面】 f:id:ueponx:20170708154030j:plain

無事にアクセスしデータが取得できたと思います。

アクセスはngrokプロセス側にも以下の様に表示されます。

f:id:ueponx:20170708155501j:plain

終わりに

ngrokを使用することでRaspberryPiで作成したWebアプリケーションを容易に公開することができました。開発時やハッカソンなどで短時間で公開したい場合にはかなり有効かなと思います。

ngrokはユーザ登録しない場合にはhttp(https)しか使用できませんが、ユーザ登録を行うとSSHやRDPなども使用できるようです。次回はそのあたりも行ってみようと思います。

IchigoJamのファームウエアをバージョンアップさせる

IchigoJamのファームウエアをバージョンアップさせる

久しぶりにIchigoJamを使用しようと思ったのですが、ファームウエアのバージョンがかなり古かったのでバージョンアップをしました。 以前にもファームウエアのバージョンを上げたことはあるのですが、メモなどを取っていなかったのでかなり苦戦しました。 苦戦というよりもハマったという感じでした。(たぶん自分だけかも知れない現象ぽい)

IchigoJamってなに?って人は以下を参照ください。

ichigojam.net

自分は秋月電子さんで購入しました。

IchigoJamのファームウエアのバージョンアップ

PCとの接続

IchigoJamのバージョンアップはメイン基板に載っているLPC1114のシリアルポートとPCを接続する必要があります。今回は家にあったUSBシリアル変換を称することにしました。IchigoJamは3.3Vなのですが、自分の持っていたのは5.0Vと3.3Vの変換をジャンパで切り替えることができるものでした。

シリアルポートとの接続に関しては以下を参考にしました。

d.hatena.ne.jp

nuneno.cocolog-nifty.com

基本は

IchigoJam PC(USBシリアル変換)
GND GND
TX RX
RX TX
ISP GND(基板のGNDから取ったほうが早いです)

このように接続を行います。

【写真】 f:id:ueponx:20170702152306j:plain

ソフトウエアの準備

ファームウエアに関しては公式サイトに公開されているのでそれをダウンロードします。

ichigojam.net

今回はversion 1.2.2をダウンロードすることにしました。ダウンロードするとアーカイブにはNTSCやキーボードなどにより複数の種類のROMがあり、そこからファイルを選択することになりますが、自分はntscとJPキーボードのファームウエアを選択しました。(ファイルはichigojam-ntsc-jpkbd.hexです。)

あとはこのファームウエアを書き込むソフトウエアであるFlash Magicをダウンロードします。

www.flashmagictool.com (画面右側にあるFlashMagic.exeのボタンをクリックすればダウンロードができます)

参考にしたサイトの情報でわかったのですがPC(Windows)でシリアルポートの設定を見る方法があるようでmodeコマンドを叩くとスピードなどがわかるようです。これって常識なんでしょうか?これまではGUIで結構確認していたのですがこちらのほうが圧倒的に楽ですね。COMポートも分かりますし。

f:id:ueponx:20170701140914j:plain

基本は参考にしたサイトと同様なのでファームウエアを書き込むだけです。

自分の場合はmodeコマンドでUSBシリアル変換機の接続がCOM3と判別されたのでこれを設定し、以下の画面の様にします。

f:id:ueponx:20170702135911j:plain

あとは書き込むだけなんですが…。

またしてもトラブル…

ここまで来て毎回トラブルなんですよね…

Flash Magicのメニューにある虫眼鏡のアイコンボタンをクリックするとIchigoJamに接続してメモリ状態を表示することができるのですが Error発生します。エラーメッセージからすると自動でボーレートの設定に失敗したというものでした。

【メモリ内容の表示ダイアログ】 f:id:ueponx:20170702141428j:plain

【エラーダイアログ】 f:id:ueponx:20170702141951j:plain

Auto設定なんてあったっけなあと思いつつ、ネットにこういう情報もあったのでシリアル変換器の不安定さの機器側の問題なのかもと思いつつも設定を見直すことにします。

【参考】 パソコンと接続 - イチゴジャム レシピ

Flash Magicのメニューから【Options】→【Advanced Options】を開くと

f:id:ueponx:20170702142410j:plain

設定のダイアログが開きます。

f:id:ueponx:20170702142642j:plain

そこで【Communications】タブをみると【High Speed Communications】にチェックがついていました。何となくこの部分が怪しい感じです。そこでチェックを外してみます。

f:id:ueponx:20170702143827j:plain

チェックを外して【OK】ボタンをクリックします。再度、【虫眼鏡ボタン】をクリックすると…。

f:id:ueponx:20170702142250j:plain

無事にダンプができました。一応これでシリアル接続も無事に行えました。

書き込みを行う

後はFlash Magicに書き込むROMのファイルを設定し、【Start】を押すと…

f:id:ueponx:20170702144808j:plain

書き込む処理が開始されます。

f:id:ueponx:20170702144841j:plain

ウインドウの左下に【Finished】が表示されると無事に終了になります。 電源をOFFにして、ISPピンとGNDを接続しているケーブルは抜いておきます。

起動すると…

シリアルコンソールとの接続をそのままにして電源をONにすると

f:id:ueponx:20170701140852j:plain

無事にVer1.2.2の開始画面が表示されます。

終わりに

トラブルはありましたが、なんとかバージョンアップができました。あんな設定触ってないと思ったんだけどなあ。

DragonBoard 410c(Debian)で日本語音声合成(Open JTalk)のTTSしてみる

DragonBoard 410c(Debian)で日本語音声合成(Open JTalk)のTTSしてみる

前回のエントリで音声の出力ができるようになったDragonBoard。この機能を元にOpen JTalkを用いた音声合成を行ってみたいと思います。

Open JTalk - HMM-based Text-to-Speech System

以下の過去エントリを参考にしていきます。

OpenJTalk関連 uepon.hatenadiary.com

Bluetoothスピーカー関連 uepon.hatenadiary.com

Open JTalkのインストー

Open JTalkMMDAgentをインストールします。

$ sudo apt-get install open-jtalk open-jtalk-mecab-naist-jdic htsengine libhtsengine-dev hts-voice-nitech-jp-atr503-m001
$ wget http://downloads.sourceforge.net/project/mmdagent/MMDAgent_Example/MMDAgent_Example-1.6/MMDAgent_Example-1.6.zip
$ unzip MMDAgent_Example-1.6.zip
$ sudo cp -R MMDAgent_Example-1.6/Voice/mei /usr/share/hts-voice/

一度行っているので迷うことはありませんでした。

TTSを実行するシェルを編集する

Open JTalkのパラメータを設定し実行するシェルスクリプトを編集します。

$ vim jtalk.sh

【jtalk.sh】

#!/bin/bash

# HTSVOICE=/usr/share/hts-voice/nitech-jp-atr503-m001/nitech_jp_atr503_m001.htsvoice
HTSVOICE=/usr/share/hts-voice/mei/mei_normal.htsvoice

voice=`tempfile`
option="-m $HTSVOICE \
  -s 16000 \
  -p 100 \
  -a 0.03 \
  -u 0.0 \
  -jm 1.0 \
  -jf 1.0 \
  -x /var/lib/mecab/dic/open-jtalk/naist-jdic \
  -ow $voice"

if [ -z "$1" ] ; then
        open_jtalk $option
else
        if [ -f "$1" ] ; then
                open_jtalk $option $1
        else
                echo "$1" | open_jtalk $option
        fi
fi

aplay -q $voice
rm $voice

編集が終わったら実行権限を与えます。

$ chmod 755 jtalk.sh

これで準備完了です。

TTSの実行

ここまで終わったので実際に実行させてみます。 コンソール上から以下の様に話したい文章を引数として与えます。

$ ./jtalk.sh こんにちは、今日は雨が降っているなか、お越しい
ただき、ありがとうございます
$ ./jtalk.sh 最大級のパワフルボディ!ダリラガーン!ダゴズバ
ーン!
$ ./jtalk.sh ドリーミングガール、恋のシミュレーション。乙女
はいつも、ときめきクライシス。

正常に動作できたようです。

【動画】

youtu.be

おわりに

思ったよりすんなりOpen JTalkを導入できました。 これでDragonBoardでも音声でアナウンスするようなものは簡単にできそうですね!

DragonBoard 410c(Debian)でPechatを使用してみる(Bluetooth経由の音声出力)

DragonBoard 410c(Debian)でPechatを使用してみる

DragonBoardの唯一困った点は音声出力のpinがデフォルトではないことかなと思います。 できれば、このあたりもついていると良かったかなと。最近は音声認識や自動音声や音声による操作もあるので、こういう方向もアクセスできるといいなあと思ったり。

ただ、DragonBoardにはBluetoothがついているのでBluetooth用の音声機器は接続できます。以前のエントリでRaspberryPiでBluetoothスピーカーのPechatを使用してみました。 一応無事には接続し使用できたのですが、XからのGUI経由でしか設定できなかったので、微妙な感じでした。そのリベンジも兼ねてDrabgonBoardでも設定をチャレンジしてみます。

uepon.hatenadiary.com

ちなみに結論に急ぎたい方は回答編まですっ飛ばしてください。

DragonBoardでBluetooth-音声デバイス設定を行う

一応、前提とする環境を確認します。OSのディストリビューションを確認します。

$ lsb_release -a
No LSB modules are available.
Distributor ID: Debian
Description:    Debian GNU/Linux 9.0 (stretch)
Release:        9.0
Codename:       stretch

もちろん、Debianですが、自分が使用したOSイメージはdragonboard410c_sdcard_install_debian-233.zipです。最新ではなく一つ古いバージョンかなと思います。(特にこだわりがなければ最新イメージのほうがいいかなと思います。)

Documentation - 96Boards

音声デバイスとしての制御はPulseAudioを使用するので、pulseaudio関係のパッケージのインストール状況も確認します。

$ dpkg -l | grep pulse
ii  libpulse-mainloop-glib0:arm64                 10.0-1                            arm64        PulseAudio client libraries (glib support)
ii  libpulse0:arm64                               10.0-1                            arm64        PulseAudio client libraries
ii  libpulsedsp:arm64                             10.0-1                            arm64        PulseAudio OSS pre-load library
ii  pulseaudio                                    10.0-1                            arm64        PulseAudio sound server
ii  pulseaudio-module-bluetooth                   10.0-1                            arm64        Bluetooth module for PulseAudio sound server
ii  pulseaudio-utils                              10.0-1                            arm64        Command line tools for the PulseAudio sound server
ii  xmms2-plugin-pulse                            0.8+dfsg-18 

デフォルトでインストールも完了しています。

Bluetoothの接続を確認する

あとはCLIからBluetoothの接続をおこなってみます。Bluetoothの確認用コマンドはbluetoothctlです。

$ sudo bluetoothctl -a
[NEW] Controller 00:00:00:00:XX:XX linaro-alip [default]
Agent registered
[bluetooth]# scan on
Discovery started
[CHG] Controller 00:00:00:00:XX:XX Discovering: yes
[NEW] Device CC:30:80:00:XX:XX Pechat-00F8A1
[NEW] Device AE:12:42:3B:XX:XX 36bde7-bt
[CHG] Device AE:12:42:3B:FF:12 RSSI: -86
[bluetooth]# pair CC:30:80:00:XX:XX
Attempting to pair with CC:30:80:00:XX:XX
[CHG] Device CC:30:80:00:XX:XX Connected: yes
[CHG] Device CC:30:80:00:XX:XX UUIDs: 00001101-0000-1000-8000-00805f9b34fb
[CHG] Device CC:30:80:00:XX:XX UUIDs: 0000110b-0000-1000-8000-00805f9b34fb
[CHG] Device CC:30:80:00:XX:XX ServicesResolved: yes
[CHG] Device CC:30:80:00:XX:XX Paired: yes
Pairing successful
[CHG] Device CC:30:80:00:XX:XX ServicesResolved: no
[CHG] Device CC:30:80:00:XX:XX Connected: no
[bluetooth]# connect CC:30:80:00:XX:XX
Attempting to connect to CC:30:80:00:XX:XX
[CHG] Device CC:30:80:00:XX:XX Connected: yes
Connection successful
[CHG] Device CC:30:80:00:XX:XX ServicesResolved: yes
[CHG] Device AE:12:42:3B:XX:XX RSSI: -87
[CHG] Device AE:12:42:3B:XX:XX RSSI: -74
[Pechat-00F8A1]# quit
Agent unregistered
[DEL] Controller 00:00:00:00:XX:XX linaro-alip [default]

無事にペアリングもコネクトもできました。あとはServiceの設定などを行うのみです。以下はほとんどRaspberryPiのときのエントリーそのままになります。RaspberryPiでは失敗していたのでかなり不安ではありますが…

/etc/systemd/system/pulseaudio.serviceファイルを作成

$ sudo vim /etc/systemd/system/pulseaudio.service

【/etc/systemd/system/pulseaudio.service】

[Unit]
Description=Pulse Audio

[Service]
Type=simple
ExecStart=/usr/bin/pulseaudio --system --disallow-exit --disable-shm

[Install]
WantedBy=multi-user.target

/etc/dbus-1/system.d/pulseaudio-bluetooth.confファイルを作成

$ sudo vim /etc/dbus-1/system.d/pulseaudio-bluetooth.conf

【/etc/dbus-1/system.d/pulseaudio-bluetooth.conf】

<busconfig>

  <policy user="pulse">
    <allow send_destination="org.bluez"/> 
  </policy>

</busconfig>

以上で設定ファイルの編集は終了となります。

pulseaudioサービスの設定

最後に起動時に自動的に設定をされるようにサービスの開始と有効化を行っておきます。

$ sudo systemctl start pulseaudio.service
$ sudo systemctl enable pulseaudio.service

これで完了です。 あとは先程と同じくBluetoothの状態の確認をしますが、基本無事にコネクトができているので一安心です。

後は音声が正常に再生されればいいのですが…

$ aplay /usr/share/sounds/alsa/Front_Center.wav
Playing WAVE '/usr/share/sounds/alsa/Front_Center.wav' : Signed 16 bit Little Endian, Rate 48000 Hz, Mono

あれ? エラーは出ないが、音がならない…RaspberryPiとは違う状況…

最初はmixserの設定で音量が下がっているのかなと思ったのですが、そんなこともなくさすがに微妙な感じになってしまいました。

仕方ないのでサービスはストップし、起動時は無効にすることにします。

$ sudo systemctl stop pulseaudio.service
$ sudo systemctl disable pulseaudio.service

回答編

結局、コマンドラインからの設定は成功しませんでした。(RaspberryPiでもうまく行っていなかったので、こちらがそのままの方法でうまくいくとは思いませんでしたが。)

最後にXを使用してBluetoothの設定を行ってみます。(事前にPechatの電源は入れておいてください。)

まずは、Xの下部のメニューバーをクリックし【設定】→【KDEシステム設定】を選択します。すると設定のダイアログウインドウが開きます。

f:id:ueponx:20170624101410j:plain

その中から【ネットワーク】→【Bluetooth】を選択します。

f:id:ueponx:20170624101422j:plain

するとBluetoothで接続されたデバイスの一覧が表示されます。 画面上にPechatが表示されているのがわかるかと思います。

f:id:ueponx:20170624101443j:plain

一覧からPechatを選択してみます。

f:id:ueponx:20170624101452j:plain

するとダイアログの右側にヘッドフォンの画像が表示されます。 その画面中のTrustedの部分にマウスでチェックをしてみます。

f:id:ueponx:20170624101502j:plain

その後、ダイアログ右側にある【Connect】をクリックします。 接続がうまくいくとボダンの文字はDisconnectという文字列に変更します。

f:id:ueponx:20170624101511j:plain

一応この時点でもaplayコマンドで音がなりませんでした。さすがに八方塞がりかと思ってしまうのですが、今度は下部のメニューバーをクリックし、【サウンドとビデオ】→【PluseAudio Volume Control】を選択します。

f:id:ueponx:20170624101520j:plain

選択後に開いだダイアログの【Output Device】を確認すると本体側(B410c)の設定とPechat側の設定が存在することがわかります。問題はなさそうでもあったので、この時点でaplayコマンドで再生させるのですが、問題はなさそうでしたが音声はなりませんでした。そのため、今度は本体側の外してみます。【Configure】タブを選択しD410cの【Profile】をOffに変更します。

f:id:ueponx:20170624101529j:plain

特に問題はなさそうですが、以前音声デバイスの優先順位の設定をしていたときに、優先度が異なると音声がならないということがあったことをふと思い出しました。

f:id:ueponx:20170624101537j:plain f:id:ueponx:20170624101544j:plain

ペアリングさせなおすのですが、これで問題はなく設定は完了になりそうです。

音声の再生

$ aplay /usr/share/sounds/alsa/Front_Center.wav
Playing WAVE '/usr/share/sounds/alsa/Front_Center.wav' : Signed 16 bit Little Endian, Rate 48000 Hz, Mono

音声が再生されました。やっと正常に動作します。 再起動時などにはペアリングなどは解除されるので起動時に再度Pechatの電源ボタンをOnにしてペアリングさせてあげれば問題はないかなと思います。

おわりに

やっぱり、コマンドラインからの設定はうまく行かず…。Xからの設定でうまくいっているので事実上問題はないのですが…残念です。現在の自分の能力ではそこまでということか。トホホ。

DragonBoard 410c(Debian)でGPIOプログラミング(Python編)

DragonBoard 410c(Debian)でGPIOプログラミング(Python編)

前回まではC言語でGPIOを触っていましたが、流石に最近はpythonとかnode.jsで触りたいですね。

uepon.hatenadiary.com

uepon.hatenadiary.com

折角、pythonのラッパーもインストールしてあるのでpython編となります。 早速サンプルを眺めてみます。

#!/usr/bin/python
import time

from gpio_96boards import GPIO

GPIO_A = GPIO.gpio_id('GPIO_A')
pins = (
    (GPIO_A, 'out'),
)

def blink(gpio):
    for i in range(5):
        gpio.digital_write(GPIO_A, GPIO.HIGH)
        time.sleep(i)
        gpio.digital_write(GPIO_A, GPIO.LOW)
        time.sleep(1)

if __name__ == '__main__':
    import argparse

    parser = argparse.ArgumentParser(
        description='Blink LED on GPIO A (pin 23)')
    args = parser.parse_args()

    with GPIO(pins) as gpio:
        blink(gpio)

基本はLチカなので実行すればGPIO_A(GPIO 23pin)に接続したLEDが点灯します。

$ sudo python blink.py

サンプルのままなので実行に関しては特に問題はありません。部分を見ていきます。

モジュールの読み込み

from gpio_96boards import GPIO

gpio_96boarsがモジュールになるようです。

GPIOのピンの指定

GPIO_Aを指定します。変数名もGPIO_Aなので少しわかりにくいかも。

GPIO_A = GPIO.gpio_id('GPIO_A')

指定したPINとIN/OUTのディレクションをタプルとして保存します。

pins = (
    (GPIO_A, 'out'),
)

出力

設定したタプルに対して値を書き込む処理となります。

gpio.digital_write(GPIO_A, GPIO.HIGH)

ここでは引数のgpioが先程のタプルであるpinsに相当します。 digital_write()で値を書き込むことになります。最初はなんで引数にGPIO_Aを渡さなければいけないのか謎があったのですが、タプルの中に複数のGPIOの設定を入れればいいのかと思って納得しました。

引数にはタプルので指定したGPIOと値をいれると出力ができます。C言語とは少し違う印象ですが、割りと冗長性も少なくできるのでわかりやすいです。

入力

今度は入力になりますが、出力と同様に

  1. GPIOのピンの指定
  2. GPIOからの入力

というステップになります。

出力と入力の対比をしたほうが理解がし易いかなと思います。

GPIO_A = GPIO.gpio_id('GPIO_A')
GPIO_C = GPIO.gpio_id('GPIO_C')
pins = (
    (GPIO_A, 'out'),
    (GPIO_C, 'in'),
)

ピンの設定はまんま同じですが、ディレクションに関してはタプルの中に書いていくことになります。複数のピンがあると冗長性が少なくなるのがこれでわかるかと思います。

入力に関しては

t = gpio.digital_read(GPIO_C)

こんな感じになると思います。取得した値はGPIO.HIGHとGPIO.LOWとなります。

ということでGPIO_Cのタクトスイッチを押したら、GPIO_Aに接続したLEDが点灯するサンプルをかいてみました。C言語編のソースをpythonに移植しています。

#!/usr/bin/python
import time
from gpio_96boards import GPIO

usleep = lambda x: time.sleep(x/1000000.0)


GPIO_A = GPIO.gpio_id('GPIO_A')
GPIO_C = GPIO.gpio_id('GPIO_C')
pins = (
    (GPIO_A, 'out'),
    (GPIO_C, 'in'),
)

def blink(gpio):
    led_state = GPIO.HIGH
    last_t = GPIO.LOW
    while True:
        t = gpio.digital_read(GPIO_C)
        if (t and (not last_t)) :
            gpio.digital_write(GPIO_A, led_state)
            usleep(100000)
            if led_state == GPIO.HIGH:
                led_state = GPIO.LOW
            else:
                led_state = GPIO.HIGH
        last_t = t
        usleep(1)

if __name__ == '__main__':
    import argparse

    parser = argparse.ArgumentParser(
        description='Blink LED on GPIO A (pin 23)')
    args = parser.parse_args()

    with GPIO(pins) as gpio:
        blink(gpio)

C言語編同様にタクトスイッチでON/OFFができるようになりました。起動時の引数を付けたときのusageメッセージはめんどくさいかったので直してませんw。

終わりに

これでC言語でもpythonでもGPIOの入力・出力ができるようになりました。C言語でも同じことはできるのですが、やっぱりpythonの方が作りやすいかなと思いました。

もうそろそろ作品ぽいものを作らないと行けないのですが、アイデアがちょっとまだまとまっていないのでどうすれば…。

/* -----codeの行番号----- */