ArduinoをFirmate経由で使う


今まで、MCP3002MCP3204PCF8591のADコンバータチップの使用方法 を紹介してきました。
今回は少し反則わざですが、ArduinoをFirmate経由でADコンバータとして使う方法を紹介します。

Arduinoは6チャネルの10ビットADコンバータを搭載しています。
そこで、Firmateプロトコルを使って、RaspberryからArduinoを操作します。
FirmateプロトコルはPC - マイコン間でやり取りするためのプロトコルで
PC側からArduinoのようなマイコンに対して、値の取得・書き込みその他の操作を行う為に使用されます。

まずはArduino側の準備です。
ArduinoでFirmataプロトコルを使用してRaspberryとやり取りする場合、
ArduinoIDEから「ファイル -> スケッチの例 -> Firmata -> Standard Firmata」を選択し、
Arduinoに書き込むだけです。



今回使用した回路は以下の回路です。
Arduinoの5V出力を5つの抵抗で5分割し、それぞれをA0からA5のピンに入力しています。
従ってA0は5V、A1は4V、A2は3V、A3は2V、A4は1V、A5は0Vとなります。
今回使用したArduinoはUNOですが、USBを持っているNANOやMEGAでも使えると思います。



次にRaspberryで使うFirmateクライアントライブラリのインストールを行います。
今回、PythonライブラリのpyFirmateを 使いました。
$ git clone https://github.com/tino/pyFirmata
$ cd pyFirmata
$ sudo python setup.py install


Raspberry側のコードは以下のようになります。
import pyfirmata
import time

PORT = '/dev/ttyUSB0'

# Definition of the analog pin
PINS = (0, 1, 2, 3, 4, 5)

# Creates a new board
board = pyfirmata.Arduino(PORT)
print "Setting up the connection to the board ..."
it = pyfirmata.util.Iterator(board)
it.start()

# Start reporting for defined pins
for pin in PINS:
    board.analog[pin].enable_reporting()

# Loop for reading the input. Duration approx. 10 s
for i in range(1, 11):
    print "\nValues after %i second(s)" % i
    for pin in PINS:
        str=board.analog[pin].read()
        if str is None:
            val=0
        else:
            val=float(str)*5.0
        print "A%i:%.4f[V]" % (pin, val),
#    time.sleep(1)
    board.pass_time(1)
   

board.exit()

実行結果は以下の様になりました。
1回目だけはデータが取れていませんが、2回目以降はそこそこの精度でデータが取れています。



一度に沢山のチャンネルのアナログデータを取りたいときには、この方法は楽チンです。
なお、pyFirmateではディジタル出力も行うことができます。
以下のコードを実行するとArduinoのオンボードのLEDがLチカします。
import pyfirmata
import time

PORT = '/dev/ttyUSB0'

# Creates a new board
board = pyfirmata.Arduino(PORT)
print "Setting up the connection to the board ..."
for i in range(10):
  board.digital[13].write(1)
  time.sleep(1)
  board.digital[13].write(0)
  time.sleep(1)

board.exit()

pyFirmate以外にPyMataと言う非常に高機能なFirmateクライアントライブラリがあります。
機能が豊富なので、こちらで詳しく紹介しています。

また、C言語のクライアントライブラリ (FirmataC)もあります。
試してみましたが、ディジタル出力はできましたが、アナログ入力はできませんでした。