设计一个实验,要求新意与复杂度,先后顺序(10分钟/组),在规定时间内做好 presentation和演示。
###文档
###1.实验目标 在实验–利用Profiles的特征值进行无线点灯的基础上,simpleBLEPeripheral作为从机,手机(Nexus 5x)作为主机。 实现二者的连接(连接上音乐响起,断开音乐停止),并且从机可以发送数据到手机。
###2.实验工具 CC2540 底板 + IAR 软件 Nexus 5x + Android Studio
###3.实验过程(代码–修改的部分)
####[3.1] 从机模块(CC2540 底板 + IAR 软件) 一、配置文件的修改 [1.0] 从机模块(CC2540 底板 + IAR 软件) [1.1] 增加char6的宏定义(simpleGATTprofile.h) [1.2] 增加char6的UUID(simpleGATTprofile.c的GLOBAL VARIABLES段中) [1.3] 增加char6的配置属性(eGATTprofile.c的Profile Attributes - variables段中) [1.4] 修改属性表(simpleGATTprofile.c) [1.5] 修改特征值的参数函数(simpleGATTprofile.c) [1.6] 修改特征值的读写函数(simpleGATTprofile.c) [1.7] 增加 char6 的通知开关初始化(simpleGATTprofile.c) [1.8] 增加通知开关初始化的实时更新(simpleGATTprofile.c) 二、应用层的修改 [2.1]设置连接密码 [2.2] 修改特征值初始化的数值(simpleBLEPeripheral.c的SimpleBLEPeripheral_Init函数中) [2.3] 修改应用层的回掉函数(simpleBLEPeripheral.c的simpleProfileChangeCB函数中)
#####[3.2] 主机模块(Nexus 5x + Android Studio) 一、新建工程 Android 官方文档说明 Android 4.3 为 BLE 的核心功能提供平台支持和 API,所以新建工程最小SDK为4.3(即API 18).
二、声明权限
1 2 3 4 <uses-permissionandroid:name="android.permission.BLUETOOTH"/> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/> <uses-feature android:name="android.hardware.bluetooth_le" android:required="true"/>
三、检查手机设备是否支持蓝牙(启用蓝牙功能)、获取蓝牙适配器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 // 检查当前手机是否支持ble 蓝牙,如果不支持退出程序 if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) { Toast.makeText(this, R.string.ble_not_supported, Toast.LENGTH_SHORT).show(); finish(); } // 初始化 Bluetooth adapter, 通过蓝牙管理器得到一个参考蓝牙适配器(API必须在以上android4.3或以上和版本) final BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE); mBluetoothAdapter = bluetoothManager.getAdapter(); // 检查设备上是否支持蓝牙 if (mBluetoothAdapter == null) { Toast.makeText(this, R.string.error_bluetooth_not_supported, Toast.LENGTH_SHORT).show(); finish(); return; }
四、开启蓝牙
1 2 3 4 5 6 7 //确保蓝夜在设备上可以开启 if (!mBluetoothAdapter.isEnabled()) { if (!mBluetoothAdapter.isEnabled()) { Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT); } }
五、扫描并显示蓝牙设备
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 // 10秒后停止查找搜索. private static final long SCAN_PERIOD = 10000; private void scanLeDevice(final boolean enable) { if (enable) { // 经过预定扫描期后停止扫描 mHandler.postDelayed(new Runnable() { @Override public void run() { mScanning = false; mBluetoothAdapter.stopLeScan(mLeScanCallback); invalidateOptionsMenu(); } }, SCAN_PERIOD); mScanning = true; mBluetoothAdapter.startLeScan(mLeScanCallback); } else { mScanning = false; mBluetoothAdapter.stopLeScan(mLeScanCallback); } invalidateOptionsMenu(); } // 扫描结果返回. private BluetoothAdapter.LeScanCallback mLeScanCallback = new BluetoothAdapter.LeScanCallback() { @Override public void onLeScan(final BluetoothDevice device, int rssi, byte[] scanRecord) { runOnUiThread(new Runnable() { @Override public void run() { mLeDeviceListAdapter.addDevice(device); mLeDeviceListAdapter.notifyDataSetChanged(); } }); } }; //仅显示设备的名字和地址 static class ViewHolder { TextView deviceName; TextView deviceAddress; }
六、连接到 GATT 服务端
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 private BluetoothManager mBluetoothManager; //蓝牙设备管理器 private BluetoothAdapter mBluetoothAdapter; //蓝牙适配器 private String mBluetoothDeviceAddress; //蓝牙设备地址 private BluetoothGatt mBluetoothGatt; private int mConnectionState = STATE_DISCONNECTED; private static final int STATE_DISCONNECTED = 0; //设备无法连接 private static final int STATE_CONNECTING = 1; //设备正在连接 private static final int STATE_CONNECTED = 2; //设备连接完毕 public final static String ACTION_GATT_CONNECTED = "com.example.bluetooth.le.ACTION_GATT_CONNECTED"; public final static String ACTION_GATT_DISCONNECTED = "com.example.bluetooth.le.ACTION_GATT_DISCONNECTED"; public final static String ACTION_GATT_SERVICES_DISCOVERED = "com.example.bluetooth.le.ACTION_GATT_SERVICES_DISCOVERED"; public final static String ACTION_DATA_AVAILABLE = "com.example.bluetooth.le.ACTION_DATA_AVAILABLE"; public final static String EXTRA_DATA = "com.example.bluetooth.le.EXTRA_DATA"; public final static UUID UUID_HEART_RATE_MEASUREMENT = UUID.fromString(SampleGattAttributes.HEART_RATE_MEASUREMENT); // I通过BLE API的不同类型的回掉方法 // connection change and services discovered. private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { @Override public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) { String intentAction; if (newState == BluetoothProfile.STATE_CONNECTED) { //设备已连接 intentAction = ACTION_GATT_CONNECTED; mConnectionState = STATE_CONNECTED; broadcastUpdate(intentAction); Log.i(TAG, "Connected to GATT server."); // Attempts to discover services after successful connection. Log.i(TAG, "Attempting to start service discovery:" + mBluetoothGatt.discoverServices()); } else if (newState == BluetoothProfile.STATE_DISCONNECTED) { //设备无法连接 intentAction = ACTION_GATT_DISCONNECTED; mConnectionState = STATE_DISCONNECTED; Log.i(TAG, "Disconnected from GATT server."); broadcastUpdate(intentAction); } } //发现新服务端 @Override public void onServicesDiscovered(BluetoothGatt gatt, int status) { if (status == BluetoothGatt.GATT_SUCCESS) { broadcastUpdate(ACTION_GATT_SERVICES_DISCOVERED); } else { Log.w(TAG, "onServicesDiscovered received: " + status); } } //读写特性 public void readCharacteristic(BluetoothGattCharacteristic characteristic) { if (mBluetoothAdapter == null || mBluetoothGatt == null) { Log.w(TAG, "BluetoothAdapter not initialized"); return; } mBluetoothGatt.readCharacteristic(characteristic); }
七、读取 BLE 信息
1 2 3 4 5 final StringBuilder stringBuilder = new StringBuilder(data.length); for(byte byteChar : data) stringBuilder.append(String.format("%02X ", byteChar)); intent.putExtra(EXTRA_DATA, new String(data) + "\n" + stringBuilder.toString()); }
###4.实验结果
###5.感谢 1.老师,您辛苦了,谢谢您。让我上了一门很棒的课(以后周一周二上午没课啦) 2.感谢我给力的队友,合作很愉快 3.感谢博主的分享CC2540 Android