2016年11月22日火曜日
2016年11月18日金曜日
今回はステレオカメラです。この機能自体はROSのパッケージを導入すれば実現可能ですが、よい結果を得るためにはキャリブレーション(校正)をしっかりと行うことがステレオ性能を左右する重要な要素となります。
今回はステレオカメラを良好に動作させるためのキャリブレーション方法について紹介いたします。
2016年11月9日水曜日
2016年10月31日月曜日
2016年10月17日月曜日
ROSで始めるロボティクス(8) ー ロボットのナビゲーションを行う
by 匿名 with 1 comment
前回までの作業でシミュレータ上で動くロボットが準備出来ましたが、今のままでは人が指示を出して動くただのラジコンでしかありません。
ここからは、障害物を避けながら目的の位置まで自立で移動するようにしていきましょう。
まずは地図を用意します。人間でも知らない場所に行く時には事前に地図を確認しますよね。ロボットにも同じように地図が必要になります。
ROSで始めるロボティクス(7) ー ロボットのための二次元mapを作る
by 匿名 with 6 comments
PMD CamBoard pico flexxは3D形状を認識することが可能な非常に小型のToFセンサーです。たまたま別部署用に購入していたものを借りることが出来ましたので、色々試してみました。
このセンサーはとにかく小さいです。ミントケースの半分ぐらいのセンサーで十分な解像度のToFセンサーなので、使い勝手は最高です。早速、ロボットのセンサーに使うため、ROSで使えるように環境を整えていきましょう。
ロボットに使用される定番センサーとしてステレオカメラやレーザーレンジファインダーなどがあります。これらを使うことで、ロボットの周囲の環境を判定し、ロボットの動作を決めることができるようになり、ロボットの自立制御の第一歩となります。
センサーのその他の選択として、マイクロソフト社Kinectやインテル社のRealSenseといった、デプスカメラなどが挙げられます。今回はロボットシミュレータにデプスカメラを追加していきます。
ロボットシミュレータとしてGazeboを使用します。Gazeboはオープンソースで開発されたロボットアプリケーション開発のための動力学シミュレータです。ROSとも連携しており、モータのみならず、ToFセンサやカメラなどもシミュレーション出来ます。
ROSで始めるロボティクス(4) ー シミュレータ上でロボットを動かしてみる
by 匿名 with 6 comments
ROSで始めるロボティクス(3) ー 差動二輪ロボットを準備する
by 匿名 with 6 comments
それではROSの開発環境をインストールしていきます。現在ROSの最新バージョンは「Kinetic Kame」ですが、ここでは「Indigo Igloo」を使用します。というのも、このバージョンはユーザーも多く、サポートする周辺のライブラリも多いため、最初はこのバージョンを選択しておくのが無難だからです。
![]() |
ROSのサイト。http://www.ros.org/ ROSに関する情報はこのサイトを確認しよう。 |
ROSで始めるロボティクス(2) ー ROSのインストールとセットアップ
by 匿名 with 1 comment
皆さんは、「ロボット開発」と聞いてどんなイメージをお持ちでしょうか。「難しい」「専門知識が必要」「大量のプログラミングが必要」そんなイメージの方も多いのではないでしょうか。本連載ではROSを使用することで手軽に「ロボット開発」を行います。ROSではロボットの「シミュレータ」環境も充実しており、「動作するロボット」がなくても開発することが可能です。
本連載ではROSを使って差動二輪ロボットを作成し、シミュレータ上でうごかしていきます。連載を通じてROSのイメージを掴んていくことができます。また実際のToFセンサーも扱います。実際に動くロボットも作成していきます。
2016年9月6日火曜日
UnityもVisual Studioも触ったことのなかった筆者が、Unity公式キャラクターである『ユニティちゃん』を使ってHololens開発をしてみます。その第1回目としてユニティちゃんをHoloLensで表示してみます。
【HoloLens開発】ユニティちゃんとHololensで戯れる - 表示編 -
by 匿名 with No comments
UnityもVisual Studioも触ったことのなかった筆者が、Unity公式キャラクターである『ユニティちゃん』を使ってHololens開発をしてみます。その第1回目としてユニティちゃんをHoloLensで表示してみます。
2016年8月29日月曜日
HoloLensの肝であるHPUチップは○○で出来ていた!?
法人向けHoloLens(Commercial Suite)が発売!追加された新機能とは?等の最新情報に加え、HoloLensに関する基本的な知識を今回の記事で書いていきます。次回、Part3の記事では、遂にHoloLens開発の中身を書いていきますのでご期待ください!
連載目次 |
Part 2: 【HoloLens開発】日本での発売に備える実機開発 - 基礎知識編 - ←本記事
Part 8: 【HoloLens開発】ユニティちゃんとHoloLensで戯れる - シェアリング編2 - (予定)
|
本記事目次
|
【HoloLens開発】日本での発売に備える実機開発 基礎知識編
by 匿名 with No comments
HoloLensの肝であるHPUチップは○○で出来ていた!?
法人向けHoloLens(Commercial Suite)が発売!追加された新機能とは?等の最新情報に加え、HoloLensに関する基本的な知識を今回の記事で書いていきます。次回、Part3の記事では、遂にHoloLens開発の中身を書いていきますのでご期待ください!
連載目次 |
Part 2: 【HoloLens開発】日本での発売に備える実機開発 - 基礎知識編 - ←本記事
Part 8: 【HoloLens開発】ユニティちゃんとHoloLensで戯れる - シェアリング編2 - (予定)
|
本記事目次
|
2016年8月19日金曜日
HoloLensは13m先の壁まで認識できる!?
連載目次 |
Part 1: 【HoloLens開発】日本での発売に備える実機開発 - 体験編 - ←本記事
Part 8: 【HoloLens開発】ユニティちゃんとHoloLensで戯れる - シェアリング編2 - (予定)
|
【HoloLens開発】日本での発売に備える実機開発 体験編
by 匿名 with No comments
HoloLensは13m先の壁まで認識できる!?
連載目次 |
Part 1: 【HoloLens開発】日本での発売に備える実機開発 - 体験編 - ←本記事
Part 8: 【HoloLens開発】ユニティちゃんとHoloLensで戯れる - シェアリング編2 - (予定)
|
2016年6月3日金曜日
はじめに
Googleに買収された Firebase が、Googleサービスに統合されより使いやすく強力になりました。またFirebaseの持つリアルタイム性を生かした IoTプロジェクトも現れてきています。今回はI/Oに発表されずにいた小粒ななIoTプロジェクトに焦点を当て、Googleに統合されたFirebaseの設定やIoTとしての活用方法について紹介いたします。2016年4月25日月曜日
![]() |
http://www.grocerycrud.com/より抜粋 |
エラーチェックをしていなかったりなどそのまま使うには不完全なところもありますので、適宜付け加えて使ってみてください。
2016年3月23日水曜日
はじめに
Linkingを利用したアプリの実装方法について
by 匿名 with No comments
2015年12月10日木曜日
https://www.youtube.com/watch?v=vUbFB1Qypg8 より抜粋
本記事は以下の記事の続きになります。
[第一回] 生活で使えるBLEデバイス
[第二回] 生活で使えるBLEデバイス~ペアリング編~
[第三回] 生活で使えるBLE~アプリ間通信編~
はじめに
私事ですが、最近携帯をGalaxy S6に変更しました。(とても気に入っています)
しかしGalaxy S6は電池の容量が少ないらしく、日常的に使っていても少し電池の減りが早い気がします。
なんとか出来ないかと電池の消費などについて少し調べてみると、充電回数を減らすことや過充電を行わないことが電池の寿命を延ばすことに繋がるようです。
ということで、今回はBLEデバイスを使って少しでも携帯の電池寿命の延命を行いたいと思います。
1. 過充電を防いで電池の寿命を長く保ちたい。
2. 家の中で携帯をすぐ無くすので、居場所を特定したい。
Battery ServiceとImmediate Alertのサービスがあるので、やりたいことは実現出来そうです。
では、実際に作ってみましょう。
実際に作ってみる
BLEデバイスは鳴動可能で、物理ボタンがあるモノにしました。今後もいろいろ遊べそうです。
やりたいこと
1. 過充電を防いで電池の寿命を長く保ちたい。
2. 家の中で携帯をすぐ無くすので、居場所を特定したい。
イメージとしては以下のよう感じです。
1. 過充電防止
2. 携帯の位置通知
BLEデバイスのサービスの確認
まず、購入したBLEデバイスを実際に接続してサービスを確認しましょう。
以下のようなサービスがあるようです。
以下のようなサービスがあるようです。
サービス名
|
UUID
|
説明
|
Generic Access
|
1800
|
デバイス名などの情報取得
|
Immediate Alert
|
1802
|
アラームを鳴らす
|
Link Loss
|
1803
|
接続が切れたときの挙動を設定する
|
Tx Power
|
1804
|
BLEの送信のパワー
|
Battery Service
|
180f
|
バッテリーの状態
|
では、実際に作ってみましょう。
実際に作ってみる
1. 過充電防止
ただし、電源接続している時だけ通知が欲しいので、ACTION_POWER_CONNECTEDを契機に、バッテリーの状態を監視するサービスを常駐させるようにしたいと思います。
構成としては以下の通りです。
図3 過充電防止-構成
では次に、Android側の実装に移ります。
使用するUUID
サービスのImmediate Alertを使用します。
Alert Levelに値(0 or 1or 2)を設定することで通知を行えるようです。
public static final UUID ALERT_SERVICE_UUID = UUID.fromString("00001802-0000-1000-8000-00805f9b34fb"); public static final UUID ALERT_LEVEL_UUID = UUID.fromString("00002a06-0000-1000-8000-00805f9b34fb");
AndroidManifestに宣言
PowerConnectedReciverの実装
電源の接続/切断を受けるレシーバーで、電源接続を契機にバッテリーの監視を行い、電源の切断を契機にバッテリーの監視を終了します。
BattryMonitorServiceからの通知を受けて、BLEデバイスへアラームの鳴動要求を通知します。
過充電を防ぐことで、電池の寿命を長持ちさせましょう。
2. 携帯の位置通知
<service android:name=".power.BatteryMonitorService" android:enabled="true"/> <service android:name=".ble.BluetoothLeService" android:enabled="true"/> <receiver android:name=".power.PowerConnectedReceiver" android:enabled="true" android:exported="false"> <intent-filter> <action android:name="android.intent.action.ACTION_POWER_CONNECTED" /> <action android:name="android.intent.action.ACTION_POWER_DISCONNECTED" /> </intent-filter> </receiver>
電源の接続/切断を受けるレシーバーで、電源接続を契機にバッテリーの監視を行い、電源の切断を契機にバッテリーの監視を終了します。
public class PowerConnectedReceiver extends BroadcastReceiver { private static final String TAG = "BleNotify.PowerConnectedReceiver"; @Override public void onReceive(Context context, Intent intent) { Log.d(TAG, "onReceive : " + intent.getAction()); if (intent.getAction().equals(Intent.ACTION_POWER_CONNECTED)) { Intent serviceIntent = new Intent(context, BatteryMonitorService.class); context.startService(serviceIntent); } else if (intent.getAction().equals(Intent.ACTION_POWER_DISCONNECTED)) { Intent serviceIntent = new Intent(context, BatteryMonitorService.class); context.stopService(serviceIntent); } } }
BatteryMonitorServiceの実装
起動時にバッテリーの状態変化を監視するサービスで、バッテリーが90%以上になるとブロードキャストを送信します。
BLEデバイスへ通知起動時にバッテリーの状態変化を監視するサービスで、バッテリーが90%以上になるとブロードキャストを送信します。
public class BatteryMonitorService extends Service { private static final String TAG = "BleNotify.BatteryMonitorService"; private ChargingOnReceiver mChargingOnReceiver; private boolean isRegisteredChargingReceiver = false; class ChargingOnReceiver extends BroadcastReceiver { public void onReceive(Context context, Intent intent) { int level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1); int scale = intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1); float batteryPct = level / (float)scale; Log.d(TAG, "change battery state : " + batteryPct*100 + "%"); if (batteryPct > 0.9) { Intent notify = new Intent(BluetoothLeService.ACTION_CALL_BATTERY_NOTIFY); LocalBroadcastManager.getInstance(context).sendBroadcast(notify); Log.d(TAG, "send broadcast Notify"); } } } @Override public void onCreate() { super.onCreate(); Log.d(TAG, "onCreate"); mChargingOnReceiver = new ChargingOnReceiver(); IntentFilter filter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED); registerReceiver(mChargingOnReceiver, filter); isRegisteredChargingReceiver = true; } @Override public int onStartCommand(Intent intent, int flags, int startId) { Log.d(TAG, "starting the BatteryMonitorService."); return START_STICKY; } @Override public IBinder onBind(Intent intent) { return null; } @Override public void onDestroy() { Log.d(TAG, "terminate the BatteryMonitorService."); // close process if (isRegisteredChargingReceiver) { unregisterReceiver(mChargingOnReceiver); } super.onDestroy(); } }
BattryMonitorServiceからの通知を受けて、BLEデバイスへアラームの鳴動要求を通知します。
public class BluetoothLeService extends Service { private BluetoothGatt mBluetoothGatt; public final static String ACTION_CALL_BATTERY_NOTIFY = "com.brilliant.blenotify.ble.le.ACTION_CALL_BATTERY_NOTIFY"; 〜中略〜 class GattRequestReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { Log.d(TAG, "onReceive : " + intent.getAction()); if (mBluetoothGatt == null) { Log.e(TAG, "GattService is not connected..."); return; } if (ACTION_CALL_BATTERY_NOTIFY.equals(intent.getAction())) { BluetoothGattCharacteristic c = getCharacteristic(GattAttributes.ALERT_SERVICE_UUID, GattAttributes.ALERT_LEVEL_UUID); if (c != null) { // 1 : vibrator // 2 : sound int level = 2; c.setValue(new byte[]{(byte) level}); mBluetoothGatt.writeCharacteristic(c); } } } } public BluetoothGattCharacteristic getCharacteristic(UUID sid, UUID cid) { BluetoothGattService s = mBluetoothGatt.getService(sid); if (s == null) { Log.w(TAG, "Service NOT found :" + sid.toString()); return null; } BluetoothGattCharacteristic c = s.getCharacteristic(cid); if (c == null) { Log.w(TAG, "Characteristic NOT found :" + cid.toString()); return null; } return c; }このようにすることで、充電中で90パーセントを超えると音を鳴らして通知してくれます。
過充電を防ぐことで、電池の寿命を長持ちさせましょう。
2. 携帯の位置通知
次携帯の位置通知は、BLEデバイス側に物理ボタンがあるので、押された場合に端末側にて鳴動等で位置を知らせます。
今回は端末がバイブレーションするところまで作ります。
構成としては以下の通り。
NotificationをONに設定
今回は端末がバイブレーションするところまで作ります。
構成としては以下の通り。
図4 携帯の位置通知-構成
NotificationをONに設定
まずはBLEデバイスからの通知を受け取る為に設定を行います。
サービス内のキャラクタリスティックスにNotification設定をONにすることで、BLEデバイスからの通知を受けることが出来ます。
サービス内のキャラクタリスティックスにNotification設定をONにすることで、BLEデバイスからの通知を受けることが出来ます。
調べてみると、Battery Service内にある「00002a1b」から始まるキャラクタリスティックスがどうやらNotificationのプロパティを持っているようです。
このキャラクタリスティックスを利用すれば、BLEデバイスからの通知を受けることが出来そうです。
※取得したキャラクタリスティックスはBluetoothGattCharacteristic#getProperties()で確認出来ます。
Blutooth SIGで定義されているBattery ServiceにはBattery Levelしかいないようなので、カスタムで追加されているようです。
このキャラクタリスティックスを利用すれば、BLEデバイスからの通知を受けることが出来そうです。
※取得したキャラクタリスティックスはBluetoothGattCharacteristic#getProperties()で確認出来ます。
Blutooth SIGで定義されているBattery ServiceにはBattery Levelしかいないようなので、カスタムで追加されているようです。
「Power State Lebel(00002a1b)」の参考:
https://groups.google.com/d/msg/android-group-japan/8PffzGRfMms/0gtEcPdjQY8J
public static final UUID BATTERY_SERVICE_UUID = UUID.fromString("0000180f-0000-1000-8000-00805f9b34fb"); public static final UUID BATTERY_LEVEL_STATE_UUID = UUID.fromString("00002a1b-0000-1000-8000-00805f9b34fb");
BluetoothGattCharacteristic c = getCharacteristic(GattAttributes.BATTERY_SERVICE_UUID, GattAttributes.BATTERY_LEVEL_STATE_UUID); if (c != null) { final int charaProp = c.getProperties(); if ((charaProp | BluetoothGattCharacteristic.PROPERTY_NOTIFY) > 0) { Log.d(TAG, "has PROPERTY_NOTIFY"); } mBluetoothGatt.setCharacteristicNotification(c, true); }
通知はボタンを押された時だけに限定します。
通知されたデータの1byte目でボタンの状態がわかります。
public class BluetoothLeService extends Service { public final static String ACTION_FINDME_NOTIFY = "com.brilliant.blenotify.ble.le.ACTION_FINDME_NOTIFY"; 〜中略〜 private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { @Override public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) { UUID uuid = characteristic.getUuid(); Log.e(TAG, "onCharacteristicChanged : " + characteristic.getUuid()); if (GattAttributes.BATTERY_LEVEL_STATE_UUID.equals(uuid)) { // For all other profiles, writes the data formatted in HEX. final byte[] data = characteristic.getValue(); Log.d(TAG, "BATTERY_LEVEL_STATE_UUID received : " + new String(data)); if (data != null && data.length > 0) { // if button pressed. if (data[0] == 1) { Intent intent = new Intent(ACTION_FINDME_NOTIFY); sendBroadcast(intent); Log.d(TAG, "send broadcast ACTION_FINDME_NOTIFY."); } else { Log.d(TAG, "Button is not pressed."); } } } else { broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic); } }FindMeRecieverの実装
BLEデバイスから通知を受けたときの動作を実装します。
public class FindMeReceiver extends BroadcastReceiver{ @Override public void onReceive(Context context, Intent intent) { Vibrator vibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE); long[] pattern = {3000, 1000, 3000, 1000}; vibrator.vibrate(pattern, -1); } }AndrodManifestにも以下を追加しておきます。
<uses-permission android:name="android.permission.VIBRATE"/> <receiver android:name=".findme.FindMeReceiver" android:enabled="true" android:exported="false"/> <intent-filter/> <action android:name="com.brilliant.blenotify.ble.le.ACTION_FINDME_NOTIFY" /> </intent-filter/> </receiver/>
これで、BLEデバイスから通知があったら端末がブルブルと震えてくれるのでどこに置いたかわかるようになりました。
さいごに
以上で「生活で使えるBLEデバイス」シリーズは終了となります。
いかがでしたでしょうか。
BLEの接続方法から実際のデータ通信までの方法を紹介してきましたが、BLEを利用するにあたって多少の苦労がありました。
BLEデバイスの持っているプロファイルに関して、独自に追加されているサービスやキャラクタリスティックスは情報がなかったり、デバイス毎にどのサービスをどの機能に利用しているか等が不明だったりします。(今回で言うところのPower State Lebel)
BluetoothやBLEでの通信のとっつきにくさはこのあたりも関係しているような気がします。
しかし、コツさえ掴んでしまえばアイデア次第で自由なモノ作りが可能な為、様々な分野で活躍できる技術であると思います。
今回までの記事が、そのコツを掴むまでのお手伝いになれば幸いです。
[第四回] 生活で使えるBLEデバイス~実用編~
by 匿名 with No comments
https://www.youtube.com/watch?v=vUbFB1Qypg8 より抜粋
本記事は以下の記事の続きになります。
[第一回] 生活で使えるBLEデバイス
[第二回] 生活で使えるBLEデバイス~ペアリング編~
[第三回] 生活で使えるBLE~アプリ間通信編~
はじめに
私事ですが、最近携帯をGalaxy S6に変更しました。(とても気に入っています)
しかしGalaxy S6は電池の容量が少ないらしく、日常的に使っていても少し電池の減りが早い気がします。
なんとか出来ないかと電池の消費などについて少し調べてみると、充電回数を減らすことや過充電を行わないことが電池の寿命を延ばすことに繋がるようです。
ということで、今回はBLEデバイスを使って少しでも携帯の電池寿命の延命を行いたいと思います。
1. 過充電を防いで電池の寿命を長く保ちたい。
2. 家の中で携帯をすぐ無くすので、居場所を特定したい。
Battery ServiceとImmediate Alertのサービスがあるので、やりたいことは実現出来そうです。
では、実際に作ってみましょう。
実際に作ってみる
BLEデバイスは鳴動可能で、物理ボタンがあるモノにしました。今後もいろいろ遊べそうです。
やりたいこと
1. 過充電を防いで電池の寿命を長く保ちたい。
2. 家の中で携帯をすぐ無くすので、居場所を特定したい。
イメージとしては以下のよう感じです。
1. 過充電防止
2. 携帯の位置通知
BLEデバイスのサービスの確認
まず、購入したBLEデバイスを実際に接続してサービスを確認しましょう。
以下のようなサービスがあるようです。
以下のようなサービスがあるようです。
サービス名
|
UUID
|
説明
|
Generic Access
|
1800
|
デバイス名などの情報取得
|
Immediate Alert
|
1802
|
アラームを鳴らす
|
Link Loss
|
1803
|
接続が切れたときの挙動を設定する
|
Tx Power
|
1804
|
BLEの送信のパワー
|
Battery Service
|
180f
|
バッテリーの状態
|
では、実際に作ってみましょう。
実際に作ってみる
1. 過充電防止
ただし、電源接続している時だけ通知が欲しいので、ACTION_POWER_CONNECTEDを契機に、バッテリーの状態を監視するサービスを常駐させるようにしたいと思います。
構成としては以下の通りです。
図3 過充電防止-構成
では次に、Android側の実装に移ります。
使用するUUID
サービスのImmediate Alertを使用します。
Alert Levelに値(0 or 1or 2)を設定することで通知を行えるようです。
public static final UUID ALERT_SERVICE_UUID = UUID.fromString("00001802-0000-1000-8000-00805f9b34fb"); public static final UUID ALERT_LEVEL_UUID = UUID.fromString("00002a06-0000-1000-8000-00805f9b34fb");
AndroidManifestに宣言
PowerConnectedReciverの実装
電源の接続/切断を受けるレシーバーで、電源接続を契機にバッテリーの監視を行い、電源の切断を契機にバッテリーの監視を終了します。
BattryMonitorServiceからの通知を受けて、BLEデバイスへアラームの鳴動要求を通知します。
過充電を防ぐことで、電池の寿命を長持ちさせましょう。
2. 携帯の位置通知
<service android:name=".power.BatteryMonitorService" android:enabled="true"/> <service android:name=".ble.BluetoothLeService" android:enabled="true"/> <receiver android:name=".power.PowerConnectedReceiver" android:enabled="true" android:exported="false"> <intent-filter> <action android:name="android.intent.action.ACTION_POWER_CONNECTED" /> <action android:name="android.intent.action.ACTION_POWER_DISCONNECTED" /> </intent-filter> </receiver>
電源の接続/切断を受けるレシーバーで、電源接続を契機にバッテリーの監視を行い、電源の切断を契機にバッテリーの監視を終了します。
public class PowerConnectedReceiver extends BroadcastReceiver { private static final String TAG = "BleNotify.PowerConnectedReceiver"; @Override public void onReceive(Context context, Intent intent) { Log.d(TAG, "onReceive : " + intent.getAction()); if (intent.getAction().equals(Intent.ACTION_POWER_CONNECTED)) { Intent serviceIntent = new Intent(context, BatteryMonitorService.class); context.startService(serviceIntent); } else if (intent.getAction().equals(Intent.ACTION_POWER_DISCONNECTED)) { Intent serviceIntent = new Intent(context, BatteryMonitorService.class); context.stopService(serviceIntent); } } }
BatteryMonitorServiceの実装
起動時にバッテリーの状態変化を監視するサービスで、バッテリーが90%以上になるとブロードキャストを送信します。
BLEデバイスへ通知起動時にバッテリーの状態変化を監視するサービスで、バッテリーが90%以上になるとブロードキャストを送信します。
public class BatteryMonitorService extends Service { private static final String TAG = "BleNotify.BatteryMonitorService"; private ChargingOnReceiver mChargingOnReceiver; private boolean isRegisteredChargingReceiver = false; class ChargingOnReceiver extends BroadcastReceiver { public void onReceive(Context context, Intent intent) { int level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1); int scale = intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1); float batteryPct = level / (float)scale; Log.d(TAG, "change battery state : " + batteryPct*100 + "%"); if (batteryPct > 0.9) { Intent notify = new Intent(BluetoothLeService.ACTION_CALL_BATTERY_NOTIFY); LocalBroadcastManager.getInstance(context).sendBroadcast(notify); Log.d(TAG, "send broadcast Notify"); } } } @Override public void onCreate() { super.onCreate(); Log.d(TAG, "onCreate"); mChargingOnReceiver = new ChargingOnReceiver(); IntentFilter filter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED); registerReceiver(mChargingOnReceiver, filter); isRegisteredChargingReceiver = true; } @Override public int onStartCommand(Intent intent, int flags, int startId) { Log.d(TAG, "starting the BatteryMonitorService."); return START_STICKY; } @Override public IBinder onBind(Intent intent) { return null; } @Override public void onDestroy() { Log.d(TAG, "terminate the BatteryMonitorService."); // close process if (isRegisteredChargingReceiver) { unregisterReceiver(mChargingOnReceiver); } super.onDestroy(); } }
BattryMonitorServiceからの通知を受けて、BLEデバイスへアラームの鳴動要求を通知します。
public class BluetoothLeService extends Service { private BluetoothGatt mBluetoothGatt; public final static String ACTION_CALL_BATTERY_NOTIFY = "com.brilliant.blenotify.ble.le.ACTION_CALL_BATTERY_NOTIFY"; 〜中略〜 class GattRequestReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { Log.d(TAG, "onReceive : " + intent.getAction()); if (mBluetoothGatt == null) { Log.e(TAG, "GattService is not connected..."); return; } if (ACTION_CALL_BATTERY_NOTIFY.equals(intent.getAction())) { BluetoothGattCharacteristic c = getCharacteristic(GattAttributes.ALERT_SERVICE_UUID, GattAttributes.ALERT_LEVEL_UUID); if (c != null) { // 1 : vibrator // 2 : sound int level = 2; c.setValue(new byte[]{(byte) level}); mBluetoothGatt.writeCharacteristic(c); } } } } public BluetoothGattCharacteristic getCharacteristic(UUID sid, UUID cid) { BluetoothGattService s = mBluetoothGatt.getService(sid); if (s == null) { Log.w(TAG, "Service NOT found :" + sid.toString()); return null; } BluetoothGattCharacteristic c = s.getCharacteristic(cid); if (c == null) { Log.w(TAG, "Characteristic NOT found :" + cid.toString()); return null; } return c; }このようにすることで、充電中で90パーセントを超えると音を鳴らして通知してくれます。
過充電を防ぐことで、電池の寿命を長持ちさせましょう。
2. 携帯の位置通知
次携帯の位置通知は、BLEデバイス側に物理ボタンがあるので、押された場合に端末側にて鳴動等で位置を知らせます。
今回は端末がバイブレーションするところまで作ります。
構成としては以下の通り。
NotificationをONに設定
今回は端末がバイブレーションするところまで作ります。
構成としては以下の通り。
図4 携帯の位置通知-構成
NotificationをONに設定
まずはBLEデバイスからの通知を受け取る為に設定を行います。
サービス内のキャラクタリスティックスにNotification設定をONにすることで、BLEデバイスからの通知を受けることが出来ます。
サービス内のキャラクタリスティックスにNotification設定をONにすることで、BLEデバイスからの通知を受けることが出来ます。
調べてみると、Battery Service内にある「00002a1b」から始まるキャラクタリスティックスがどうやらNotificationのプロパティを持っているようです。
このキャラクタリスティックスを利用すれば、BLEデバイスからの通知を受けることが出来そうです。
※取得したキャラクタリスティックスはBluetoothGattCharacteristic#getProperties()で確認出来ます。
Blutooth SIGで定義されているBattery ServiceにはBattery Levelしかいないようなので、カスタムで追加されているようです。
このキャラクタリスティックスを利用すれば、BLEデバイスからの通知を受けることが出来そうです。
※取得したキャラクタリスティックスはBluetoothGattCharacteristic#getProperties()で確認出来ます。
Blutooth SIGで定義されているBattery ServiceにはBattery Levelしかいないようなので、カスタムで追加されているようです。
「Power State Lebel(00002a1b)」の参考:
https://groups.google.com/d/msg/android-group-japan/8PffzGRfMms/0gtEcPdjQY8J
public static final UUID BATTERY_SERVICE_UUID = UUID.fromString("0000180f-0000-1000-8000-00805f9b34fb"); public static final UUID BATTERY_LEVEL_STATE_UUID = UUID.fromString("00002a1b-0000-1000-8000-00805f9b34fb");
BluetoothGattCharacteristic c = getCharacteristic(GattAttributes.BATTERY_SERVICE_UUID, GattAttributes.BATTERY_LEVEL_STATE_UUID); if (c != null) { final int charaProp = c.getProperties(); if ((charaProp | BluetoothGattCharacteristic.PROPERTY_NOTIFY) > 0) { Log.d(TAG, "has PROPERTY_NOTIFY"); } mBluetoothGatt.setCharacteristicNotification(c, true); }
通知はボタンを押された時だけに限定します。
通知されたデータの1byte目でボタンの状態がわかります。
public class BluetoothLeService extends Service { public final static String ACTION_FINDME_NOTIFY = "com.brilliant.blenotify.ble.le.ACTION_FINDME_NOTIFY"; 〜中略〜 private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { @Override public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) { UUID uuid = characteristic.getUuid(); Log.e(TAG, "onCharacteristicChanged : " + characteristic.getUuid()); if (GattAttributes.BATTERY_LEVEL_STATE_UUID.equals(uuid)) { // For all other profiles, writes the data formatted in HEX. final byte[] data = characteristic.getValue(); Log.d(TAG, "BATTERY_LEVEL_STATE_UUID received : " + new String(data)); if (data != null && data.length > 0) { // if button pressed. if (data[0] == 1) { Intent intent = new Intent(ACTION_FINDME_NOTIFY); sendBroadcast(intent); Log.d(TAG, "send broadcast ACTION_FINDME_NOTIFY."); } else { Log.d(TAG, "Button is not pressed."); } } } else { broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic); } }FindMeRecieverの実装
BLEデバイスから通知を受けたときの動作を実装します。
public class FindMeReceiver extends BroadcastReceiver{ @Override public void onReceive(Context context, Intent intent) { Vibrator vibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE); long[] pattern = {3000, 1000, 3000, 1000}; vibrator.vibrate(pattern, -1); } }AndrodManifestにも以下を追加しておきます。
<uses-permission android:name="android.permission.VIBRATE"/> <receiver android:name=".findme.FindMeReceiver" android:enabled="true" android:exported="false"/> <intent-filter/> <action android:name="com.brilliant.blenotify.ble.le.ACTION_FINDME_NOTIFY" /> </intent-filter/> </receiver/>
これで、BLEデバイスから通知があったら端末がブルブルと震えてくれるのでどこに置いたかわかるようになりました。
さいごに
以上で「生活で使えるBLEデバイス」シリーズは終了となります。
いかがでしたでしょうか。
BLEの接続方法から実際のデータ通信までの方法を紹介してきましたが、BLEを利用するにあたって多少の苦労がありました。
BLEデバイスの持っているプロファイルに関して、独自に追加されているサービスやキャラクタリスティックスは情報がなかったり、デバイス毎にどのサービスをどの機能に利用しているか等が不明だったりします。(今回で言うところのPower State Lebel)
BluetoothやBLEでの通信のとっつきにくさはこのあたりも関係しているような気がします。
しかし、コツさえ掴んでしまえばアイデア次第で自由なモノ作りが可能な為、様々な分野で活躍できる技術であると思います。
今回までの記事が、そのコツを掴むまでのお手伝いになれば幸いです。
2015年11月27日金曜日
https://linkingiot.com/developer/#developers より引用はじめに
NTTドコモ等の複数の国内企業が連携して「Linking」というプラットフォームが発表されました。
公開されたサイトを見てみると、どうやらLinkingとはIoT(Internet of Things)に関係するらしいフレーズが散りばめられています。
- すべてのモノが、ネットでつながる
- デバイス開発者も、アプリ開発者も、そしてユーザーも。
- Linkingプラットフォームが、つくるをつなぐ。
すべてがつながる「Linking」とは
by 匿名 with No comments
https://linkingiot.com/developer/#developers より引用はじめに
NTTドコモ等の複数の国内企業が連携して「Linking」というプラットフォームが発表されました。
公開されたサイトを見てみると、どうやらLinkingとはIoT(Internet of Things)に関係するらしいフレーズが散りばめられています。
- すべてのモノが、ネットでつながる
- デバイス開発者も、アプリ開発者も、そしてユーザーも。
- Linkingプラットフォームが、つくるをつなぐ。
登録:
投稿 (Atom)