Android携帯を使ってBLEモジュールのスキャン」でBLEモジュールのスキャンを行いましたが、今回は、Android携帯を使ってCC2541 SensorTagから温度データを取得します。

温度データ取得アプリの作成

次のように温度データ取得アプリを作成します。

  • 42-45行目にはCC2541 SensorTagのUUIDを設定します。
  • 119行目でCC2541 SensorTagが検出されると、124行目でCC2541 SensorTagへ接続を開始し、126行目でBELスキャンを停止します。
  • 157行目で温度データの取得要求を行います。
  • 170行目で、CC2541 SensorTagの温度計測を開始します。
  • 174行目でCCCD への書き込みを行います。この設定によりNotifyでパソコンに通知(コールバック)されます。
  • 178行目にデータが変化したときに実行されるコールバック関数「onCharacteristicChanged」です。
  • 189行目で受信した温度データを16進表示します。

MainActivity.java

package com.tomosoft.blesensortag;

import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.os.Handler;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothManager;
import android.bluetooth.le.BluetoothLeScanner;
import android.bluetooth.le.ScanCallback;
import android.bluetooth.le.ScanResult;

import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCallback;
import android.bluetooth.BluetoothProfile;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattDescriptor;
import android.bluetooth.BluetoothGattService;


import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.widget.Toast;
import android.widget.TextView;

import android.util.Log;
import java.util.List;
import java.util.UUID;


public class MainActivity extends AppCompatActivity {
    private BluetoothAdapter adapter;
    private BluetoothLeScanner scanner;
    private MyScancallback scancallback;

    private BluetoothGattCallback gattCallback;
    private BluetoothGatt mGatt;
    private BluetoothGattService mService;

    private final String TEMP_SERVICE = "f000aa00-0451-4000-b000-000000000000";
    private final String TEMP_DATA = "f000aa01-0451-4000-b000-000000000000";
    private final String TEMP_REQ = "f000aa02-0451-4000-b000-000000000000";
    private final String NOTIFY_DESCRIPTOR = "00002902-0000-1000-8000-00805f9b34fb";


    private boolean mScanned = false;
    private final int PERMISSION_REQUEST = 100;


    private Handler handler;
    private final int SCAN_PERIOD = 10000;

    private BluetoothDevice device;
    private TextView textView;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // text_view: activity_main.xml の TextView の id
        textView = findViewById(R.id.text_view);

        // テキストを設定
        textView.setText("");

