- 追加された行はこの色です。
- 削除された行はこの色です。
#freeze
[[FrontPage]]
* 12/8 Arduino と Android の接続 ... ADK [#ffa552f2]
** ADK の概要 [#x88417b5]
- ADK ...Accessory Development Kit
- ADK はAndroid のアクセサリを作成するための、参考的な実装です。これは、ハードウェア会社や電子工作を趣味としている人々のスタートポイントとして利用できます。各ADKのリリースは、ソースコードとハードウェアの仕様が一緒に供給されます。これにより、あなた自身のアクセサリを簡単に作ることができます。新しい、これと異なるADKのハードウェアを作ることを推奨します。 &br;
Android の機能を強化するため、オーディオのドッキングステーションや、運動機器や、個人的な医療検査機器や、電子百葉箱や、その他の外部ハードウェア機器などがAndroid アクセサリとして使えます。&br;
アクセサリは、Android Open Accessory (AOA)プロトコルを使って、USB ケーブルやBluetooth 接続を通じて、Android デバイスと通信します。もし、USB を使うアクセサリを作成する場合、あなたのアクセサリハードウェアとAndroid が通信するために、どのようにAOAプロトコルを実装するか、理解する必要があります。より詳しくは、 [[Android Open Accessory protocol:http://source.android.com/tech/accessories/]] をみてください。
- 参考ページ/文献
-- http://itpro.nikkeibp.co.jp/article/NEWS/20110511/360206/
-- http://developer.android.com/tools/adk/index.html
-- エレキジャック No.23、特集「Android × Arduino で IO!」CQ出版社, 2012年 11月
-- Smartphone World Volume. 3「Android × Arduino 即効プログラミング」CQ出版社
-- 大川善邦著「Android によるマイコン・ボード制御入門」CQ出版社, 2012年8月
-- 岩田直樹、杉浦登、高木基成、原田明憲、吉田研一「Android ADK プログラミング & 電子工作バイブル」ソシム, 2012
-- 坂本俊之、出村成和、渡邊昌之著「基礎から学ぶ組み込みAndroid」C&R 研究所, 2010年
** 簡単なADK応用プログラムの開発例 [#j9744a01]
- http://y-anz-m.blogspot.jp/2011/12/androidhello-adk.html
** ADK 開発環境の構築 [#s8ca8b11]
- http://developer.android.com/tools/adk/adk.html
*** 1. Arduino (1.0 以上)の開発環境をインストール [#w1805f29]
- http://arduino.cc/en/Main/Software
*** 2. ADK パッケージのダウンロード [#nbaea27a]
- https://dl-ssl.google.com/android/adk/adk_release_20120606.zip
*** 3. Arduino の例題プログラムやライブラリやハードウェアの仕様が入ったパッケージをダウンロードして、解凍 [#l997c43f]
- app, arduino_libs, hardware ディレクトリがある。
-- https://dl-ssl.google.com/android/adk/adk_release_20120606.zip
-- http://developer.android.com/tools/adk/adk.html
*** 4. Arduino開発環境にADKライブラリのインストール [#g5f335b0]
- arduino_libs/AndroidAccessory と arduino_libs/USB_Host_Shield directories を <arduino_installation_root>/libraries/にディレクトリごと、すべてコピー。
*** 5. Arduino のスケッチ(firmware)を作成し、Arduinoに書き込み [#u8adfbb2]
- 以下、ADKの firmware の簡単なスケッチの例(今後、ずっとこれを使います)
#include <Max3421e.h>
#include <Usb.h>
#include <AndroidAccessory.h>
/*
data format
pin
A0-A7 ... analog input
4-7 ... digital input
8-11 ... digital/analog(pwm) output
receive
[
'a' or 'd'
pin,
data,
]
send
[
4 (=data_length(byte)),
'a'
port,
data(high),
data(low)
]
or
[
4 (=data_length(byte)),
'd'
data (pin 0-7)
data (0x00)
data (0x00)
]
*/
#define analogInMax 8
#define digitalInMax 8
#define digitalOutMax 14
int analogIns[analogInMax];
int digitalIns[digitalInMax];
int digitalOuts[digitalOutMax];
int digitalVal;
AndroidAccessory acc("Google, Inc.",
"AdkTwitter",
"DemoKit Arduino Board",
"1.0",
"http://www.android.com",
"0000000012345678");
void setup();
void loop();
void setup()
{
Serial.begin(115200);
Serial.print("\r\nStart");
for(int i=0;i<digitalInMax;i++) digitalIns[i]=i;
for(int i=0;i<digitalOutMax;i++) digitalOuts[i]=i;
for(int i=0;i<digitalInMax;i++)
pinMode(digitalIns[i],INPUT);
for(int i=digitalInMax;i<digitalOutMax;i++)
pinMode(digitalOuts[i],OUTPUT);
// pinMode(ledPin, OUTPUT);
// pinMode(b3Pin, INPUT);
analogIns[0]=A0;
analogIns[1]=A1;
analogIns[2]=A2;
analogIns[3]=A3;
analogIns[4]=A4;
analogIns[5]=A5;
analogIns[6]=A6;
analogIns[7]=A7;
acc.powerOn();
}
void loop()
{
byte inMsg[3];
byte outMsg[4];
if (acc.isConnected()) {
int len = acc.read(inMsg, sizeof(inMsg), 1);
int i;
byte b;
if(len>0){
if(inMsg[0]=='a'){
if(inMsg[1]<digitalOutMax)
analogWrite(digitalOuts[inMsg[1]], inMsg[2]);
}
else
if(inMsg[0]=='d'){
if(inMsg[1]<digitalOutMax){
if(inMsg[2]==1)
digitalWrite(digitalOuts[inMsg[1]], HIGH);
else
digitalWrite(digitalOuts[inMsg[1]], LOW);
}
}
}
digitalVal=0;
for(int i=0;i<digitalInMax;i++){
int b=0;
if(digitalRead(digitalIns[i])==HIGH)
b=1;
digitalVal=digitalVal<<1 | b;
}
outMsg[0]='d';
outMsg[1]=digitalVal & 0xff;
outMsg[2]=0;
outMsg[3]=0;
acc.write(outMsg,4);
int sensorValue;
for(int i=0;i<analogInMax;i++){
sensorValue = analogRead(analogIns[i]);
outMsg[0]='a';
outMsg[1]=i;
outMsg[2]=(sensorValue>>8) & 0xff;
outMsg[3]=sensorValue & 0xff;
acc.write(outMsg,4);
}
** [[ADK 開発環境の構築]] [#s8ca8b11]
** [[ADK利用プログラムの説明]] [#e8ed11de]
** 演習 [#p0b08f6e]
*** 入力センサの追加 [#z5a31087]
- Arduino 側で以下の図のような回路を作って、+ 5V に接続されたジャンパ線を 6 番ピンと 7番ピンに触ることにより、Android の入力画面のデジタル入力の 6 番と7番の値が変化することを確かめてください。
-- &ref(arduino-circuit-3.jpg);
*** Android で、LED 点灯自動制御 [#t0389563]
- 前回、Arduino のスケッチで作成した、暗くなったらLEDを点灯し、明るくなったらLEDを消灯するシステムを、Arduino のスケッチを書き換える変わりに、Android 側の、ArduinoProcessor.java の
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{
}
}
}
delay(100);
の部分を書き換えることにより、実現してください。
- コメントアウトしている
this.adkService.parseSetCommand("out-d-8=1");
は、Arduino の 8 番ポートのディジタル出力値を 1 (HIGH) にすることを表しています。これを参考にしてください。
*** Android で、LED 点灯自動制御2 [#vbb8b58e]
- LED の点灯、消灯の状態が変わったとき、その後1分間は、照度センサの値に関係なく、LEDの点滅の状態を持続させるようにしてください。(次回、twitter につぶやく回数を制限する練習です)
- 回答例
public class ArduinoProcessor {
private static final String TAG = "AdkService";
private AdkService adkService;
private long lastTime;
private long minimumHoldTime=100000;
// 最小状態保持時間(msec)。twitter の制限も。tweet は1日に1000回まで。1時間で42回まで。
private boolean led_on=false;
public ArduinoProcessor(AdkService s){
adkService=s;
}
public void setAdkService(AdkService as){
adkService=as;
}
public void processDigitalInput(int vals){
// Log.d(TAG,"processDigitalInput-"+vals);
}
public void processAnalogInput(int port, int val){
// Log.d(TAG,"processAnalogInput-port="+port+" val="+val);
if(port==0){
if(val<=10){
if(adkService==null) return;
if(!led_on){
Date date = new Date();
long timeNow=date.getTime();
if(timeNow-lastTime>minimumHoldTime){
this.adkService.parseSetCommand("out-d-8=1");
// this.adkService.sendCommandToActivity("twitter tweet", "LED ON at "+date.toString());
led_on=true;
lastTime=timeNow;
}
}
}
else{
if(adkService==null) return;
if(led_on){
Date date=new Date();
long timeNow=date.getTime();
if(timeNow-lastTime>minimumHoldTime){
this.adkService.parseSetCommand("out-d-8=0");
// this.adkService.sendCommandToActivity("twitter tweet", "LED OFF at "+date.toString());
led_on=false;
lastTime=timeNow;
}
}
}
}
}
public void wait(int t){
try{
Thread.sleep((long)t);
}
catch(InterruptedException e){
}
}
}
*** 6. Android 側開発環境構築 [#k817d114]
- Eclipse の Android SDK マネージャ のアイコンをクリックして起動し、Android 4.0 ( Google APIs 14 を含む) をインストール
-- &ref(12/8/eclipse-adk-1.png,50%);
-- &ref(12/8/eclipse-adk-2.png,30%);
*** 7. Android 側アプリ開発 [#m657b89d]
*** 8. Android 側アプリをAndroid 端末の SDカードに保存し、アプリをインストール [#ode9cf9c]
-- アストロファイルマネージャなどを利用
*** 9. Android 端末と Arduino をUSBケーブルで接続。 [#r8905741]
*** 10. 実行。 [#q2ec023b]
** ADK利用の流れ [#n3745f4b]
- 1. BroadcastReceiver を利用して、ACTION_USB_PERMISSION を判定する。
- 2. UsbAccessoryのインスタンスを取得する。
- 3. UsbAccessoryのインスタンスよりParcelFileDescriptorを取得する。
- 4. ParcelFileDescriptorよりFileDescriptorを取得し、FileInputStreamとFileOutputStreamを取得する
- 5. 各Streamを利用し、入出力の処理を行う。
** Arduino の光センサの状態をAndroid に表示、Android でArduino のLEDを点滅 [#gd08bddf]
** デバッグ [#p0b08f6e]
- LogcatViewer [#z89dd6d3]
-- http://d.hatena.ne.jp/bs-android/20100519/1274206549
** Android で、LED 点灯自動制御 [#t0389563]
** 総合演習 [#ydd1ed5b]
*** 総合演習 [#ydd1ed5b]
- 隣どおし、または前後で2-4人のグループを作って、今までのプログラムを参考にしたり、改造したりして、何か面白いものを作ってください。
* QA [#f518682e]
** Arduino 側と Android 端末側のそれぞれで動作するアプリの機能の実装は、制御される側と制御する側という視点で行えばよいか? [#a0833cdb]
- USB のホスト側とデバイス側のどちらか?という意味では、Android がデバイス側で、Arduinoがホスト側です。Arduino 単体でもかなり複雑なことはできますが、今回の例題では、Arduino はただ単にセンサとアクチュエータを Android と接続するためだけに使っています。このように役割分担することでシステム開発が楽になると思います。
** Eclipse 上で変更を行ったアプリのパッケージ作成手順を詳しく説明して欲しい。パッケージを作成する際の注意事項等があると助かると思います。 [#w61f6e8f]
- 12/15 に説明します。
** タブレットでアプリを起動した際、Arduino の接続を検出できなかったり、接続を検出できんても通信がおこなえていなかったりという現象がありました。アプリの再起動や再インストールなどで復活しましたが、安定させる方法などはないでしょうか? [#v886abdc]
- Arduino の接続検出の問題は、Arduino 側のUSB 通信ライブラリの問題でした。setup() 関数の中の、
acc.powerOn() の前に、delay(5); を入れるとこの問題を緩和することができます。
** Android 側のソースの説明はあったが、Arduino のソースの説明をもっと挟んで欲しかった。 [#qbeef320]
- 次回のセミナーでは、ADKの接続不良の対処方法をもとに、ADK の動作確認を行い、twitter に LED の点滅状況を通知するプログラムをくむことができればと思う。
** 実際に動かしながら説明して欲しいと感じました。 [#s5946608]
** ADK 利用プログラムで各ソースの内容が把握しづらかった。 [#s24e2487]
----
#counter