12/8
プログラムの内容 †
- Arduino の光センサの状態をAndroid に表示、Android でArduino のLEDを点滅
使い方 †
- Arduino とAndroid 端末を USB ケーブルで接続し、Android 端末でこのアプリケーションを起動します。
起動すると、最初、Android ロボットが寝た絵が表示された後、以下のような表示が出ます。
- 表示画面上部の [In], [Out] タブで入出力表示を切り替えます。起動した直後は入力データを表示しています。
- 入力表示のとき、
- a0 ... a7 の下の数字がArduino のアナログ入力ポートの A0 ... A7 の値を示します。
- Digital Input: の右に並ぶ8つの数字(0 から 7) の背景の色が Arduino のポート 0 ... 7 に入力されたディジタル値を表します。白だったら0で 水色だったら1を表します。
- 出力表示のとき、以下のような画面になります。
- Arduino の 8 から 13 までの 6 のポートへの出力を制御し、表示します。
- pin8 - pin13 の右が現在の出力を表します。
- 各 pin のラジオボタンでデジタル出力か、アナログ出力の選択を行います。
- デジタル出力の場合 [on] をタッチすると、その pin に 約5Vが出力されます。[0ff]をタッチすると、そのpinに約0V が出力されます。
- アナログ出力の場合、スライドバーの位置で、PWM の比率を 0-255 階調で指定します。
- [Stop] タブを選ぶと、プログラムを終了します。ただし、再起動するとき、Android の設定画面でこのアプリケーションを強制終了しないと、再起動しないことがあります。
ADK利用の流れ †
- 1. BroadcastReceiver? を利用して、ACTION_USB_PERMISSION を判定する。
- 2. UsbAccessory?のインスタンスを取得する。
- 3. UsbAccessory?のインスタンスよりParcelFileDescriptor?を取得する。
- 4. ParcelFileDescriptor?よりFileDescriptor?を取得し、FileInputStream?とFileOutputStream?を取得する
- 5. 各Streamを利用し、入出力の処理を行う。
Manifest の内容 †
AdkArduinoActivity?.java †
- 本アプリケーションの GUI を担当しているクラスのソースです。UsbAccessory? の起動なども行います。
- このActivity の起動時に onCreate(), onStart() と共に, onResume() がシステム側から起動されます。
- onResume() 内で prepareUsbConnection?() が呼び出され、prepareUsbConnection?() 内で mUsbManager? を作成します。
- また、prepareUsbConnection?() では、Usb が接続されたときに、それを認識する準備を行います。この準備により、Usbが接続されたとき、以下の部分によってそれが受信され、Usb との接続が行われます。
private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver(){
@Override
public void onReceive(Context context, Intent intent){
Log.i(TAG, "BroadcastReceiver-onRecieve");
String action = intent.getAction();
if (ACTION_USB_PERMISSION.equals(action)) {
Log.i(TAG, "BroadcastReceiver-onRecieve- ACTION_USB_PERMISSION");
synchronized (this) {
UsbAccessory accessory = UsbManager.getAccessory(intent);
if (intent.getBooleanExtra( UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
openAccessory(accessory);
startService();
doBindService();
} else {
Log.d(TAG, "permission denied for accessory "
+ accessory);
}
mPermissionRequestPending = false;
}
} else if (UsbManager.ACTION_USB_ACCESSORY_DETACHED.equals(action)) {
Log.i(TAG, "BroadcastReceiver-onRecieve- ACTION_USB_ACCESSORY_DETACHED");
UsbAccessory accessory = UsbManager.getAccessory(intent);
if (accessory != null && accessory.equals(mAccessory)) {
closeAccessory();
}
}
}
};
- openAccessory(accessory); で 入出力ストリームが作成され、startService(); で AdkService? を起動します。
- AdkService? が ADK を使って、Arduino との情報交換を行います。
- doBindService?(); は、AdkArduinoActivity? と AdkService? を結びつけ、この間の情報交換を可能にします。
- AdkArduinoActivity? と AdkService? の間の情報交換は、Handlerを使って行います。
AdkService?.java †
- mUsbAccessory? を AdkArduinoActivity? から受け取り、Arduino との間のデータ交換を永続的に行います。
- Arduino へのデータ出力は、public void outputDevice(byte command, byte target, int value) を使います。
- Arduino からのデータ入力は AdkThread? の中の run メソッドのループを通じて行います。
- 内部の IncomingHandler? クラスは、AdkArduinoActivity? との間の情報交換に使います。
- Usb 通信に使う FileDescriptor? も、このクラスでAdkArduinoActivity? から受け取ります。FileDescriptor? から、Arduino と通信を行う入出力ストリームを取り出します。
AdkThread?.java †
Arduino-Android(AdkService?, AdkThread?)間通信 †
AdkService?-AdkArduinoActivity?間通信 †
ArduinoProcess?.java †
- AdkThread? において、Arduino から送られてきたディジタルデータが入力されると、このクラスの
public void processDigitalInput(int vals)
が呼び出されます。この中でそれに対応する処理を書くことで、GUI にコマンドを送ったり、Arduino の制御を行なったりすることができます。
- AdkThread? において、Arduino から送られてきたアナログデータが入力されると、このクラスの
public void processAnalogInput(int port, int val)
が呼び出されます。この中でそれに対応する処理を書くことで、GUI にコマンドを送ったり、Arduino の制御を行なったりすることができます。
- このクラスは以下のようになっていて、processDigitalInput? も processAnalogInput? も、最初は以下のように、ほとんど空っぽでなにもしません。この中身を埋めることにより、様々な処理を行うことができます。
public class ArduinoProcessor {
private static final String TAG = "ArduinoProcessor";
private AdkService adkService;
private long lastTime;
public ArduinoProcessor(AdkService s){
adkService=s;
}
public void setAdkService(AdkService as){
adkService=as;
}
public void processDigitalInput(int vals){
// ADK Accessory からデジタル入力, vals には、Arduino のポート 0-7 の 1 byte の値が入る
// Log.d(TAG,"processDigitalInput-"+vals);
}
public void processAnalogInput(int port, int val){ // ADK Accessory からアナログ入力
// Log.d(TAG,"processAnalogInput-port="+port+" val="+val);
if(adkService==null) return;
if(port==0){
if(val<=10){
// this.adkService.parseSetCommand("out-d-8=1");
}
else{
}
}
}
public void wait(int t){
try{
Thread.sleep((long)t);
}
catch(InterruptedException e){
}
}
}
Counter: 2390,
today: 3,
yesterday: 0
|