        //BLE対応端末かどうかを調べる。対応していない場合はメッセージを出して終了
        if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
            Toast.makeText(this, R.string.ble_not_supported, Toast.LENGTH_SHORT).show();
            finish();
        }
        //Bluetoothアダプターを初期化する
        BluetoothManager manager = (BluetoothManager)getSystemService(Context.BLUETOOTH_SERVICE);
        adapter = manager.getAdapter();

        //bluetoothの使用が許可されていない場合は許可を求める。
        if( adapter == null || !adapter.isEnabled() ){
            Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            startActivityForResult(intent,PERMISSION_REQUEST);
        }
        else{
            scanner = adapter.getBluetoothLeScanner();
            scancallback = new MyScancallback();

            //スキャニングを10秒後に停止
            handler = new Handler();
            handler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    scanner.stopScan(scancallback);
                    finish();
                }
            }, SCAN_PERIOD);
            //スキャンの開始
            scanner.startScan(scancallback);
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        Log.d("onActivityResult","start");
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == PERMISSION_REQUEST) {
            Log.d("onActivityResult","permission");
        }
    }

    class MyScancallback extends ScanCallback{
        @Override
        public void onScanResult(int callbackType, ScanResult result) {
            Log.d("scanResult","start");
            if( mScanned == true ) return;
            if( result.getDevice() == null ) return;
            textView.append(result.getDevice().getAddress()+" - "+result.getDevice().getName()+"\n");
            if( result.getDevice().getName() == null )return;
            Log.d("onScanResult",result.getDevice().getName() );
            if( result.getDevice().getName().contains("SensorTag") ){
                //BLE端末情報の保持
                device = result.getDevice();
                mScanned = true;
                gattCallback = new MyGattcallback();
                device.connectGatt(getApplicationContext(), false, gattCallback);
                //スキャン停止
                scanner.stopScan(scancallback);
            }
        }
    }

    class MyGattcallback extends BluetoothGattCallback{
        @Override
        public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
            Log.d("onConnect","change");
            if( newState == BluetoothProfile.STATE_CONNECTED){
                gatt.discoverServices();
            }
        }

        @Override
        public void onServicesDiscovered(BluetoothGatt gatt, int status) {
            mGatt = gatt;
            if( status == BluetoothGatt.GATT_SUCCESS ){
                Log.d("onServicesDiscovered","success");
                List<BluetoothGattService> list = gatt.getServices();
                for( BluetoothGattService service : list){
                    Log.d("onServicesDiscovered",service.getUuid().toString());

                    if( service.getUuid().toString().equals(TEMP_SERVICE) ) {
                        Log.d("onServicesDiscovered","success1");
                        mService = service;

                        byte[] bytes = { 1}; // 書き込むバイト列

                        BluetoothGattCharacteristic characteristic1 = service.getCharacteristic(UUID.fromString(TEMP_REQ));
                        characteristic1.setValue(bytes);
                        mGatt.writeCharacteristic(characteristic1);
                    }
                }
            }
        }

        @Override
        public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
            if (status == BluetoothGatt.GATT_SUCCESS) {
                // 成功
                Log.d("onCharacteristicWrite","start");

                //Descriptorの記述
                BluetoothGattCharacteristic characteristicdata = mService.getCharacteristic(UUID.fromString(TEMP_DATA));
                mGatt.setCharacteristicNotification(characteristicdata,true);
                BluetoothGattDescriptor descriptor = characteristicdata.getDescriptor(UUID.fromString(NOTIFY_DESCRIPTOR));
                descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
                mGatt.writeDescriptor(descriptor);
            }
       }
        @Override
        public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
            Log.d("onCharacteristic","change");
            if( characteristic.getUuid().toString().equals(TEMP_DATA) ){
                Log.d("onCharacteristic",characteristic.getUuid().toString());
                final byte[] t = characteristic.getValue();
                Log.d("length",":"+t.length);
                Log.d("value",String.format("%x %x %x %x",t[0],t[1],t[2],t[3]));

                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        textView.append(String.format("%x %x %x %x\n",t[0],t[1],t[2],t[3]));
                    }
                });
            }
        }
    }


}

温度データ取得アプリの実行

Android Studio でスキャンアプリを作成し、ツールバーにある「Run」をクリックします。2,30秒でスキャンアプリがAndroid携帯にロードされて実行され、次のようにSensorTagから取得した温度データがバイト形式で表示されます。温度センサーデータのデータ変換式については、「SensorTagの IR温度センサー「TI TMP006」」を参照してください。

次のようにAndroid Studio上の「logcat」ビューで出力されたログを確認します。

   ・・・
2021-05-27 06:15:35.986 5500-5500/com.tomosoft.blesensortag D/BluetoothAdapter: isLeEnabled(): ON
2021-05-27 06:15:35.992 5500-5513/com.tomosoft.blesensortag D/BluetoothLeScanner: onClientRegistered() - status=0 clientIf=6 mClientIf=0
2021-05-27 06:15:36.081 5500-5523/com.tomosoft.blesensortag I/Adreno-EGL: : EGL 1.4 QUALCOMM build:  (I909a4398ad)
    OpenGL ES Shader Compiler Version: XE031.09.00.04
    Build Date: 05/30/17 Tue
    Local Branch: 
    Remote Branch: 
    Local Patches: 
    Reconstruct Branch: 
