2012年02月18日

AndroidからFTDI Bit-bangモードの制御

Android上で動作する、FTDIのUSBシリアル/パラレル変換チップFT232/245シリーズ用のデバイスドライバ FTDriver(@ksksue氏作)ってのがありまして、今話題です。
https://github.com/ksksue/FTDriver
Android 3.1以降で対応した、USB Host APIにより、FTDIチップから任意のシリアル入出力が出来ます。

今回、ksksue氏のgithubからのフォークに初挑戦し、そこにBit-bangモードに対応する改変を入れてみました。
上記本線からforkしたのはこちら⇨ https://github.com/yishii/FTDriver

Bit-bangモードとは、FTDIのFT232BM、FT245BMからサポートされたモードで、USBシリアル/USBパラレル変換ではなく、汎用入出力IOをUSBからの制御に基づいて行う、USB-IO的な動作するモードです。
FT232RLでは、5ビットのC-BUSピンのも追加され、UARTの機能を生かしたまま、Bit-bangモードを使用することもできます(要EEPROM書き換え)。

P1100979.JPG

Bit-bangモードの制御追加は、OSSのlibusb上の制御モジュールlibFTDIを参考に実装してみました。
使い方は簡単。こんなかんじです。

	FTDriver mSerial;
	final int MODE_SERIAL = FTDriver.BAUD115200;
	mSerial = new FTDriver((UsbManager)getSystemService(
		Context.USB_SERVICE));
	mSerial.begin(MODE_SERIAL);

	// 第二引数 1 => Output
	mSerial.setBitmode(true, 0xff,
		FTDriver.FTDI_MPSSE_BITMODE_BITBANG);

	for(i=0;i<=5;i++){
		data[0] = (byte)0xff;
		mSerial.write(data,1);
		Log.i("FTDriverTest","Output high");

		data[0] = (byte)0x00;
		mSerial.write(data,1);
		Log.i("FTDriverTest","Output low");

	}
	// exit from bit-bang mode
	mSerial.setBitmode(false, 0, 0);

	mSerial.end();
入力の場合、
	FTDriver mSerial;
	final int MODE_SERIAL = FTDriver.BAUD115200;
	byte data;

	mSerial = new FTDriver((UsbManager)getSystemService(
		Context.USB_SERVICE));
	mSerial.begin(MODE_SERIAL);

	mSerial.setBitmode(true, 0x00,
		FTDriver.FTDI_MPSSE_BITMODE_BITBANG);

	data = mSerial.getPinState();

	// exit from bit-bang mode
	mSerial.setBitmode(false, 0, 0);

	mSerial.end();

動画貼り付けました。実験としては、秋月のフルカラーLEDバーをFTDI FT232RLが搭載されたArduino duemilanoveのFTDIピンに接続し、Android側からIO制御するものです。
FTDI_BBdemo.png
FTDIボードとして、Arduino duemilanoveを使用していますが、AVR側は何もしない起動直後に無限ループするファームを焼いています。従って、Arduinoではなく、単なるFTDIボードとして使用しています。


以下のボードでAndroidから8ビットの汎用I/Oできるってことです。

FT232RL搭載小型USB-シリアルアダプタ 5V
スイッチサイエンス
売り上げランキング: 16984


Arduinoをはじめようキット
スイッチサイエンス
売り上げランキング: 510
ラベル:FTDI android
posted by いしいっち at 15:09| Comment(0) | TrackBack(0) | Android開発関連 | このブログの読者になる | 更新情報をチェックする

2011年12月28日

ADKやBTに対応したMemoryMapLibリリースしました

以前本ブログでご紹介いたしましたArduino用の機器間通信プロトコルモジュール MemoryMapLibを バージョンアップさせ、Android Accessory(ADK)で使用できるようにしてみました。

以前の記事はこちら。
http://projectc3.seesaa.net/article/237969593.html
プロトコルの詳細説明は上記URL内記事内にpdfへのリンクを貼りつけています。

MemoryMapLibは、夜子ママ氏作のAndroid用ライブラリ AndyLibと通信できるライブラリです。MemoryMapプロトコルに対応 している機器と通信できます。
AndyLibでは通信路としてBluetooth以外に、Android AccessoryやMicrobridgeなど複数の経路を抽象化、上位アプリ側に 公開するレイヤとして機能してくれます。
対するArduino側のMemoryMapLibも、各種インターフェースに対応する作りにしました。
この2つのモジュール間のやりとりは中間経路をいろいろ選択できるといえると思います。

★今現在、AndyLibについては、日本Androidの会・神戸支部のリポジトリにて公開されています。

