2013年04月28日

Raspberry PiでI/O拡張&Arduinoシールドを使おう〜firmata+Ruby編

Raspberry Piでいろいろと制御を楽しむ時に、よりたくさんのI/Oを叩きたいとか、サーボを手軽に動かしたくなる場合があるかもしれません。また、Arduinoシールドを既に持っている場合、これを活用したいという場合もあるでしょう。
Raspberry PiはそれほどはI/Oが充実していませんしね〜。
以下は回路図のピンヘッダのところ。
RPi_PIN_sch.png
回路図にありますように、SPI、I2Cが出てるので、ポートエキスパンダを接続するという手は使えます。
ポートエキスパンダは、例えばこんなのとか。
http://akizukidenshi.com/catalog/g/gI-03708/

とはいえPWMやりたい、とかAD値を取りたいとか、なんてことを手軽な工作で実現するには手間がかかりそうです。


本記事では、上記を解決するアプローチの1つとして、firmataのスケッチを書き込んだArduinoマイコンボードをRaspberry PiのUSBポートに接続し、Raspberry Pi側からArduinoを手足のように使って制御を行なってみる内容になっています。
そんなわけで、ArduinoシールドもRaspberry Piから制御できるようになります。いろいろお持ちの方は資産活用できるかもしれませんね

firmataは、元々PC用のJavaベースの開発環境Processingで、PCに接続したArduinoマイコンボードを制御してフィジカルコンピューティングするものです(と理解してます)。

そこで、firmataのプロトコル http://firmata.org/wiki/Protocol をRaspberryPi側に喋らせる事で、Raspberry Piで手軽にArduinoマイコンボードを制御できるようにする準備をしていきたいと思います。
今回、Raspberry Pi側で使用する言語はRubyにしました。これでRaspberry Pi上のスクリプト言語で、お手軽にスケッチ相当のコードを書いて、フィジカルコンピューティング出来ますね!(たぶん)

IMG_20130428_030933resized.jpg
さて、今回はArduinoマイコンボードとして最もスタンダードなものの1つである、Arduino Unoを使用しました。
最近スイッチサイエンスさんではこのボード、永久保証されてるようで話題になりました。
【永久保証付き】Arduino Uno
スイッチサイエンス
売り上げランキング: 3,309

Arduinoマイコンボード側の準備

では、これに、Standard Firmataのスケッチを焼きこんでおきましょう。サンプルに用意されています。
ss_firmata.png

Raspberry Pi側の準備
Raspberry Pi側のディストリビューションはRaspbian Wheezyを使用します。その他のLinuxディストリビューションでも多分実施可能かとは思います。Arduno Unoを認識させる為には、USB CDC ACMデバイスを認識できるようにする必要がありますが、Raspbian Wheezyでは標準で認識するようになってます。

●Rubyのセットアップ
今回はRubyとRubyでシリアルポートを制御するruby-serialportを使用します。また、ruby-serialportをセットアップするのにRubygemを使用しますので、以下のようにセットアップするとOKです。

$ sudo apt-get install ruby
$ sudo apt-get install ruby-dev
$ sudo apt-get install rubygems
$ sudo gem install ruby-serialport

ruby-devは、gemでモジュールをインストールする際に必要になる関係でセットアップしています。

では、ライブラリを準備します。

patcoll氏のruby-firmataをベースに、現在のfirmataで使用できるように改造し、改変や機能追加したものを私のgithubで公開しています。

当初そのまま使えるかなと思ってたのですが、ruby-firmataの開発が2年ほど止まっているようで、その間のfirmataの拡張などもあったためでしょうか、そのままでは動作させられませんでした。
改変版は以下にあります。
https://github.com/yishii/ruby-firmata
これを取得します。
下記のようにgitで取得出来ますし、gitを使わない場合、「zip_icon_github.png」アイコンをクリックするとZip形式でダウンロード出来ます。
git clone https://github.com/yishii/ruby-firmata
それではサンプルコードを用意します。以下のコードは、上述のリポジトリ内にあります、test.rbとなってます。
runメソッドにクラスを渡すとsetupとloopを呼び出すArduino IDEライクなスタイルです。直接Arduinoクラスメソッド呼び出しでの制御もできますので、お好みで。

digital_readやanalog_readメソッドの値は、firmataではレポートが定期的(または変化があった時)にArduino側から送られてきますので、それをパースした結果を返します。本ライブラリでいえば、Arduino::parseを呼び出した内部でArduinoからのレポートを解釈し、内部で記録します。

コードを見ていただくとおわかりになるかと思いますが、内容としては、デジタルピン2番をリードしてデジタルピン13番のHigh/Lowを制御するのと、アナログピン0番をリードしてデジタルピン9番に接続したサーボモーターを制御させています。

require './lib/arduino'

class Test
  def initialize(arduino)
    @arduino = arduino
  end

  def setup
    @arduino.set_report_interval(100) # アナログ値のレポート間隔 = 100[ms] 短かくし過ぎた場合通信量が大きくなるので注意
    @arduino.pin_mode(Arduino::DIGITAL2 , Arduino::INPUT)
    @arduino.pin_mode(Arduino::DIGITAL3 , Arduino::INPUT)
    @arduino.pin_mode(Arduino::DIGITAL13, Arduino::OUTPUT)
    @arduino.pin_mode(Arduino::DIGITAL9 , Arduino::SERVO)
    @arduino.pin_mode(Arduino::ANALOG0  , Arduino::ANALOG)
    @arduino.report # デジタル・アナログのレポート開始
  end

  def loop
    @arduino.parse # レポートを受信して解釈する

    # デジタルピン2番のLOW/HIGHでデジタルピン13番を制御
    if (@arduino.digital_read(Arduino::DIGITAL2) == 0)
      @arduino.digital_write(Arduino::DIGITAL13,0)
    else
      @arduino.digital_write(Arduino::DIGITAL13,1)
    end

    # アナログピン0番の入力値を用いてデジタルピン9番のサーボを回転させる
    val = @arduino.analog_read(Arduino::ANALOG0)
    @arduino.servo_write(Arduino::DIGITAL9,val >> 2)
   end

end

arduino = Arduino.new("/dev/ttyACM0")
arduino.run(Test)



/dev/ttyACM0は、Arduino Unoのシリアルポートのデバイススペシャルファイルです。これを介してRaspberry PiからArduino Unoにアクセスします。

テストに使用したのは、ジョイスティックシールド+サーボモーター+LEDです。
IMG_20130428_030941resized.jpg
IMG_20130428_030852resized.jpg
使用してるところの動画撮りましたのでどーぞ!


firmataを使用すれば、手軽にRaspberry PiでI/O制御の拡張と、既存Arduinoシールド資産が活用できるので、よかったら是非どうぞー!

ちなみに、今回使用したライブラリはArduino::parseメソッドを呼び出して1バイトずつデータを解釈させるのですが、できれば受信は別スレッドで行わせたほうが扱いやすいように思います。その内また更新して本ブログに掲載させていただこうかなーと思います。
Raspberry Piユーザーガイド
Eben Upton Gareth Halfacree
インプレスジャパン
売り上げランキング: 1,952
Raspberry Pi Type B 512MB
Raspberry Pi Type B 512MB
posted with amazlet at 13.04.28
RS Components Ltd
売り上げランキング: 1,915
posted by いしいっち at 04:16| Comment(0) | TrackBack(0) | Raspberry Pi | このブログの読者になる | 更新情報をチェックする
この記事へのコメント
コメントを書く
お名前:

メールアドレス:

ホームページアドレス:

コメント:

※ブログオーナーが承認したコメントのみ表示されます。

この記事へのトラックバック