20130119 adkハンズオン発表資料
- 2. 配布物の確認をお願いします
○ ブレッドボード ○ 配線材
○ LED (赤色) ●
緑(長)× 1
○ タクトスイッチ ●
緑(長)× 2
○ 抵抗器 1kΩ × 1 ●
赤×2
○ 抵抗器 10kΩ × 2 ●
黒×2
○ Cds
○ サーミスタ
作業中でも、線材や部品の不足に気づいたら、
声をかけて下さい
01.19, 2013 Copyright C-LIS CO., LTD. 2011
2
- 4. 自己紹介 – 有山 圭二
○ 有限会社シーリスの代表
○ 普段はAndroidのアプリ開発とかしています
●
たまにコントリビュートもしてるよ
○ 電子工作の経験は、約2ヶ月
01.19, 2013 Copyright C-LIS CO., LTD. 2011
4
- 5. 今回は、
「発表ドリブン学習」です
01.19, 2013 Copyright C-LIS CO., LTD. 2011
5
- 6. 発表ドリブン学習とは?
勉強会等での発表が決まってから、
ようやくその技術の勉強を本格的に始めること。
01.19, 2013 Copyright C-LIS CO., LTD. 2011
6
- 8. ADK(Accessory Development Kit) とは
○ Android端末にアクセサリを接続する規格AOA(Android Open
Accessory)に準拠したデバイスや、対応アプリケーションを実
装する開発キット
○ 2011年5月、Google I/Oで発表 (ADK 2011)
○ Android端末とアクセサリはUSBで接続。Android側ではアク
セサリの認識と対応アプリケーションの立ち上げまでを担当
○ Android端末とアクセサリの通信は、byte列の送受信で行う
01.19, 2013 Copyright C-LIS CO., LTD. 2011
8
- 9. ADK 2011の概要
○ オープンソースハードウェア”Arduino”に、Android端末
を接続する「USBホスト機能」を付加したもの。
○ Androidとの通信をハンドリングするライブラリが配布さ
れている。
01.19, 2013 Copyright C-LIS CO., LTD. 2011
9
- 10. Arduino とは
○ Arduino(アルドゥイーノ)は、AVRマイコン、入出力ポー
トを備えた基板、C言語風のArduino言語とそれの統合開
発環境から構成されるシステム。 (Wikipediaより)
○ USB接続経由でプログラムの書き込みが出来る
01.19, 2013 Copyright C-LIS CO., LTD. 2011
10
- 14. はじめて の スケッチ
#define PIN_LED 13
void setup() {
pinMode(PIN_LED, OUTPUT);
}
void loop() {
digitalWrite(PIN_LED, HIGH);
}
adk-handson/led
01.19, 2013 Copyright C-LIS CO., LTD. 2011
14
- 17. Arduino MEGA ADK
PCへ接続
+ 給電
Android端末へ
01.19, 2013 Copyright C-LIS CO., LTD. 2011
17
- 23. LED
短い方がGND
01.19, 2013 Copyright C-LIS CO., LTD. 2011
23
- 24. LEDを挿す
短い方がGND
01.19, 2013 Copyright C-LIS CO., LTD. 2011
24
- 25. LEDを点滅
#define PIN_LED 13
void setup() {
pinMode(PIN_LED, OUTPUT);
}
void loop() {
digitalWrite(PIN_LED, HIGH);
delay(1000);
digitalWrite(PIN_LED, LOW);
delay(1000);
}
adk-handson/blink_led
01.19, 2013 Copyright C-LIS CO., LTD. 2011
25
- 39. LEDをゆっくりと点滅
#define PIN_LED 13
void setup() {
pinMode(PIN_LED, OUTPUT);
}
int light = 0;
int p = 1;
void loop() {
light += p;
if (light == 0 || light == 255) {
p *= -1;
}
delay(10);
analogWrite(PIN_LED, light);
} adk-handson/illuminate_led
01.19, 2013 Copyright C-LIS CO., LTD. 2011
39
- 41. Width
PWM (Pulse Wave Modulation)
01.19, 2013 Copyright C-LIS CO., LTD. 2011
41
- 44. SWTCH ILLUMINATE LED
#define PIN_LED 13
#define PIN_SWITCH 8
#define ON 1
void setup() {
Serial.begin(115200);
pinMode(PIN_LED, OUTPUT);
pinMode(PIN_SWITCH, INPUT);
}
boolean on = false;
int prevState = 0;
int light = 0;
int p = 1;
adk-handson/switch_illuminate_led
01.19, 2013 Copyright C-LIS CO., LTD. 2011
44
- 45. void loop() {
int state = digitalRead(PIN_SWITCH);
if (state == ON && state != prevState) {
on = !on;
light = 0;
p = 1;
Serial.println("State change.");
}
prevState = state;
if (on == true) {
light += p;
if (light == 0 || light == 255) {
p *= -1;
}
delay(10);
}
analogWrite(PIN_LED, light);
}
adk-handson/switch_illuminate_led
01.19, 2013 Copyright C-LIS CO., LTD. 2011
45
- 46. 上手く動かない場合 - シリアルモニタ
void setup() {
Serial.begin(115200);
pinMode(PIN_LED, OUTPUT);
pinMode(PIN_SWITCH, INPUT);
}
void loop() {
int state = digitalRead(PIN_SWITCH);
if (state == ON && state != prevState) {
on = !on;
light = 0;
p = 1;
Serial.println("State change.");
}
// 省略
01.19, 2013 Copyright C-LIS CO., LTD. 2011
46
- 51. 暗くなると光るLED
#define PIN_LED 13
#define PIN_CDS A0
#define ON 1
#define LIGHT_THRESHOLD 700
void setup() {
Serial.begin(115200);
pinMode(PIN_LED, OUTPUT);
pinMode(PIN_CDS, INPUT);
}
boolean on = false;
int prevState = 0;
int light = 0;
int p = 1;
adk-handson/cds_illuminate_led
01.19, 2013 Copyright C-LIS CO., LTD. 2011
51
- 52. void loop() {
int state = analogRead(PIN_CDS);
Serial.println(state);
if (state > LIGHT_THRESHOLD && on
|| state < LIGHT_THRESHOLD && !on) {
on = !on;
light = 0;
p = 1;
}
if (on) {
light += p;
if (light == 0 || light == 255) {
p *= -1;
}
delay(10);
}
analogWrite(PIN_LED, light);
}
adk-handson/cds_illuminate_led
01.19, 2013 Copyright C-LIS CO., LTD. 2011
52
- 55. ADK 2011パッケージのダウンロード
https://dl-ssl.google.com/android/adk/adk_release_20120606.zip
01.19, 2013 Copyright C-LIS CO., LTD. 2011
55
http://developer.android.com/tools/adk/adk.html
- 56. ADK 2011ライブラリをコピー
arduino_libs以下を、Documents/Arduino/libraries にコピー
01.19, 2013 Copyright C-LIS CO., LTD. 2011
56
- 57. Arduino スケッチ - ADKへの対応
#include <usb.h>
#include <AndroidAccessory.h>
#define PIN_LED 13
AndroidAccessory acc("C-LIS CO., LTD.",
"ADK Test",
"This is an ADK test.",
"1.0.0",
"http://www.c-lis.co.jp",
"1234567890");
void setup() {
pinMode(PIN_LED, OUTPUT);
acc.powerOn();
}
void loop() {
if (acc.isConnected()) {
digitalWrite(PIN_LED, HIGH);
} else {
digitalWrite(PIN_LED, LOW);
}
}
adk-handson/adk_led
01.19, 2013 Copyright C-LIS CO., LTD. 2011
57
- 60. usb.jarをbuild pathに追加
[SDKをインストールしたディレクトリ]/add-ons/addon-google_apis-google-10/libs 60
01.19, 2013 Copyright C-LIS CO., LTD. 2011
- 61. <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="jp.co.c_lis.adktest"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="10"
android:targetSdkVersion="17" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:launchMode="singleInstance"
android:theme="@style/AppTheme" >
<uses-library android:name="com.android.future.usb.accessory" />
<activity
android:name="jp.co.c_lis.adktest.MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED" />
</intent-filter>
<meta-data
android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED"
android:resource="@xml/accessory_filter" />
</activity>
</application>
</manifest>
AndroidManifest.xml
61
01.19, 2013 Copyright C-LIS CO., LTD. 2011
- 62. <?xml version="1.0" encoding="utf-8"?>
<resources>
<usb-accessory manufacturer="C-LIS CO., LTD." model="ADK Test" version="1.0.0" />
</resources>
res/xml/accessory_filter.xml
01.19, 2013 Copyright C-LIS CO., LTD. 2011
62
- 65. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" >
<ToggleButton
android:id="@+id/toggle_led"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:textOff="LED OFF"
android:textOn="LED ON" />
</RelativeLayout>
res/layout/activity_main.xml
01.19, 2013 Copyright C-LIS CO., LTD. 2011
65
- 66. import com.android.future.usb.UsbAccessory;
import com.android.future.usb.UsbManager;
// 以下、import 省略
public class MainActivity extends Activity {
private static final String LOG_TAG = "AdkTest";
private static final String ACTION_USB_PERMISSION = "jp.co.c_lis.adktest.action.USB_PERMISSION";
private UsbManager mUsbManager = null;
private PendingIntent mPermissionIntent = null;
private boolean mPermissionRequestPending = false;
private UsbAccessory mAccessory = null;
private ToggleButton mLed = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mLed = (ToggleButton) findViewById(R.id.toggle_led);
mUsbManager = UsbManager.getInstance(this);
mPermissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(
ACTION_USB_PERMISSION), 0);
IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
filter.addAction(UsbManager.ACTION_USB_ACCESSORY_DETACHED);
registerReceiver(mUsbReceiver, filter);
// 現在は非推奨。Fragment#setRetainInstance(boolean)を使う
Object obj = getLastNonConfigurationInstance();
if (obj != null) {
mAccessory = (UsbAccessory) obj;
openAccessory(mAccessory);
}
}
MainActivity.java
01.19, 2013 Copyright C-LIS CO., LTD. 2011
66
- 67. private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (ACTION_USB_PERMISSION.equals(action)) {
synchronized (this) {
UsbAccessory accessory = UsbManager.getAccessory(intent);
if (intent.getBooleanExtra(
UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
openAccessory(accessory);
} else {
Log.d(LOG_TAG, "permission denied for accessory "
+ accessory);
}
mPermissionRequestPending = false;
}
} else if (UsbManager.ACTION_USB_ACCESSORY_DETACHED.equals(action)) {
UsbAccessory accessory = UsbManager.getAccessory(intent);
if (accessory != null && accessory.equals(mAccessory)) {
closeAccessory();
}
}
}
};
MainActivity.java
01.19, 2013 Copyright C-LIS CO., LTD. 2011
67
- 68. @Override
public void onResume() {
super.onResume();
if (mInputStream != null && mOutputStream != null) {
return;
}
UsbAccessory[] accessories = mUsbManager.getAccessoryList();
UsbAccessory accessory = (accessories == null ? null : accessories[0]);
if (accessory != null) {
if (mUsbManager.hasPermission(accessory)) {
openAccessory(accessory);
} else {
synchronized (mUsbReceiver) {
if (!mPermissionRequestPending) {
mUsbManager.requestPermission(accessory, mPermissionIntent);
mPermissionRequestPending = true;
}
}
}
} else {
Log.d(LOG_TAG, "mAccessory is null");
}
}
MainActivity.java
1.19, 2013 Copyright C-LIS CO., LTD. 2011
68
- 69. private ParcelFileDescriptor mFileDescriptor = null;
private FileInputStream mInputStream = null;
private FileOutputStream mOutputStream = null;
private void openAccessory(UsbAccessory accessory) {
mFileDescriptor = mUsbManager.openAccessory(accessory);
if (mFileDescriptor != null) {
mAccessory = accessory;
FileDescriptor fd = mFileDescriptor.getFileDescriptor();
mInputStream = new FileInputStream(fd);
mOutputStream = new FileOutputStream(fd);
Log.d(LOG_TAG, "accessory opened");
enableControls(true);
} else {
Log.d(LOG_TAG, "accessory open fail");
}
}
private void closeAccessory() {
enableControls(false);
try {
if (mFileDescriptor != null) {
mFileDescriptor.close();
}
} catch (IOException e) {
} finally {
mFileDescriptor = null;
mAccessory = null;
}
Log.d(LOG_TAG, "accessory closed");
}
MainActivity.java
01.19, 2013 Copyright C-LIS CO., LTD. 2011
69
- 70. @Override
public void onPause() {
super.onPause();
closeAccessory();
}
@Override
public void onDestroy() {
unregisterReceiver(mUsbReceiver);
super.onDestroy();
}
MainActivity.java
1.19, 2013 Copyright C-LIS CO., LTD. 2011
70
- 74. public class MainActivity extends Activity implements OnCheckedChangeListener {
// 省略
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mLed = (ToggleButton) findViewById(R.id.toggle_led);
mLed.setOnCheckedChangeListener(this);
// 省略
}
private void setLed(boolean on) {
try {
mOutputStream.write(on ? 0x1 : 0x0);
mOutputStream.flush();
} catch (IOException e) {
Log.e(LOG_TAG, "IOException", e);
}
}
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
switch (buttonView.getId()) {
case R.id.toggle_led:
setLed(isChecked);
break;
}
}
}
MainActivity.java
01.19, 2013 Copyright C-LIS CO., LTD. 2011
74
- 75. Arduino - Android端末からの情報を受信
void loop() {
byte receive_msg[1];
if (acc.isConnected()) {
int len = acc.read(receive_msg, sizeof(receive_msg), 1);
if (len > 0) {
if(receive_msg[0] == 1) {
digitalWrite(PIN_LED, HIGH);
} else {
digitalWrite(PIN_LED, LOW);
}
}
}
}
adk-handson/adk_led
01.19, 2013 Copyright C-LIS CO., LTD. 2011
75
- 77. ADK CDS ILLUMINATE LED
#include <Usb.h>
#include <AndroidAccessory.h>
#define PIN_LED 13
#define PIN_CDS A0
#define ON 1
#define LIGHT_THRESHOLD 700
AndroidAccessory acc("C-LIS CO., LTD.",
"ADK Test",
"This is an ADK test?",
"1.0.0",
"http://www.c-lis.co.jp",
"1234567890");
void setup() {
Serial.begin(115200);
pinMode(PIN_LED, OUTPUT);
pinMode(PIN_CDS, INPUT);
acc.powerOn();
}
adk-handson/cds_illuminate_led
01.19, 2013 Copyright C-LIS CO., LTD. 2011
77
- 78. boolean init_flg = false;
boolean on = false;
int light = 0;
int p = 1;
void loop() {
int state = analogRead(PIN_CDS);
if (acc.isConnected()) {
if (!init_flg) {
analogWrite(PIN_LED, LOW);
init_flg = true;
}
byte receive_msg[1];
byte send_msg[1];
send_msg[0] = state / 4;
acc.write(send_msg, sizeof(send_msg));
int len = acc.read(receive_msg, sizeof(receive_msg), 1);
if (len > 0) {
if(receive_msg[0] == 1) {
analogWrite(PIN_LED, 255);
} else {
analogWrite(PIN_LED, 0);
}
}
} else {
init_flg = false;
// 以下、cds_illuminate_led の重複
}
}
adk-handson/adk_cds_illuminate_led
01.19, 2013 Copyright C-LIS CO., LTD. 2011
78
- 79. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" >
<ToggleButton
android:id="@+id/toggle_led"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:textOff="LED OFF"
android:textOn="LED ON" />
<TextView
android:id="@+id/tv_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="@id/toggle_led"
android:layout_centerHorizontal="true" />
</RelativeLayout>
res/layout/activity_main.xml
01.19, 2013 Copyright C-LIS CO., LTD. 2011
79
- 80. public class MainActivity extends Activity implements OnCheckedChangeListener {
// 省略
private ToggleButton mLed = null;
private TextView mLabel = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mLed = (ToggleButton) findViewById(R.id.toggle_led);
mLed.setEnabled(false);
mLed.setOnCheckedChangeListener(this);
mLabel = (TextView) findViewById(R.id.tv_label);
// 省略
}
MainActivity.java
01.19, 2013 Copyright C-LIS CO., LTD. 2011
80
- 81. private ParcelFileDescriptor mFileDescriptor;
private FileInputStream mInputStream;
private FileOutputStream mOutputStream;
private void openAccessory(UsbAccessory accessory) {
mFileDescriptor = mUsbManager.openAccessory(accessory);
if (mFileDescriptor != null) {
mAccessory = accessory;
FileDescriptor fd = mFileDescriptor.getFileDescriptor();
mInputStream = new FileInputStream(fd);
mOutputStream = new FileOutputStream(fd);
Thread thread = new Thread(mDataReceiveRunnable);
thread.start();
Log.d(LOG_TAG, "accessory opened");
enableControls(true);
} else {
Log.d(LOG_TAG, "accessory open fail");
}
}
private void closeAccessory() {
enableControls(false);
try {
if (mFileDescriptor != null) {
mFileDescriptor.close();
}
} catch (IOException e) {
} finally {
mInputStream = null;
mOutputStream = null;
mFileDescriptor = null;
mAccessory = null;
}
Log.d(LOG_TAG, "accessory closed");
}
MainActivity.java
01.19, 2013 Copyright C-LIS CO., LTD. 2011
81
- 82. private int mCdsValue = 0;
private final Runnable mDataReceiveRunnable = new Runnable() {
public void run() {
int len = 0;
byte[] buff = new byte[1];
try {
while (len >= 0) {
len = mInputStream.read(buff);
mCdsValue = ((int) buff[0] & 0xff);
mHandler.sendEmptyMessage(HANDLE_RECEIVE_MESSAGE);
synchronized (this) {
try {
wait(1000 / 8);
} catch (InterruptedException e) {
}
}
}
} catch (IOException e) {
Log.e(LOG_TAG, "IOException", e);
}
}
};
private static final int HANDLE_RECEIVE_MESSAGE = 0x01;
private final Handler mHandler = new Handler() {
public void handleMessage(Message msg) {
switch (msg.what) {
case HANDLE_RECEIVE_MESSAGE:
mLabel.setText("明るさ: " + mCdsValue);
break;
}
}
};
MainActivity.java
01.19, 2013 Copyright C-LIS CO., LTD. 2011
82
- 84. ADK開発の取り扱い
○ ハードウエアの設計・組み立て
○ Arduino ←→ Android データ通信プロトコル設計
○ Arduinoスケッチの実装
○ Androidアプリの実装
01.19, 2013 Copyright C-LIS CO., LTD. 2011
84
- 85. 参考書籍
Arduinoをはじめよう
今回のハンズオンのArduino編は、ほ
とんどこの書籍をなぞったもの。
後半がArduino言語のリファレンスに
なっているので、中級者以降にもお薦
め。
ADKの話題は無し。
http://www.amazon.co.jp/Arduino%E3%82%92%E3%81%AF%E3%81%98%E3%82%81%E3%82%88%
E3%81%86-Make-PROJECTS-Massimo-Banzi/dp/4873113989
01.19, 2013 Copyright C-LIS CO., LTD. 2011
85
- 86. 参考書籍
Android ADK 組込みプログラミング
完全ガイド
深く知りたいならこの一冊。432pの
ボリュームで、基礎から丁寧に解説。
http://www.amazon.co.jp/Android-%E7%B5%84%E8%BE%BC%E3%81%BF%E3%83%97%E3%
83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E5%AE%8C%E5%85%A8%E3%
82%AC%E3%82%A4%E3%83%89-Smart-Mobile-Developer/dp/4798125938
01.19, 2013 Copyright C-LIS CO., LTD. 2011
86
- 88. ご清聴ありがとうございました。
Arduinoスケッチ+Androidアプリのソースコードは、下記で配布しています
https://github.com/keiji/adk-handson
01.19, 2013 Copyright C-LIS CO., LTD. 2011
88