2011年11月19日土曜日

ADKアプリの作成 ープロジェクト作成ー

Androidプロジェクトで、SDKはGoogleAPIs API Level10を選択。
これで2.3.4でUSB Accessory Modeを使用できる。

AndroidManifest.xml
<application android:icon="@drawable/ic_launcher"
                    android:label="@string/app_name" >
 ①<uses-library android:name="com.android.future.usb.accessory" />
    <activity android:label="@string/app_name"
                  android:name=".TestADKActivity" >
        <intent-filter >
            <action android:name="android.intent.action.MAIN" />
         ②<action android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED" />                
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
     ②<meta-data android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED"
                        ③android:resource="@xml/accessory_filter" />
    </activity>
</application>
①USB Accessory APIを使う宣言。
②USBホスト接続時のアプリ起動指定。
③Arduinoのスケッチ内で起動するAndroidアプリを特定する情報を記載する。

accessory_filter.xml
<resources>
    <usb-accessory manufacturer="Utsugen" model="TestADK" version="1.0" />
</resources>

Arduinoスケッチ
AndroidAccessory acc("Utsugen",
    "TestADK",
    "TestADK by Utsugen",
    "1.0",
    "http://utsugen.blogspot.com/",
    "0000000012345678");




ADKの学習

Androidは USBホスト と USBデバイス の両方になる事が出来る。

下側のUSBデバイスとして動作する為のライブラリが
Android USB Accessory Development Kit ADKとして提供されている。
そしてこのときのUSBホストがArduinoという構成だ。

ADKにはDemoKitというアプリが入っているので読んでみよう。

まずはAndroidManifest.xml。
アクティビティ
・.DemoKitLaunch    <ーー"android.intent.action.MAIN"
・.DemoKitActivity
・.DemoKitPhone
・.DemoKitTablet
・UsbAccessoryActivity

次にMAINのDemoKitLaunchクラス。
ここではactivity.getWindowManager().getDefaultDisplay()から
画面サイズを取り出している。
画面サイズが閾値以上ならDemoKitTablet、以下ならDemoKitPhoneを
IntentにつめてstartActivityしている。
タブレットかスマートフォンかの識別子が無いのだろう。

Xperiaで動かすのでDemoKitPhoneクラスを見ていこう。
ここは画面上のIN/OUTタブの切り替えを管理しているだけ。

DemoKitPhoneが継承しているのはBaseActivityクラス。
ここはUSBホストへの入力信号を受け取ったハンドラに合わせて
処理実行クラスのメソッドを呼び出している。

さらにBaseActivityが継承しているのはDemoKitActivityクラス。
ここでUsbManagerが生成されるいわば実装クラス。
UsbManagerのFileInputStreamとFileOutputStreamを使って
入力信号受信スレッドと、出力信号生成メソッドを実装している。


DemoKitLaunch
            |__ DemoKitPhone ー BaseActivity ー DemoKitActivity
                                                                  |         |
                                                        InputController ColorWheelLEDController
                                                        RelayController
                                                        ServoController


AndroidManifest.xmlにはUsbAccessoryActivityが記述されている。
<intent-filter>、<meta-data>に
"android.hardware.usb.action.USB_ACCESSORY_ATTACHED"
が指定されているので、このクラスはソースから明示的に呼ばれるのではなく、
USBホストにAndoroid端末が接続された際に呼び出される。
このクラスがDemoKitLaunchをIntentにつめてstartActivityしている。


2011年11月17日木曜日

ADK! Arduino側の準備


  1. ADK一式ダウンロード
    http://developer.android.com/guide/topics/usb/adk.html
  2. Arduinoライブラリのコピー
    ADK_release_0512 -> firmware -> arduino_libs -> USB_Host_Shield
                                                                              -> AndroidAccessory
    ADK内の上の2つのディレクトリを以下にコピー。
    Arduino -> パッケージの中身を表示 -> Contents -> Resources
    -> Java -> Libraries
  3. USBホストシールドライブラリのダウンロード
    http://www.circuitsathome.com/arduino_usb_host_shield_projects
    このページ内のLegacy USB Host libraryからダウンロード。
  4. USBホストシールドライブラリのコピー
    3の全てのファイルを2のUSB_Host_Shieldに上書きコピー。
  5. サンプルスケッチ
    3のページ内のAndroid ADK-compatible library releaseのスケッチをUpload。
    #include <Max3421e.h>
    #include <Usb.h>
    #include <AndroidAccessory.h>
     
    AndroidAccessory acc("Google, Inc.",
           "DemoKit",
           "DemoKit Arduino Board",
           "1.0",
           "http://www.android.com",
           "0000000012345678");
    void setup();
    void loop();
     
    void setup()
    {
     Serial.begin(115200);
     Serial.print("\r\nStart");
     acc.powerOn();
    }
     
    void loop()
    {
      byte msg[3];
     
     if (acc.isConnected()) {
                    Serial.print("Accessory connected. ");
      int len = acc.read(msg, sizeof(msg), 1);
                    Serial.print("Message length: ");
                    Serial.println(len, DEC);
            }
     
     delay(100);
    }