さて本記事では、MemoryMapLibのAndroid Accessoryで使用する場合と、UART(Bluetooth含む) で使用する場合のコードの対比をしていきたいと思います。

ライブラリに同梱しましたサンプルスケッチは、ADKとUARTシリアル両方に対応しています。

サンプルスケッチの中に
#if 1
#define ADK_ENABLE
#else
#define SERIAL_ENABLE
#endif
という部分がありますので、ADK_ENABLEまたは、SERIAL_ENABLEのいずれかが有効になるようにしていただければOKです。

プロトコル等は上述のMemoryMapLibの説明から変化ありませんが、ADK等のインターフェースに対応できるように、一部改変しました。 インターフェースの設定は、 MemoryMapLib::setStreamInterface() で行います。

ここに、Android Accessoryまたは、SerialのStreamのインスタンスを設定します。
上記初期設定の後、通信処理についてはインターフェースに関わらず共通です。

●Android Accessory(ADK)選択時の初期化部例
MemoryMap mMemoryMap;
AndroidAccessory mAndroidAccessory("IshiiWorks",
    "AndyTank","AndyTank","1.0","http://www.yishii.jp/",
    "0000000012345678"); // ★作成するデバイスに合わせて変更
AndroidAccessoryStream mAndroidAccessoryStream;

setup(void){
    mAndroidAccessoryStream.setInterface(&mAndroidAccessory);
    mMemoryMap.setStreamInterface(&mAndroidAccessoryStream);
}
void loop()
{
    mMemoryMap.poll();
}

●UART(Bluetooth)選択時の初期化部
setup(void){
    Serial.begin(9600);  // 外部機器とは9600bpsで通信
    Serial.flush();
    mSerialStream.setInterface(&Serial);
    mMemoryMap.setStreamInterface(&mSerialStream);
}
void loop()
{
    mMemoryMap.poll();
}

以上です。
新たにインターフェースを追加する場合には、それ用のCommunicationStreamクラスを定義すればOKです。
とりあえず、Microbridge版も作ろうかなと思います。

ソースは以下のgithubにあげてあります。
https://github.com/yishii/Arduino_MemoryMapLib

電脳Arduinoでちょっと未来を作る (マイコンと電子工作)
藤本 直明 神崎 康宏 森 直久 光永 法明 k.kinukawa hatayan 山田 斉 ざがん あみのさん
CQ出版
売り上げランキング: 33770
posted by いしいっち at 07:00| Comment(0) | TrackBack(0) | Android開発関連 | このブログの読者になる | 更新情報をチェックする

2011年08月12日

PICとAndroidとUSB接続する Microbridge/PIC公開!

PICマイコンといろいろなバージョンのAndroid端末を接続し、マイコンと端末とが自在に連携できるソフトウェアスタック「Microbridge/PIC」を公開しました!!

Google code : microbridge-pic
http://code.google.com/p/microbridge-pic/


元々Niels Brouwer氏作成のArduinoとUSB Host Shieldとを組み合わせたシステム向けのC++実装によるライブラリ「MicroBridge」というものがあり、これをUSBホスト内蔵PIC向けにポーティングしたものになります。
本家MicroBridge : http://code.google.com/p/microbridge/

MicroBridgeは、ADK(というかAndroid Open Accessory)に対応していない端末でも、本来ADKで実現するような外部機器連携を実現したい、という課題に対して、
本来AndroidとPCとが、デバッグの目的で通信する為のプロトコルADB(Android Debug Bridge)のPC側通信相当をマイコンにやらせる事で、ADBはAndroidの古いバージョンにも実装されているので、例えばAndroid1.6のHT-03AやIS01でもADKの様な電子機器連携実験が出来る、というものになります。

では、ADBで何が出来るか?なのですが、例えば、PCでAndroidのログデータを取得する時は、
adb logcat
というコマンドを実行しますよね。
また、
adb push ファイル
や、
adb shell
でLinuxのシェルのコマンドを叩いたりとか
PC側アプリとAndroidアプリとがソケット通信で連携したい時には、
adb forward tcp:port_no tcp:port_noとしたり、
また、DDMSでのスクリーンショット取得などしたりしますが、これらは実際には、内部でADBの通信で実現されているものですので、そのような事がマイコンから実行出来るというわけです。従って、古いバージョンにも搭載されているADBを利用しますから、ADKに対応していないバージョンのAndroid端末でもADKと似たような、外部機器連携に使用できるというわけです。ADBによるADKの置き換えをする場合、上記のadb forwardによるソケット通信が丁度代替手段になります。

さて、今回は、1チップでUSBホスト出来るPICマイコン向けにPIC用gccのMicrochip C30コンパイラと、MicrochipのUSB Hostフレームワーク上で動作できるよう移植をする際、PIC ADK Miniboard Rev.1を使用しています。PIC24FJ64GB002の神戸支部オリジナルマイコンボードです。

