1. GPIOツール関連の状況
前回は、HummingBoardのGPIOポートの出力が制御できることを検証しました。
Raspberry PiでGPIOを制御するには、GPIOライブラリを使います。このライブラリを使うことでJavaScriptやPythonなどからでもGPIOの制御ができるようになります。
Raspberry Piで一番使われているツールとしてWirinigPiというコマンドレベルのライブラリがあります。また、RPi.GPIO上のraspberry-gpio-python などプログラミングを対象としたツールなどもあります。ここではRasberryPi の解説が目的ではないのでそちらの詳しくは専門のサイトをご覧いただくとして、2015年1月時点、HummingBoard ではRaspberryPi のようにツールが揃っていません。
WiringPiの公式サイトは
にあります。よくできたツールなので、多くの上位のアプリケーションから利用されるのも納得できます。しかしながら上のアプリケーションからは、RPIでしか使えないということが問題となります。
pilightという上位アプリケーションのプロジェクトではハードウェア依存性をなくすためにwiringPiをポーティングする努力をしていて、WiringX というものが立ち上がっています。2015年1月時点ではまだGoogleで検索しても出てこないプロジェクトですが、GithubのURLは
https://github.com/pilight/wiringX
にあります。また、プロジェクトの公式サイトは
となります。
アマチュア向けのGPIOで使えるセンサーなどの「電子工作」向けのパーツは、Arduino向けが一番多く見られます。近頃では、それらのハードウェアに対応したRaspberryPi用のドライバやツール類が作られてネット上でも数多く紹介されています。そうしたハードウェア毎のドライバとは別途、RaspberryPiのGPIOやI2Ci向けにはデファクトスタンダード的なツールもできてきています。
- C の wiringPi
- ruby の pi_piper
- python の raspberry-gpio-python
などがそうです。
Arduinoとか、RaspberryPi 対応のローレイヤーのドライバやツールの場合、残念なことにHummingBoardには対応されていません。
一方で、pilight は、ハイレイヤーのアプリケーションAPIを提供しています。カテゴリーでみると以下の様なものがサポートされています。名前を見るだけでも、上位アプリケーションのレイヤーをターゲットにしていることがわかります。
- Program API(XBMC, Lirc)
- Weather
- Sensor
- Dimmers
- Contact Sensor
- Switches
- Misc
pilightのURLは
です。活動も活発で、日々の更新も頻繁です。このプロジェクトでは、下位レイヤーのAPIの機種依存性をなくす努力をしていて、その中にwiringXを位置づけていて、wiringXも管理しようとしているようです。wiringXのもとはwiringPiからポーティングしてきているわけですが、ARM向けのGPIOとI2Cのマルチプラットフォーム対応が目的としています。汎用性の分、wiringPi のAPI すべてをカバーはできていません。基本機能に徹しています。
SolidRunコミュニティではHummingBoard向けのnode.jsも議論されている。wiringXはそのベースにも使われようとしています。なお、pilight については別途特集して取り上げる予定です。
2. WiringXのインストール
前置きが長くなりました。wiringX をインストールして試してみましょう。
HumminBoardの前提として、前回と同様のDebianを使用します。
(*) 前回紹介した Cubox-i_Debian_2.2_wheezy_3.14.14
Debianをインストールしている場合、すでにSSHは使えるようになっているはずです。今後の作業はPCからSSH経由のターミナルで作業することがおすすめです。(CuBox-iではシリアルコンソールがマイクロUSBで接続できましたが、HBではサポートされていません)
別途インストールする必要がある場合にはrootで
# aptitude install ssh
とします。OpenSSH のデーモンやらクライアントやら一通りインストールできます。
# ps aux | grep sshd
でsshdが起動していることが確認できます。起動できていない場合は起動します。
# /etc/init.d/ssh restart
PC側ではPuttyなどのターミナルソフトを用います。(WindowsやLinuxではおなじみですが、Macで使う場合には環境の設定がやや面倒です。それでもMacのみですべての環境を整えるという方ならセットアップしておく価値はあるでしょう。)
# git clone
https://github.com/pilight/wiringX.git |
# sudo ./gen.package.sh # sudo dpkg -i libwiringx*.deb
# sudo apt-get install cmake |
3. 動作確認
準備がすんだところで、動作の確認をしていきます。wiringXのインストールされたディレクトリを見ると、examples というフォルダがはいっています。それを試していきます。
# cd ~ # cd examples |
blink.c interrupt.c read.c(2015年1月上旬時点)がおさめられています。
このフォルダにはMakefileがあるのでシンプルに make とするだけで、このディレクトリ内のソースはすべてコンパイルされます。再度ディレクトリ内をみるとそれぞれの実行ファイルができています。(そういうことなので、ちょっとした実験用のコードを書くならこのディレクトリ内に *.c のファイルを作れば一緒にmake されるので利用するといいでしょう)
GPIOの確認を、前回と同じ工作キットを使って確認していきます。今回も簡単に結果が確認できるLEDで試してみましょう。
工作キットのコネクタ部分にはRPI用の信号名が書かれています。GPIOの番号の振り方では間違い易いので、前回紹介したRPI名(工作キッ上の表記)とHB名の対応表に、wiringXの番号を追加したものを下に準備しました。
例えばblink.c では pinMode(0, OUTPUT); とあるのはwiringXの#0 という意味なのでこれは、ブレッドボードではP0, HB名ではGPIO 73ということになります。
ブレッドボードの信号名P0にLEDを挿して、コンソールから
# ./blink |
とするとLEDがブリンクします。どうでしょうか。
次のinterrupt.c をみると
pinMode(0, OUTPUT);
wiringXISR(1, INT_EDGE_BOTH);
というのが見えます。wiringX#0が出力になっていて、HIGH/LOWを書かれる毎にLEDのオンオフをします。もう一方のwiringXISRでは、wiringX#1、即ちP1の入力ででH->LまたはL->Hの両方の変化のエッジで割り込みをかける設定としています。
回路としては、P1にスイッチをとりつけ、一定時間内にスイッチの変化があるとinterrupt と表示され、変化がないとtimeout となります。LEDは無関係にブリンクします。
3つ目のread.c では、P1の状態の入力値を読むようになっています。スイッチを動かして値の変化を確かめてください。
動作しましたでしょうか。
GPIO Signal(wiringX pin#) 対応表
GPIO | Signal | pin# | HB Signal |
WiringX pin |
GPIO | Signal | pin# | HB Signal |
WiringX pin |
|
7 | CE1 | 26 | ECSPI2_SS1 | 11 | 17 | P0 | 11 | GPIO 73 | 0 | |
8 | CE0 | 24 | ECSPI2_SS0 | 10 | 18 | P1 | 12 | GPIO 72 | 1 | |
11 | SCLK | 23 | SPI_SCLK | 14 | 27(21) | P2 | 13 | GPIO 71 | 2 | |
9 | MISO | 21 | SPI_MISO | 13 | 22 | P3 | 15 | GPIO 10 | 3 | |
10 | MOSI | 19 | SPI_MOSI | 12 | 23 | P4 | 16 | GPIO 194* | 4 | |
15 | RXD | 10 | UART RX | 16 | 24 | P5 | 18 | GPIO 195* | 5 | |
14 | TXD | 8 | UART TX | 15 | 25 | P6 | 22 | GPIO 67 | 6 | |
3(1) | SCL | 5 | I2C_SCL | 9 | 4 | P7 | 7 | GPIO 1 | 7 | |
2(0) | SDA | 3 | I2C_SDA | 8 | GND |
4. wiringXではサポートされていないこと
wiringXではwiringPiをポーティングしてきているわけですが、基本機能に限っています。
wiringXのAPI
void delayMicroseconds(unsigned int howLong); void pinMode(int pin, int mode); void digitalWrite(int pin, int value); int digitalRead(int pin); int waitForInterrupt(int pin, int ms); int wiringXGC(void); int wiringXISR(int pin, int mode); int wiringXSetup(void); int wiringXI2CRead(int fd); int wiringXI2CReadReg8(int fd, int reg); int wiringXI2CReadReg16(int fd, int reg); int wiringXI2CWrite(int fd, int data); int wiringXI2CWriteReg8(int fd, int reg, int data); int wiringXI2CWriteReg16(int fd, int reg, int data); int wiringXI2CSetup(int devId); char *wiringXPlatform(void); int wiringXValidGPIO(int gpio); |
名前をみれば大体想像がつくような機能のみです。
SolidRunは今後wiringHBをリードしていくようですが、wiringPiとフルコンパチになるかどうかは不明です。現状wiringX でサポートされていないのは以下のようなファンクション類です。
- PWM Control (Pulse Width Modulator)
- Concurrent Processing (multi-threading)
H/Lのデューティを変えて微妙なLED表示をするような「小細工」は使えません。
以上で wiringPi の記事などを参考にする際、wiringXでできることかどうかも判断できます。
5. Python でGPIOを制御する
wiringXをインストールしたところで、Pythonスクリプトから利用できるようにしましょう。たとえば、上のinerrupt.c はこのようになります。
pythonで制御するサンプルコード
import os import sys from time import sleep from wiringX.gpio import gpio
def interrupt(x): if x > 0: print "interrupt" else: print "timeout"
gpio.setup();
gpio.pinMode(gpio.PIN0, gpio.OUTPUT); gpio.wiringXISR(gpio.PIN1, gpio.INT_EDGE_BOTH);
try: gpio.waitForInterrupt(interrupt, gpio.PIN1, 1000); while True: gpio.digitalWrite(gpio.PIN0, gpio.HIGH); sleep(1); gpio.digitalWrite(gpio.PIN0, gpio.LOW); sleep(2); except KeyboardInterrupt: pass; |
Python環境をwiringXに対応させるには、wiringXフォルダにあるpythonフォルダに行って準備されたスクリプトで行えます。wiringXの全ファンクションがpythonで使えるようになります。
# cd wiringX/python # python setup.py install |
pythonフォルダにはexamplesというフォルダがあり、wiringXで試したものと同じ動作をするものがおさめられている。このexamplesで動作を確認することができます。
(すぐに直るとおもわれますが、1月20日時点のバージョンではコンパイルエラーがでて環境作成に失敗していました)
一旦動作確認ができたら、以降はpythonで書くと楽になります。期待して待ちましょう。
参考のためにファンクションリストをあげておきます。
Function list:
- gpio.setup() - gpio.pinMode(pin, mode) - gpio.digitalWrite(pin, state) - gpio.digitalRead(pin) - gpio.valid(pin) - gpio.gc() - gpio.platform() - gpio.I2CSetup(address) - gpio.I2CRead(address) - gpio.I2CReadReg8(fd, address) - gpio.I2CReadReg16(fd, address) - gpio.I2CWrite(fd, data) - gpio.I2CWriteReg8(fd, address, data) - gpio.I2CWriteReg16(fd, address, data) |
今回はwiringXのインストールとpythonからそれを利用できる基本環境を整えました。
コメントをお書きください