2011年11月5日土曜日

9V電池でArduinoを動かす。

これまではPCとArduinoをUSBで接続して給電していた。
今後は無線で動き回る物を作りたいので電源について考えた。

Arduino UNOの入力電圧は7〜12V。最低限必要な動作電圧は5V。
ACアダプタは9Vの2.1mmセンタープラス型推奨。

9V電池が一番簡単そうだ。
DCポート用の2.1mmプラグが手元に無い。
だが、DCポートとVinポートは内部で繋がっているとのことなので、
電池ボックスの赤リード線(+)をVin、黒リード線(-)をGNDに接続する。



動作OKのようだ。

次は電池はDCポートに接続して、Vinからの9Vでモーターの制御を行いたい。


2011年11月4日金曜日

アナログ入力とシリアル通信

Arduinoのアナログ入力はアナログ0〜5ピンを使用する。

CdSセル(光センサ)の入力値を、LEDのPWM出力に使ってみる。

さらにCdSセルの入力値はシリアル通信でPCに送るのは簡単で
Serial.println 関数を呼ぶだけ。


2011年11月3日木曜日

PWMをやってみる。

モーターの回転数制御に欠かせないPWMをLEDで試してみる。

PWMとは、電圧を上下させる代わりに、HIGH/LOWの比率を変化させる事で
モーターの回転数を制御する仕組み。
回転数 速い
回転数 遅い

ArduinoのデジタルIOピン0〜13のうち、3,5,6,9,10,11の6本がPWMに使用できる。
PWMはアナログ出力を使う。
  analogWrite(ピン番号, 0〜255)





#define  LED  11
#define  SW   6

int val = 0;
int valOld = 0;
int state = 0;
int stateOld = 0;

void  setup()
{
  pinMode( LED, OUTPUT );
  pinMode( SW, INPUT );
}

void  loop()
{
  val = digitalRead( SW );
  if( val == HIGH && valOld == LOW ){
    state = 1 - state;
    delay(10);
  }
  valOld = val;
 
  if( state != stateOld ){
    if( state == 1 ){
      for( int i=0; i<=255; i++){
        analogWrite( LED, i );
        delay( 10 );
      }
    } else {
      for( int i=255; i>=0; i--){
        analogWrite( LED, i );
        delay( 10 );
      }
    }
    stateOld = state;
  }
}

2011年10月21日金曜日

タクトスイッチを使う。

Arduinoの5V出力をタクトスイッチにつなげて、
Arduinoの入力ピンで状態を受け取る。

LEDには330Ωの抵抗を使ったが、タクトスイッチには?
仮に抵抗を使わなかった場合には、
5V / 0Ω = ?
無限大の電流が流れて、ショートの状態となってしまう。

10KΩの抵抗を使う。
茶 黒       橙     金
1 0 x 1000  ±5%



スケッチはこのように書いた。
#define  LED  13
#define  SW   6

int val = 0;

void  setup()
{
  pinMode( LED, OUTPUT );
  pinMode( SW, INPUT );
}

void  loop()
{
  val = digitalRead( SW );
  if( val == HIGH ){
    digitalWrite( LED, HIGH );
  } else {
    digitalWrite( LED, LOW );
  }
}


これはスイッチを押している間だけLEDが点灯するスケッチ。
やはりスイッチはON/OFFに使いたい。

Arduinoは1秒間に数百万行のコードを実行できる。
指でスイッチを押している間にも、loop関数は何度も呼び出される事になる。

そのうちの押し初めの1回だけ検出する = 「前回がLOW、今回がHIGH」

#define  LED  13
#define  SW   6

int val = 0;
int valOld = 0;
int state = 0;

void  setup()
{
  pinMode( LED, OUTPUT );
  pinMode( SW, INPUT );
}

void  loop()
{
  val = digitalRead( SW );
  if( val == HIGH && valOld == LOW ){
    state = 1 - state;
    delay(10);
  }
  valOld = val;
  if( state == 1 ){
    digitalWrite( LED, HIGH );
  } else {
    digitalWrite( LED, LOW );
  }
}