2021-05-27 06:15:36.084 5500-5523/com.tomosoft.blesensortag I/OpenGLRenderer: Initialized EGL, version 1.4
2021-05-27 06:15:36.084 5500-5523/com.tomosoft.blesensortag D/OpenGLRenderer: Swap behavior 1
2021-05-27 06:15:36.087 5500-5523/com.tomosoft.blesensortag W/Adreno-ES20: : open failed: errno 13
2021-05-27 06:15:36.326 5500-5500/com.tomosoft.blesensortag D/scanResult: start
2021-05-27 06:15:36.338 5500-5500/com.tomosoft.blesensortag D/onScanResult: SensorTag
2021-05-27 06:15:36.347 5500-5500/com.tomosoft.blesensortag D/BluetoothGatt: connect() - device: B4:99:4C:64:CD:DF, auto: false
2021-05-27 06:15:36.348 5500-5500/com.tomosoft.blesensortag D/BluetoothGatt: registerApp()
2021-05-27 06:15:36.348 5500-5500/com.tomosoft.blesensortag D/BluetoothGatt: registerApp() - UUID=6990d53a-d1fa-4a0b-b89a-1a72262d9f9b
2021-05-27 06:15:36.350 5500-5512/com.tomosoft.blesensortag D/BluetoothGatt: onClientRegistered() - status=0 clientIf=10
2021-05-27 06:15:36.351 5500-5500/com.tomosoft.blesensortag D/BluetoothAdapter: isLeEnabled(): ON
2021-05-27 06:15:37.186 5500-5512/com.tomosoft.blesensortag D/BluetoothGatt: onClientConnectionState() - status=0 clientIf=10 device=B4:99:4C:64:CD:DF
2021-05-27 06:15:37.186 5500-5512/com.tomosoft.blesensortag D/onConnect: change
2021-05-27 06:15:37.186 5500-5512/com.tomosoft.blesensortag D/BluetoothGatt: discoverServices() - device: B4:99:4C:64:CD:DF
2021-05-27 06:15:39.250 5500-5513/com.tomosoft.blesensortag D/BluetoothGatt: onSearchComplete() = Device=B4:99:4C:64:CD:DF Status=0
2021-05-27 06:15:39.250 5500-5513/com.tomosoft.blesensortag D/onServicesDiscovered: success
2021-05-27 06:15:39.250 5500-5513/com.tomosoft.blesensortag D/onServicesDiscovered: 00001800-0000-1000-8000-00805f9b34fb
2021-05-27 06:15:39.250 5500-5513/com.tomosoft.blesensortag D/onServicesDiscovered: 00001801-0000-1000-8000-00805f9b34fb
2021-05-27 06:15:39.250 5500-5513/com.tomosoft.blesensortag D/onServicesDiscovered: 0000180a-0000-1000-8000-00805f9b34fb
2021-05-27 06:15:39.250 5500-5513/com.tomosoft.blesensortag D/onServicesDiscovered: f000aa00-0451-4000-b000-000000000000
2021-05-27 06:15:39.251 5500-5513/com.tomosoft.blesensortag D/onServicesDiscovered: success1
2021-05-27 06:15:39.252 5500-5513/com.tomosoft.blesensortag D/onServicesDiscovered: f000aa10-0451-4000-b000-000000000000
2021-05-27 06:15:39.252 5500-5513/com.tomosoft.blesensortag D/onServicesDiscovered: f000aa20-0451-4000-b000-000000000000
2021-05-27 06:15:39.252 5500-5513/com.tomosoft.blesensortag D/onServicesDiscovered: f000aa30-0451-4000-b000-000000000000
2021-05-27 06:15:39.252 5500-5513/com.tomosoft.blesensortag D/onServicesDiscovered: f000aa40-0451-4000-b000-000000000000
2021-05-27 06:15:39.252 5500-5513/com.tomosoft.blesensortag D/onServicesDiscovered: f000aa50-0451-4000-b000-000000000000
2021-05-27 06:15:39.252 5500-5513/com.tomosoft.blesensortag D/onServicesDiscovered: 0000ffe0-0000-1000-8000-00805f9b34fb
2021-05-27 06:15:39.252 5500-5513/com.tomosoft.blesensortag D/onServicesDiscovered: f000aa60-0451-4000-b000-000000000000
2021-05-27 06:15:39.253 5500-5513/com.tomosoft.blesensortag D/onServicesDiscovered: f000ccc0-0451-4000-b000-000000000000
2021-05-27 06:15:39.253 5500-5513/com.tomosoft.blesensortag D/onServicesDiscovered: f000ffc0-0451-4000-b000-000000000000
2021-05-27 06:15:39.264 5500-5512/com.tomosoft.blesensortag D/onCharacteristicWrite: start
2021-05-27 06:15:39.264 5500-5512/com.tomosoft.blesensortag D/BluetoothGatt: setCharacteristicNotification() - uuid: f000aa01-0451-4000-b000-000000000000 enable: true
2021-05-27 06:15:39.572 5500-5512/com.tomosoft.blesensortag D/onCharacteristic: change
2021-05-27 06:15:39.572 5500-5512/com.tomosoft.blesensortag D/onCharacteristic: f000aa01-0451-4000-b000-000000000000
2021-05-27 06:15:39.572 5500-5512/com.tomosoft.blesensortag D/length: :4
2021-05-27 06:15:39.573 5500-5512/com.tomosoft.blesensortag D/value: ca fe e4 b
2021-05-27 06:15:40.547 5500-5513/com.tomosoft.blesensortag D/onCharacteristic: change
2021-05-27 06:15:40.547 5500-5513/com.tomosoft.blesensortag D/onCharacteristic: f000aa01-0451-4000-b000-000000000000
2021-05-27 06:15:40.547 5500-5513/com.tomosoft.blesensortag D/length: :4
2021-05-27 06:15:40.548 5500-5513/com.tomosoft.blesensortag D/value: bb fe e4 b
2021-05-27 06:15:41.571 5500-5512/com.tomosoft.blesensortag D/onCharacteristic: change
2021-05-27 06:15:41.571 5500-5512/com.tomosoft.blesensortag D/onCharacteristic: f000aa01-0451-4000-b000-000000000000
2021-05-27 06:15:41.571 5500-5512/com.tomosoft.blesensortag D/length: :4
2021-05-27 06:15:41.572 5500-5512/com.tomosoft.blesensortag D/value: be fe e4 b
2021-05-27 06:15:42.546 5500-5513/com.tomosoft.blesensortag D/onCharacteristic: change
2021-05-27 06:15:42.546 5500-5513/com.tomosoft.blesensortag D/onCharacteristic: f000aa01-0451-4000-b000-000000000000
2021-05-27 06:15:42.546 5500-5513/com.tomosoft.blesensortag D/length: :4
2021-05-27 06:15:42.546 5500-5513/com.tomosoft.blesensortag D/value: bc fe e4 b
2021-05-27 06:15:43.570 5500-5512/com.tomosoft.blesensortag D/onCharacteristic: change
2021-05-27 06:15:43.570 5500-5512/com.tomosoft.blesensortag D/onCharacteristic: f000aa01-0451-4000-b000-000000000000
2021-05-27 06:15:43.570 5500-5512/com.tomosoft.blesensortag D/length: :4
2021-05-27 06:15:43.570 5500-5512/com.tomosoft.blesensortag D/value: c2 fe e4 b
2021-05-27 06:15:44.545 5500-5513/com.tomosoft.blesensortag D/onCharacteristic: change
2021-05-27 06:15:44.546 5500-5513/com.tomosoft.blesensortag D/onCharacteristic: f000aa01-0451-4000-b000-000000000000
2021-05-27 06:15:44.546 5500-5513/com.tomosoft.blesensortag D/length: :4
2021-05-27 06:15:44.551 5500-5513/com.tomosoft.blesensortag D/value: bd fe e4 b
2021-05-27 06:15:45.568 5500-5512/com.tomosoft.blesensortag D/onCharacteristic: change
2021-05-27 06:15:45.569 5500-5512/com.tomosoft.blesensortag D/onCharacteristic: f000aa01-0451-4000-b000-000000000000
2021-05-27 06:15:45.569 5500-5512/com.tomosoft.blesensortag D/length: :4
2021-05-27 06:15:45.569 5500-5512/com.tomosoft.blesensortag D/value: b6 fe e8 b
2021-05-27 06:15:45.986 5500-5500/com.tomosoft.blesensortag D/BluetoothAdapter: isLeEnabled(): ON
2021-05-27 06:15:45.986 5500-5500/com.tomosoft.blesensortag D/BluetoothLeScanner: could not find callback wrapper
   ・・・