Computer & RF Technology

FTDI FT232RLのBitBangモードをMacのrubyから使う

RF関連に限らず、ちょっとした機能を持つチップやデバイスは、SPI(Serial Peripheral Interface)やI2Cで制御する必要がありますが、普通はマイコンなどを使います。最近ではArduinoなども開発環境も揃っていますので、気軽に使えてとても便利です。しかし、PC/Macと連携させて動作させたいという場合には、シリアル等で別途Arduinoと通信をしなければならず、ファームウェアも作成する必要があります。本来であれば単にいくつかのピンを制御したいだけなのに、冗長な感も否めません。昔であればプリンタのパラレルポートを使う場合もありましたが、PCからプリンタインターフェースが消えて既に久しいです。今であればUSBを使うべきところでしょう。

image

そこで今回ですが最近広く使われているFT232RLのBitBangモードを使ってみます。FT232RLとはFTDI社のUSBシリアル変換チップで、Arduinoにも使われています。このチップにはBitBangモードという入出力機能が用意されていて、シリアル入出力の代わりに8bit分の汎用I/Oポートとして利用することができます。今回はこちらを使ってみることにします。

BitBangモードによる入出力をするためには、制御するために何らかのコードを書く必要があります。ドライバとしてFTDI社純正のFTD2XXがあり、CベースのAPIが提供されていますので、これでコードを書くことは可能です。しかし、プロトタイピングや書いて試しての繰り返しのためにはもっと気軽に使いたいところです。そこで今回は使い慣れているrubyを使って、FT232RLのBitBangモードをスクリプトで制御してみることにします。

後で書く予定ですが、本当ならGNURadioと合わせて利用するためにpythonでやりたいところです。ですが、まずは使い慣れたrubyでちゃんと動作させてから、後ほど移行を考えることにします。

使用するAPIですが、libusbベースのlibftdiというライブラリがHomebrewでインストールできるようなので、今回はこちらを使ってみることにしました。libusbベースの実装は、Mac/Linuxの場合ドライバのインストールが不要なので面倒が一つ減らせます(FTD2XXの場合はドライバが必要です)。

FT232RLは、秋月のAE-UM232Rを使用します。最近は中華製のモジュールもありますし入手は容易です。ピン接続を示します。BitBangモードでのIOポートはD0-D7です。

image

MacからBitBangモードを使用するためには、おまじないが必要です。FT232RLをUSBに接続すると、通常はOSに組み込まれているドライバによりシリアルアダプタとして認識されてしまいます。この状態ではBitBangモードで使うことができませんので、事前にftd_sioドライバを外しておく必要があります。Macの場合には以下の操作をします。特権での操作なのでパスワードが必要です。

$ sudo kextunload /System/Library/Extensions/FTDIUSBSerialDriver.kext

ちょっと面倒ですがこの操作はOSを再起動する度に行う必要があります。もしArduinoを使う場合など、FT232RLをシリアルとして使う必要があるなら下記で元に戻すことができます。

$ sudo kextload /System/Library/Extensions/FTDIUSBSerialDriver.kext

libftdiをbrew installします。依存しているlibusbもインストールされるはずです。

$ brew install libftdi

libftdiをインストールすると、いくつかテスト用のコマンドも同時にインストールされるのでまずはこれを試してみます。

$ /usr/local/bin/simple
ftdi_read_chipid: 0
FTDI chipid: FFC8BFF1
$ bitbang ftdi open succeeded: 0
enabling bitbang mode
turning everything on
turning everything off
fe fd fb f7 ef df bf 7f
fe fd fb f7 ef df bf 7f
fe fd fb f7 ef df bf 7f
fe fd fb f7 ef df bf 7f
disabling bitbang mode

うまく動いているようです。つづいて、これをrubyから使うために、libftdi-rubyをインストールします。githubでも公開されていますが、gemになっているのでインストールにはこちらを使います。

$ gem install libftdi-ruby
Fetching: libftdi-ruby-0.0.4.gem (100%)
Successfully installed libftdi-ruby-0.0.4
Gems updated: libftdi-ruby
Installing ri documentation for libftdi-ruby-0.0.4...
Installing RDoc documentation for libftdi-ruby-0.0.4...

0.0.4が入ればOKです。

テストスクリプトをここからコピペして動かしてみます。

$ ruby libftdi-ruby-test.rb 
Context is:
usb_ctx = #
usb_dev = #
usb_read_timeout = 3
usb_write_timeout = 250000
type = 3279360
baudrate = 1
bitbang_enabled = 0
readbuffer = #
readbuffer_offset = 4096
readbuffer_remaining = 4096
readbuffer_chunksize = 64
writebuffer_chunksize = 0
max_packet_size = 0
interface = 2
index = 129
in_ep = 1
out_ep = 128
bitbang_mode = 1
eeprom = #
error_str = 
module_detach_mode = auto_detach_sio_module

ちゃんとrubyからも認識していることが確認できたら、次にLEDを点滅させてみます。FT232RLの1番ピンとGNDの間に数百オームの抵抗とLEDを直列に繋ぎます。

image

スクリプトはこんな感じになります。

gemでlibftdi-rubyをインストールした場合、このファイルは /usr/local/lib/ruby/user-gems/1.8/gems/libftdi-ruby/examples/blink.rb に入るはずです。

動かしてみます。

$ ./blink.rb

うまく動いているようです。動画も上げておきます。

https://youtu.be/mt8aszsF02Q

ちなみに、デバイスが接続されていない時には以下のエラーとなります。

-3: Ftdi::StatusCodeError

また、シリアルドライバがロードされている場合には以下です。

-5: Ftdi::StatusCodeError

LEDの点滅(通称Lチカ)ができたら、あとは何でも制御できるはずです。コンパイルもアップロードも不要なので、気軽に書いては試すことが繰り返せます。引き続きSPIデバイスの制御をやってみたいと思います。

はまったポイントとリファレンス

comments powered by Disqus