14: Intel Edison Board for Arduinoにおけるマルチプレクサとその低水準操作方法

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

よく訓練されたアップル信者、都元です。昨日のエントリーはこちらです。やっとハードウェアを触り始め、OSの中に入ったのでこのまま楽しい実習が続くかと思いきや、本日は座学です。

マルチプレクサ - multiplexer - mux

Intel Edison Arduino Board Hardware Guideを読んでいると「pin muxing」や「muxed function」という語句が出てきます。辞書でmuxを調べても「もしかして: max」と言われて絶望しました。

素直にGoogle先生に聞くと、どうやらマルチプレクサというメカニズムのことを指しているようです。ドキュメントには「multiplexing control」という記述もあり、確かに同じ話をしているようです。

要するに、ボード上に配置された各ピンについて、それぞれ1ピン=1機能ではなく、1つのピンに複数の機能を持たせてしまおう、という仕組みです。で、各ピンに対する設定によって、どの機能を使うかを制御します。

確かに、そもそもArduinoボードには20個のGPIO端子(デジタル14個、アナログ6個)があります。デジタルの14個については、入力端子にもなり、出力端子にもなります。設定によって機能を切り替えるわけです。

Arduinoボードピン番号

Arduinoボードにある20個のGPIO端子は、それぞれIO0IO20という記号が割り振られています。下図における、ピンク背景 *1の数字が、これに相当します。

arduino-pinout-diagram

各ピンについては、GPIO, PWM, UART, I2C, SPI, ADCあたりが多重化されています。内容はピン毎に違いますが。えーー…。わたくし、シリアル通信周りの知識が非常に弱いことを自覚したので引き続き頑張ります。

設定実習

下記において、IOxxというのは前述の通り「Arduinoボードにおけるピン番号」です。一方GPxxは、Edison本体から出るシグナル名です。ということを意識して読み進めてください。

ピン・マルチプレクサの設定

では具体的に。各端子を設定する様子を見て行きましょう。詳細に追いかけると実はかなり複雑なので、ここではさらっと。ガチでやる場合は、Intel Edison Arduino Board Hardware GuideのTable2〜7辺りを参照します。ここを参照すると、

  • IO14(要するにアナログ入力のA0)はGP44が繋がっている (Table2)
  • これをADC *2に設定するための、MUXのシグナルがGP200 (Table3, 4)
  • 入出力の切り替えシグナルはGP232 (Table3, 4)
  • プルアップ切り替えシグナルはGP208 (Table3, 4, 7)
  • TRI_STATE_ALL(後述)はGP214 (Table6)

といったことが把握できます。こういった情報を元に、Edison上のLinuxから、キャラクタデバイスファイルを介して設定を行い、そして値の入出力を行います。具体的にはこんな設定を流すと、IO14(要するにアナログ入力のA0)がアナログ入力端子として機能します。ArduinoにのAVR-CおけるpinMode等を呼び出した感じですね。

echo 200 > /sys/class/gpio/export
echo 232 > /sys/class/gpio/export
echo 208 > /sys/class/gpio/export
echo 214 > /sys/class/gpio/export
echo high > /sys/class/gpio/gpio214/direction
echo high > /sys/class/gpio/gpio200/direction
echo low > /sys/class/gpio/gpio232/direction
echo in > /sys/class/gpio/gpio208/direction
echo low > /sys/class/gpio/gpio214/direction

ちなみにGP214TRI_STATE_ALLというのは、全てのピン接続をEdisonから浮かす役割を持っています。なので、設定開始時にhighを送って浮かせ、設定完了後にlowを送って再接続をしています。マルチプレクサの設定をする場合は、開始時終了時にこの操作をすることが推奨されています。

ピンからの入力値の取り出し

そして、値の取り出しは、こう *3。下記は、IO14に可変抵抗(ボリューム)を繋いで、時計回りに目一杯回した状態で実行しました。

# cat /sys/bus/iio/devices/iio:device1/in_voltage0_raw
3937

そして逆(反時計回り)はこう。

# cat /sys/bus/iio/devices/iio:device1/in_voltage0_raw
121

センサー(というには大げさですが)が返したアナログな電圧を、情報として取り出すことに成功しました!

マルチプレクサ設定の後片付け

ちなみに、/sys/class/gpio/exportに対してGPIO番号(例えばGP000の000部分)を送ると、/sys/class/gpio/gpio000が使えるようになります。既に使える状態なのにexportしようとするとエラーが発生しますので、要らなくなったポートは下記のように片付けておくといいかもしれません。

echo 200 > /sys/class/gpio/unexport
echo 232 > /sys/class/gpio/unexport
echo 208 > /sys/class/gpio/unexport
echo 214 > /sys/class/gpio/unexport

まとめ

…なーんてことは、実際にセンサやアクチュエータと協調動作するソフトウェアでやってらんないですよね。こういったデバイスファイルに対する操作を抽象化し、高水準なAPIを提供するのがmraa等のライブラリです。

今後はライブラリを使うにせよ、どのような仕組みでアプリケーションが各ピンにアクセスしているのかを知っておくと良いでしょう。

参考

明日のエントリーはこちらです。

脚注

  1. 右下の凡例における「IDE」の色。
  2. Analog-to-digital converter
  3. このファイルシステムpathの作り方は、正直ドキュメントから読み取れませんでした。どうしたものか。