我正在开发一款Android应用,可以通过BLE实时从设备中检索数据。
如设备数据表中所述,BLE使用20毫秒的连接间隔。在GATT通知中发送20个用户数据字节(等于每个通道的2个样本和2个字节的运行计数器)。来自设备的数据是乒乓缓冲的,并且基于OSAL定时器每14ms发送多达六个BLE通知分组。采样率设置为160个样本/秒。每个样本为3个字节,并发送3个通道。
每个通知包由20个字节组成,包含以下内容:
测量样本1(原始ADC数据)
测量样本2(原始ADC数据)
之后我绘制了这些数据,但看起来我只得到105左右的采样率,而应该有160个样本/秒。从信号看起来看起来似乎缺少一些样品。
我发布了我在下面使用的代码。我想知道可能是什么原因,代码中是否存在错误或设计缺陷?有没有其他方法可以检索数据?
// This is used to register and get callback methods from Bluetooth adapter
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.");
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);
}
}
//This method gets triggered auto whenever characteristics is read by BT
@Override
public void onCharacteristicRead(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic,
int status) {
if (status == BluetoothGatt.GATT_SUCCESS) {
//on successful read of value, call update function.
broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);
Log.d("SOURCE", "charactersitics read");
}
Log.d("SOURCE", "error reading: " + Integer.toString(status));
}
@Override
public void onCharacteristicChanged(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic) {
broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);
}
};
Intent Sampintent;
private void broadcastUpdate(final String action,
final BluetoothGattCharacteristic characteristic) {
if (UUID_HEART_RATE_MEASUREMENT.equals(characteristic.getUuid())) {
Sampintent = new Intent(action);
final byte[] sigbytes = characteristic.getValue();
Message m = Message.obtain();
Bundle b =new Bundle();
b.putByteArray("bytes",sigbytes);
m.setData(b);
mHandler.sendMessage(m);
}
}
// handler object used to post process the sample read.
private PostSampleRead mHandler = new PostSampleRead();
public class PostSampleRead extends Handler {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
try {
//raw byte array read at a time by BT. rouhgly 20 bytes per packet
final byte[] b = msg.getData().getByteArray("bytes");
// ignoring first two bytes b[0] and b[1] , contain running counter
int b1 = b[2] & 0xff;
int b2 = b[3] & 0xff;
int b3 = b[4] & 0xff;
if (b1 == 255 && b1 == b2 && b2 == b3) {
} else {
// First sample of ch1
byte[] channel1 = {b[2], b[3], b[4]};
// First sample of ch2
byte[] channel2 = {b[5], b[6], b[7]};
// First sample of ch3
byte[] channel3 = {b[8], b[9], b[10]};
//pack three bytes to one value
BigInteger ch1 = new BigInteger(channel1);
BigInteger ch2 = new BigInteger(channel2);
BigInteger ch3 = new BigInteger(channel3);
String c1 = ch1.toString();
String c2 = ch2.toString();
String c3 = ch3.toString();
try {
//sneding all three samples to activity via broadcast.
Sampintent.putExtra(EXTRA_DATA_CH1, c1);
Sampintent.putExtra(EXTRA_DATA_CH2, c2);
Sampintent.putExtra(EXTRA_DATA_CH3, c3);
sendBroadcast(Sampintent);
} catch (Exception e) {
e.printStackTrace();
}
// Second sample of ch1
byte[] channel1_ = {b[11], b[12], b[13]};
// Second sample of ch2
byte[] channel2_ = {b[14], b[15], b[16]};
// Second sample of ch3
byte[] channel3_ = {b[17], b[18], b[19]};
packing 3bytes into one value.
BigInteger ch1_ = new BigInteger(channel1_);
BigInteger ch2_ = new BigInteger(channel2_);
BigInteger ch3_ = new BigInteger(channel3_);
String c1_ = ch1_.toString();
String c2_ = ch2_.toString();
String c3_ = ch3_.toString();
sending to activity via broadcast.
Sampintent.putExtra(EXTRA_DATA_CH1, c1_);
Sampintent.putExtra(EXTRA_DATA_CH2, c2_);
Sampintent.putExtra(EXTRA_DATA_CH3, c3_);
sendBroadcast(Sampintent);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}