R1205964.JPG


Google codeにアップしているソースは、まだデバッグ後の整理がきちんと出来ていません。
特に、microbridge/Adb_pic.c はMicrobridge/PICのメインモジュールになりますが、Arduino実装も#if 0〜#endifで残していたりしてかなりごちゃごちゃしてしまっています^^;まあ動きますので^^;;
これからメンテしていきます^^;

現在Microbridge/PICのサイトにアップしているソースは、Android端末と接続することで、端末のログデータ(logcat)を取得し、PICのUARTから吐き続けるものになります。
アップしているツリーではmain.cにメインの処理を実装しています。(元祖MicroBridgeがArduinoプロジェクトだったのでメインアプリがスケッチになっています。main.cはMicroBridgeでのスケッチに相当するイメージです)

Microbridge/PICの基本的な使い方はシンプルで、
(1)ADB_init()
して、
(2)handle=ADB_addConnection(connectionString,flag)
でADB接続を開始し、ハンドルを取得し、
(3)ADB_poll(handle)
でポーリングさせるだけです。イベントがあれば、adbEventHandler()がMicrobridge/PIC側から呼び出されるのでイベントに応じた処理をハンドラ内に実装すればOKです。

例えば、logcatのログデータを取得するという場合でしたら、(2)のパラメータconnectionStringに「"shell:exec logcat"」を設定します。
flagは、コマンド終了後再度同じコマンドを連続して実行する事でずっと指定した内容を実行しつづけたい時にtrueにします。

shellを使用した、別な例として、例えばAndroidのLinuxのロードアベレージを取得したい場合には、

ADB_init();
c=ADB_addConnection("shell:exec cat /proc/loadavg",false);
while(1){
ADB_poll(c);
}

などとすれば、Android端末のロードアベレージのデータが取得できたとき、adbEventHandlerが呼び出されます。

また、以下のブログで記載させていただきました、Android端末に外部キーパッドを接続して操作する実験でも、ブログにも記載させていただいておりますが、shellのinputコマンドを叩くことで実現しています。結構Androidのシェルから叩いて実現できることは多そうで楽しそうです。
http://projectc3.seesaa.net/article/218366776.html

DDMSでスクリーンショットを取得する操作をMicrobridge/PICでする事もできます。
http://projectc3.seesaa.net/article/216842505.html


また、Android端末のアプリとソケット接続で繋ぎたい時には、例えばポート番号60101で接続したいとした場合、

ADB_init();
c=ADB_addConnection("tcp:60101",true);
while(1){
ADB_poll(c);
}


とすることで、PCのADBでの操作の「adb forward tcp:xxxxx tcp:60101」に相当するADBデーモンに対する制御を行ってアプリとソケット通信を介して連携できます。
日本Androidの会・神戸支部のGoogle codeのリポジトリでは、上記のadb forwardでの簡単なアプリとの連携サンプルコードをアップしています。
(先日、大阪日本橋の電気街ででんでんタウンもくもく会というPIC ADK Miniboardのイベント http://atnd.org/events/18402 がありまして、それに目がけて取り急ぎこしらえました)
Google codeサイト側もこれからコンテンツやソース等充実していきます。

なお、本家MicroBridgeでは、Android端末とマイコンの間で複数個の接続を並列して確立できる作りになっています。
(例:logcatを取得する接続を切断せず、並行してadb forwardも行う、等)
現状のMicrobridge/PICでの既知の制限事項は、一つのADB接続のみをハンドリングしているというものです(実装上はほぼ考慮しているるのですが、全てのAPIで対応できていない)。本家同様の複数接続対応(ポーリングでデータを取得した時にどの接続のものかIDで判断するようにする)自体は困難では無さそうなので、近日中にアップデートしようかなと思っています〜。

なお、PIC ADK Miniboard Rev.1については、過去記事でも何度か記事にさせていただいておりますのでよろしければご参照くださいませ。

また、ボード及びソフト関連について詳しくはGoogle Groupsの日本Androidの会・神戸支部へどうぞー。
http://groups.google.com/group/android-jp-kobe?hl=ja
現在、PIC ADK Miniboard Rev.2に関する議論も進めています。




Android NDKネイティブプログラミング―Native Development Kit
出村 成和
秀和システム
売り上げランキング: 725



Arduino Uno
Arduino Uno
posted with amazlet at 11.08.02
スイッチサイエンス
売り上げランキング: 10101



posted by いしいっち at 13:52| Comment(0) | TrackBack(1) | Android開発関連 | このブログの読者になる | 更新情報をチェックする