设计一个实验,要求新意与复杂度,先后顺序(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).
二、声明权限
<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"/>
三、检查手机设备是否支持蓝牙(启用蓝牙功能)、获取蓝牙适配器
// 检查当前手机是否支持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;
}
四、开启蓝牙
//确保蓝夜在设备上可以开启
if (!mBluetoothAdapter.isEnabled()) {
if (!mBluetoothAdapter.isEnabled()) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
}
}
五、扫描并显示蓝牙设备
// 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 服务端
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 信息
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