- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在努力从/向自定义蓝牙低功耗设备读取数据/向其发送数据。我使用的是 Microchip RN4020 蓝牙模块。
我找到的每个教程或示例都解释了如何将您的移动应用程序连接到设备,但我没有找到如何与其实际交互。因此,这正是我可以用我的应用程序做什么和不能做什么。
对于呈现的每个特征,我做了以下操作:
gatt.readCharacteristic(services.get(i).getCharacteristics().get(j));
这是我打印值时的结果:
getStringValue= Mobi_F934��
getStringValue= null
getStringValue= ����d���
getStringValue= 001EC030F934
getStringValue= 2.1
getStringValue= 1.10
getStringValue= 1.10
getStringValue= Microchip
getStringValue= RN4020
getStringValue=
getStringValue=
我不知道这是否重要......
如何读取从我的 BLE 设备发送的数据?
编辑:我的安卓代码
@TargetApi(21)
public class MainActivity extends ActionBarActivity {
private BluetoothAdapter mBluetoothAdapter;
private int REQUEST_ENABLE_BT = 1;
private Handler mHandler;
private static final long SCAN_PERIOD = 10000;
private BluetoothLeScanner mLEScanner;
private ScanSettings settings;
private List<ScanFilter> filters;
private BluetoothGatt mGatt;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mHandler = new Handler();
if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
Toast.makeText(this, "BLE Not Supported",
Toast.LENGTH_SHORT).show();
finish();
}
// Initializes Bluetooth adapter
final BluetoothManager bluetoothManager =
(BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
mBluetoothAdapter = bluetoothManager.getAdapter();
}
@Override
protected void onResume() {
super.onResume();
// Ensures Bluetooth is available on the device and it is enabled. If not,
// displays a dialog requesting user permission to enable Bluetooth.
if (mBluetoothAdapter == null || !mBluetoothAdapter.isEnabled()) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
} else {
if (Build.VERSION.SDK_INT >= 21) {
mLEScanner = mBluetoothAdapter.getBluetoothLeScanner();
settings = new ScanSettings.Builder()
.setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
.build();
filters = new ArrayList<ScanFilter>();
}
scanLeDevice(true);
}
}
@Override
protected void onPause() {
super.onPause();
if (mBluetoothAdapter != null && mBluetoothAdapter.isEnabled()) {
scanLeDevice(false);
}
}
@Override
protected void onDestroy() {
if (mGatt == null) {
return;
}
mGatt.close();
mGatt = null;
super.onDestroy();
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_ENABLE_BT) {
if (resultCode == Activity.RESULT_CANCELED) {
//Bluetooth not enabled.
finish();
return;
}
}
super.onActivityResult(requestCode, resultCode, data);
}
private void scanLeDevice(final boolean enable) {
if (enable) {
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
if (Build.VERSION.SDK_INT < 21) {
mBluetoothAdapter.stopLeScan(mLeScanCallback);
} else {
mLEScanner.stopScan(mScanCallback);
}
}
}, SCAN_PERIOD);
if (Build.VERSION.SDK_INT < 21) {
mBluetoothAdapter.startLeScan(mLeScanCallback);
} else {
mLEScanner.startScan(filters, settings, mScanCallback);
}
} else {
if (Build.VERSION.SDK_INT < 21) {
mBluetoothAdapter.stopLeScan(mLeScanCallback);
} else {
mLEScanner.stopScan(mScanCallback);
}
}
}
private ScanCallback mScanCallback = new ScanCallback() {
@Override
public void onScanResult(int callbackType, ScanResult result) {
Log.e("callbackType", "MAX " + String.valueOf(callbackType));
Log.e("result", "MAX " + result.toString());
BluetoothDevice btDevice = result.getDevice();
connectToDevice(btDevice);
}
@Override
public void onBatchScanResults(List<ScanResult> results) {
for (ScanResult sr : results) {
Log.e("ScanResult - Results", "MAX " + sr.toString());
}
}
@Override
public void onScanFailed(int errorCode) {
Log.e("Scan Failed", "MAX " + "Error Code: " + errorCode);
}
};
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() {
Log.e("onLeScan", "MAX " + device.toString());
connectToDevice(device);
}
});
}
};
public void connectToDevice(BluetoothDevice device) {
if (mGatt == null) {
mGatt = device.connectGatt(this, false, gattCallback);
scanLeDevice(false);// will stop after first device detection
}
}
private final BluetoothGattCallback gattCallback = new BluetoothGattCallback() {
@Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
Log.e("onConnectionStateChange", "MAX " + "Status: " + status);
switch (newState) {
case BluetoothProfile.STATE_CONNECTED:
Log.e("gattCallback", "MAX " + "STATE_CONNECTED");
gatt.discoverServices();
break;
case BluetoothProfile.STATE_DISCONNECTED:
Log.e("gattCallback", "MAX " + "STATE_DISCONNECTED");
break;
default:
Log.e("gattCallback", "MAX " + "STATE_OTHER");
}
}
@Override
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
List<BluetoothGattService> services = gatt.getServices();
Log.e("onServicesDiscovered", "MAX " + services.toString());
/*
for(int i = 0; i < services.size(); i++){
for (int j = 0; j < services.get(i).getCharacteristics().size(); j++){
Log.e("MAX", "i= " + i + " j= " + j);
gatt.readCharacteristic(services.get(i).getCharacteristics().get
(j));
}
}
*/
gatt.readCharacteristic(services.get(0).getCharacteristics().get(0));
}
@Override
public void onCharacteristicRead(BluetoothGatt gatt,
BluetoothGattCharacteristic
characteristic, int status) {
Log.e("onCharacteristicRead", "MAX " + characteristic.toString());
Log.e("onCharacteristicRead", "MAX " +characteristic.getStringValue(0));
//gatt.disconnect();
}
};
}
编辑 2:我的 arduino 代码
#include <SoftwareSerial.h>
/* Set up BT to arduino uno
BT RN4020 Arduino Uno
------------------------------------------------
Red 3.3V
Green GND
Yellow(RX) TX (digital pin 1)
Orange(TX) RX (digital pin 0)
White PIN 8 (!) This is not GND (!)
Blue 3.3V (Ioref can also be used)
*/
/*
-----------------------------------------------------------------------------
-----EXPLANATION PROGRAM-----------------------------------------------------
----------------------------
Eerst wordt de BT module geïnitialiseerd door verschillende commando's door te
sturen. Bij elk commando wordt gecheckt of de BT module het juiste antwoord
heeft teruggestuurd.
De initialisatie moet gebeuren in CMD mode, de CMD/MLDP pin moet laag zijn. Na
de initialisatie checken we tot de BT module is geconnecteerd met het device.
Als de BT module geconnecteerd is zetten we deze uit CMD mode en in MLDP mode
om het verzenden en ontvangen van data te ondersteunen. Daarna zenden we om de
seconde de string 'test' door.
Dit gebeurt zolang het device geconnecteerd is met de BT module.
------------------------------------------------------------------------------
------------------------------------------------------------------------------
-----------------------------
*/
int CMD_MLD_pin = 8; // IO pin for CMD/MLDP pin (LOW --> CMD, HIGH --> MLDP)
void setup() // Initialising BT RN4020
{
pinMode(CMD_MLD_pin, OUTPUT);
digitalWrite(CMD_MLD_pin, LOW); // put CMD/MLDP pin LOW for CMD mode
delay(5000);
/* Initialize Bluetooth */
Serial.begin(115200); // Set up serial connection with required baud rate of
// 115200
delay(1500);
Serial.println("R,1"); //Reboot
while(!Serial.find("Reboot")){} // Waiting until BT RN4020 responds the
required string
while(!Serial.find("CMD")){}
//delay(2000);
Serial.println("SF,1"); // Factory reset
while(!Serial.find("AOK")){}
//delay(1500);
Serial.println("SR,32000000"); // Set device as peripheral
while(!Serial.find("AOK")){}
Serial.println("S-, Mobi"); // Change name of BT
while(!Serial.find("AOK")){}
//delay(1500);
Serial.println("R,1"); // Reboot to make changes effective
while(!Serial.find("Reboot")){}
while(!Serial.find("CMD")){}
//delay(2000);
}
void loop()
{
// Wait until the device responds it is connected
// If the device is connected we will send every second the string 'test'
while(!Serial.find("Connected")){} // Wait until BT RN4020 is connected to a
// device
digitalWrite(CMD_MLD_pin, HIGH); // Go to MLDP to support data stream
while(!Serial.find("MLDP")){} // Wait until BT RN4020 is effectively in MLDP
// mode
delay(500);
while (!Serial.find("Connection End")) // Send string to BTRN4020 while the
// BT RN4020 is conected to a device
{
Serial.println("test");
delay(1000);
}
}
最佳答案
在提出问题几个月后,我设法解决了我的问题。那时我忘了分享我的解决方案。无论如何,迟到总比不到好!
这是我在测试基于 BLE 的 android - TI sensortag 通信时编写的一些代码。
一个完整的例子可以在 https://github.com/maxhelskens/SmergyBicycle 找到。
package com.example.max.smergy;
import android.annotation.TargetApi;
import android.app.Activity;
import android.app.ProgressDialog;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCallback;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattDescriptor;
import android.bluetooth.BluetoothGattService;
import android.bluetooth.BluetoothManager;
import android.bluetooth.BluetoothProfile;
import android.bluetooth.le.BluetoothLeScanner;
import android.bluetooth.le.ScanCallback;
import android.bluetooth.le.ScanFilter;
import android.bluetooth.le.ScanResult;
import android.bluetooth.le.ScanSettings;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.util.SparseArray;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.TextView;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
@TargetApi(21)
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
private static final String DEVICE_NAME = "SensorTag";
/* Humidity Service */
private static final UUID HUMIDITY_SERVICE = UUID.fromString("F000AA20-0451-4000-B000-000000000000");
private static final UUID HUMIDITY_DATA_CHAR = UUID.fromString("f000aa21-0451-4000-b000-000000000000");
private static final UUID HUMIDITY_CONFIG_CHAR = UUID.fromString("f000aa22-0451-4000-b000-000000000000");
/* magneto Service */
private static final UUID MAGNETO_SERVICE = UUID.fromString("F000AA80-0451-4000-B000-000000000000");
private static final UUID MAGNETO_DATA_CHAR = UUID.fromString("f000aa81-0451-4000-b000-000000000000");
private static final UUID MAGNETO_CONFIG_CHAR = UUID.fromString("f000aa82-0451-4000-b000-000000000000");
/* Barometric Pressure Service */
private static final UUID PRESSURE_SERVICE = UUID.fromString("f000aa40-0451-4000-b000-000000000000");
private static final UUID PRESSURE_DATA_CHAR = UUID.fromString("f000aa41-0451-4000-b000-000000000000");
private static final UUID PRESSURE_CONFIG_CHAR = UUID.fromString("f000aa42-0451-4000-b000-000000000000");
private static final UUID PRESSURE_CAL_CHAR = UUID.fromString("f000aa43-0451-4000-b000-000000000000");
/* Client Configuration Descriptor */
private static final UUID CONFIG_DESCRIPTOR = UUID.fromString("00002902-0000-1000-8000-00805f9b34fb");
private BluetoothAdapter mBluetoothAdapter;
private SparseArray<BluetoothDevice> mDevices;
private BluetoothGatt mGatt;
private TextView mTemperature, mHumidity, mPressure;
private ProgressDialog mProgress;
private int REQUEST_ENABLE_BT = 1;
private BluetoothLeScanner mLEScanner;
private ScanSettings settings;
private List<ScanFilter> filters;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setProgressBarIndeterminate(true);
// Find the toolbar view inside the activity layout
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
// Sets the Toolbar to act as the ActionBar for this Activity window.
// Make sure the toolbar exists in the activity and is not null
setSupportActionBar(toolbar);
/*
* We are going to display the results in some text fields
*/
mTemperature = (TextView) findViewById(R.id.text_temperature);
mHumidity = (TextView) findViewById(R.id.text_humidity);
mPressure = (TextView) findViewById(R.id.text_pressure);
//Check if BLE is supported
if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
Toast.makeText(this, "BLE Not Supported",
Toast.LENGTH_SHORT).show();
finish();
}
final BluetoothManager bluetoothManager =
(BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
mBluetoothAdapter = bluetoothManager.getAdapter();
mDevices = new SparseArray<BluetoothDevice>();
/*
* A progress dialog will be needed while the connection process is
* taking place
*/
mProgress = new ProgressDialog(this);
mProgress.setIndeterminate(true);
mProgress.setCancelable(false);
}
@Override
protected void onResume() {
super.onResume();
if (mBluetoothAdapter == null || !mBluetoothAdapter.isEnabled()) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
} else {
if (Build.VERSION.SDK_INT >= 21) {
mLEScanner = mBluetoothAdapter.getBluetoothLeScanner();
settings = new ScanSettings.Builder()
.setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
.build();
filters = new ArrayList<ScanFilter>();
}
}
clearDisplayValues();
}
@Override
protected void onPause() {
super.onPause();
//Make sure dialog is hidden
mProgress.dismiss();
//Cancel any scans in progress
mHandler.removeCallbacks(mStopRunnable);
mHandler.removeCallbacks(mStartRunnable);
if (Build.VERSION.SDK_INT < 21) {
mBluetoothAdapter.stopLeScan(mLeScanCallback);
} else {
mLEScanner.stopScan(mScanCallback);
}
}
@Override
protected void onStop() {
super.onStop();
//Disconnect from any active tag connection
if (mGatt != null) {
mGatt.close();
mGatt = null;
}
}
@Override
protected void onDestroy() {
if (mGatt == null) {
return;
}
mGatt.close();
mGatt = null;
super.onDestroy();
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_ENABLE_BT) {
if (resultCode == Activity.RESULT_CANCELED) {
//Bluetooth not enabled.
finish();
return;
}
}
super.onActivityResult(requestCode, resultCode, data);
}
// Menu icons are inflated just as they were with actionbar
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
//Add any device elements we've discovered to the overflow menu
for (int i=0; i < mDevices.size(); i++) {
BluetoothDevice device = mDevices.valueAt(i);
menu.add(0, mDevices.keyAt(i), 0, device.getName());
}
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.bluetoothSearch:
mDevices.clear();
startScan();
//scanLeDevice(true);
return true;
default:
//Obtain the discovered device to connect with
BluetoothDevice device = mDevices.get(item.getItemId());
Log.i(TAG, "Connecting to " + device.getName());
/*
* Make a connection with the device
*/
connectToDevice(device);
//Display progress UI
mHandler.sendMessage(Message.obtain(null, MSG_PROGRESS, "Connecting to " + device.getName() + "..."));
return super.onOptionsItemSelected(item);
}
}
private void clearDisplayValues() {
mTemperature.setText("---");
mHumidity.setText("---");
mPressure.setText("---");
}
private Runnable mStopRunnable = new Runnable() {
@Override
public void run() {
stopScan();
}
};
private Runnable mStartRunnable = new Runnable() {
@Override
public void run() {
startScan();
}
};
private void startScan() {
if (Build.VERSION.SDK_INT < 21) {
mBluetoothAdapter.startLeScan(mLeScanCallback);
} else {
mLEScanner.startScan(filters, settings, mScanCallback);
}
setProgressBarIndeterminateVisibility(true);
mHandler.postDelayed(mStopRunnable, 2500);
}
private void stopScan() {
if (Build.VERSION.SDK_INT < 21) {
mBluetoothAdapter.stopLeScan(mLeScanCallback);
} else {
mLEScanner.stopScan(mScanCallback);
}
setProgressBarIndeterminateVisibility(false);
}
private BluetoothAdapter.LeScanCallback mLeScanCallback =
new BluetoothAdapter.LeScanCallback() {
@Override
public void onLeScan(final BluetoothDevice device, int rssi, byte[] scanRecord) {
Log.i("onLeScan", device.toString());
mDevices.put(device.hashCode(), device);
//Update the overflow menu
invalidateOptionsMenu();
}
};
/*
private void scanLeDevice(final boolean enable) {
if (enable) {
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
if (Build.VERSION.SDK_INT < 21) {
mBluetoothAdapter.stopLeScan(mLeScanCallback);
} else {
mLEScanner.stopScan(mScanCallback);
}
}
}, SCAN_PERIOD);
if (Build.VERSION.SDK_INT < 21) {
mBluetoothAdapter.startLeScan(mLeScanCallback);
} else {
mLEScanner.startScan(filters, settings, mScanCallback);
}
} else {
if (Build.VERSION.SDK_INT < 21) {
mBluetoothAdapter.stopLeScan(mLeScanCallback);
} else {
mLEScanner.stopScan(mScanCallback);
}
}
}
*/
private ScanCallback mScanCallback = new ScanCallback() {
@Override
public void onScanResult(int callbackType, ScanResult result) {
Log.i("callbackType", String.valueOf(callbackType));
Log.i("result", result.toString());
BluetoothDevice btDevice = result.getDevice();
mDevices.put(btDevice.hashCode(), btDevice);
//Update the overflow menu
invalidateOptionsMenu();
}
@Override
public void onBatchScanResults(List<ScanResult> results) {
for (ScanResult sr : results) {
Log.i("ScanResult - Results", sr.toString());
}
}
@Override
public void onScanFailed(int errorCode) {
Log.e("Scan Failed", "Error Code: " + errorCode);
}
};
public void connectToDevice(BluetoothDevice device) {
if (mGatt == null) {
mGatt = device.connectGatt(this, false, gattCallback);
stopScan();
}
}
/*
* In this callback, we've created a bit of a state machine to enforce that only
* one characteristic be read or written at a time until all of our sensors
* are enabled and we are registered to get notifications.
*/
private final BluetoothGattCallback gattCallback = new BluetoothGattCallback() {
/* State Machine Tracking */
private int mState = 0;
private void reset() { mState = 0; }
private void advance() { mState++; }
/*
* Send an enable command to each sensor by writing a configuration
* characteristic. This is specific to the SensorTag to keep power
* low by disabling sensors you aren't using.
*/
private void enableNextSensor(BluetoothGatt gatt) {
BluetoothGattCharacteristic characteristic;
switch (mState) {
/*
case 0:
Log.d(TAG, "Enabling pressure cal");
characteristic = gatt.getService(PRESSURE_SERVICE)
.getCharacteristic(PRESSURE_CONFIG_CHAR);
characteristic.setValue(new byte[] {0x02});
break;
case 1:
Log.d(TAG, "Enabling pressure");
characteristic = gatt.getService(PRESSURE_SERVICE)
.getCharacteristic(PRESSURE_CONFIG_CHAR);
characteristic.setValue(new byte[] {0x01});
break; */
case 0:
Log.d(TAG, "Enabling humidity");
characteristic = gatt.getService(HUMIDITY_SERVICE)
.getCharacteristic(HUMIDITY_CONFIG_CHAR);
characteristic.setValue(new byte[] {0x01});
break;
case 1:
Log.d(TAG, "Enabling magneto");
characteristic = gatt.getService(MAGNETO_SERVICE)
.getCharacteristic(MAGNETO_CONFIG_CHAR);
characteristic.setValue(new byte[] {(byte)0x7F, (byte)0x00});
break;
default:
mHandler.sendEmptyMessage(MSG_DISMISS);
Log.i(TAG, "All Sensors Enabled");
return;
}
gatt.writeCharacteristic(characteristic);
}
/*
* Read the data characteristic's value for each sensor explicitly
*/
private void readNextSensor(BluetoothGatt gatt) {
BluetoothGattCharacteristic characteristic;
switch (mState) {
/*
case 0:
Log.d(TAG, "Reading pressure cal");
characteristic = gatt.getService(PRESSURE_SERVICE)
.getCharacteristic(PRESSURE_CAL_CHAR);
break;
case 1:
Log.d(TAG, "Reading pressure");
characteristic = gatt.getService(PRESSURE_SERVICE)
.getCharacteristic(PRESSURE_DATA_CHAR);
break;*/
case 0:
Log.d(TAG, "Reading humidity");
characteristic = gatt.getService(HUMIDITY_SERVICE)
.getCharacteristic(HUMIDITY_DATA_CHAR);
break;
case 1:
Log.d(TAG, "Reading magneto");
characteristic = gatt.getService(MAGNETO_SERVICE)
.getCharacteristic(MAGNETO_DATA_CHAR);
break;
default:
mHandler.sendEmptyMessage(MSG_DISMISS);
Log.i(TAG, "All Sensors Enabled");
return;
}
gatt.readCharacteristic(characteristic);
}
/*
* Enable notification of changes on the data characteristic for each sensor
* by writing the ENABLE_NOTIFICATION_VALUE flag to that characteristic's
* configuration descriptor.
*/
private void setNotifyNextSensor(BluetoothGatt gatt) {
BluetoothGattCharacteristic characteristic;
switch (mState) {
/*
case 0:
Log.d(TAG, "Set notify pressure cal");
characteristic = gatt.getService(PRESSURE_SERVICE)
.getCharacteristic(PRESSURE_CAL_CHAR);
break;
case 1:
Log.d(TAG, "Set notify pressure");
characteristic = gatt.getService(PRESSURE_SERVICE)
.getCharacteristic(PRESSURE_DATA_CHAR);
break;*/
case 0:
Log.d(TAG, "Set notify humidity");
characteristic = gatt.getService(HUMIDITY_SERVICE)
.getCharacteristic(HUMIDITY_DATA_CHAR);
break;
case 1:
Log.d(TAG, "Set notify magneto");
characteristic = gatt.getService(MAGNETO_SERVICE)
.getCharacteristic(MAGNETO_DATA_CHAR);
break;
default:
mHandler.sendEmptyMessage(MSG_DISMISS);
Log.i(TAG, "All Sensors Enabled");
return;
}
//Enable local notifications
gatt.setCharacteristicNotification(characteristic, true);
//Enabled remote notifications
BluetoothGattDescriptor desc = characteristic.getDescriptor(CONFIG_DESCRIPTOR);
desc.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
gatt.writeDescriptor(desc);
}
@Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
Log.i("onConnectionStateChange", "Status: " + status);
if (status == BluetoothGatt.GATT_SUCCESS && newState == BluetoothProfile.STATE_CONNECTED) {
/*
* Once successfully connected, we must next discover all the services on the
* device before we can read and write their characteristics.
*/
gatt.discoverServices();
mHandler.sendMessage(Message.obtain(null, MSG_PROGRESS, "Discovering Services..."));
} else if (status == BluetoothGatt.GATT_SUCCESS && newState == BluetoothProfile.STATE_DISCONNECTED) {
/*
* If at any point we disconnect, send a message to clear the weather values
* out of the UI
*/
mHandler.sendEmptyMessage(MSG_CLEAR);
} else if (status != BluetoothGatt.GATT_SUCCESS) {
/*
* If there is a failure at any stage, simply disconnect
*/
gatt.close();
}
}
@Override
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
List<BluetoothGattService> services = gatt.getServices();
Log.i("onServicesDiscovered", services.toString());
mHandler.sendMessage(Message.obtain(null, MSG_PROGRESS, "Enabling Sensors..."));
/*
* With services discovered, we are going to reset our state machine and start
* working through the sensors we need to enable
*/
reset();
enableNextSensor(gatt);
}
@Override
public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
Log.i("onCharacteristicRead", characteristic.toString());
//For each read, pass the data up to the UI thread to update the display
if (HUMIDITY_DATA_CHAR.equals(characteristic.getUuid())) {
mHandler.sendMessage(Message.obtain(null, MSG_HUMIDITY, characteristic));
}
if (MAGNETO_DATA_CHAR.equals(characteristic.getUuid())) {
mHandler.sendMessage(Message.obtain(null, MSG_MAGNETO, characteristic));
}
if (PRESSURE_DATA_CHAR.equals(characteristic.getUuid())) {
mHandler.sendMessage(Message.obtain(null, MSG_PRESSURE, characteristic));
}
if (PRESSURE_CAL_CHAR.equals(characteristic.getUuid())) {
mHandler.sendMessage(Message.obtain(null, MSG_PRESSURE_CAL, characteristic));
}
//After reading the initial value, next we enable notifications
setNotifyNextSensor(gatt);
}
@Override
public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
//After writing the enable flag, next we read the initial value
readNextSensor(gatt);
}
@Override
public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
/*
* After notifications are enabled, all updates from the device on characteristic
* value changes will be posted here. Similar to read, we hand these up to the
* UI thread to update the display.
*/
if (HUMIDITY_DATA_CHAR.equals(characteristic.getUuid())) {
mHandler.sendMessage(Message.obtain(null, MSG_HUMIDITY, characteristic));
}
if (MAGNETO_DATA_CHAR.equals(characteristic.getUuid())) {
mHandler.sendMessage(Message.obtain(null, MSG_MAGNETO, characteristic));
}
if (PRESSURE_DATA_CHAR.equals(characteristic.getUuid())) {
mHandler.sendMessage(Message.obtain(null, MSG_PRESSURE, characteristic));
}
if (PRESSURE_CAL_CHAR.equals(characteristic.getUuid())) {
mHandler.sendMessage(Message.obtain(null, MSG_PRESSURE_CAL, characteristic));
}
}
@Override
public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
//Once notifications are enabled, we move to the next sensor and start over with enable
advance();
enableNextSensor(gatt);
}
@Override
public void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status) {
Log.d(TAG, "Remote RSSI: " + rssi);
}
private String connectionState(int status) {
switch (status) {
case BluetoothProfile.STATE_CONNECTED:
return "Connected";
case BluetoothProfile.STATE_DISCONNECTED:
return "Disconnected";
case BluetoothProfile.STATE_CONNECTING:
return "Connecting";
case BluetoothProfile.STATE_DISCONNECTING:
return "Disconnecting";
default:
return String.valueOf(status);
}
}
};
/*
* We have a Handler to process event results on the main thread
*/
private static final int MSG_HUMIDITY = 101;
private static final int MSG_PRESSURE = 102;
private static final int MSG_PRESSURE_CAL = 103;
private static final int MSG_MAGNETO = 104;
private static final int MSG_PROGRESS = 201;
private static final int MSG_DISMISS = 202;
private static final int MSG_CLEAR = 301;
private Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
BluetoothGattCharacteristic characteristic;
switch (msg.what) {
case MSG_HUMIDITY:
characteristic = (BluetoothGattCharacteristic) msg.obj;
if (characteristic.getValue() == null) {
Log.w(TAG, "Error obtaining humidity value");
return;
}
updateHumidityValues(characteristic);
break;
case MSG_MAGNETO:
characteristic = (BluetoothGattCharacteristic) msg.obj;
if (characteristic.getValue() == null) {
Log.w(TAG, "Error obtaining magneto value");
return;
}
updateMagnetoValues(characteristic);
break;
case MSG_PRESSURE:
characteristic = (BluetoothGattCharacteristic) msg.obj;
if (characteristic.getValue() == null) {
Log.w(TAG, "Error obtaining pressure value");
return;
}
updatePressureValue(characteristic);
break;
case MSG_PRESSURE_CAL:
characteristic = (BluetoothGattCharacteristic) msg.obj;
if (characteristic.getValue() == null) {
Log.w(TAG, "Error obtaining cal value");
return;
}
updatePressureCals(characteristic);
break;
case MSG_PROGRESS:
mProgress.setMessage((String) msg.obj);
if (!mProgress.isShowing()) {
mProgress.show();
}
break;
case MSG_DISMISS:
mProgress.hide();
break;
case MSG_CLEAR:
clearDisplayValues();
break;
}
}
};
/* Methods to extract sensor data and update the UI */
private void updateHumidityValues(BluetoothGattCharacteristic characteristic) {
double humidity = SensorTagData.extractHumidity(characteristic);
mHumidity.setText(String.format("%.0f%%", humidity));
}
ArrayList<Double> magnets = new ArrayList<>();
double average = 0;
int count = -1;
int wait5 = 0;
private void updateMagnetoValues(BluetoothGattCharacteristic characteristic) {
double magnet = SensorTagData.extractMagnetoX(characteristic);
Log.e("MAGNETO", "" + magnet);
magnet = Math.abs(magnet);
if (wait5 == 0) {
if (magnet > average + 300 || magnet < average - 300) {
wait5 = 6;
count ++;
mPressure.setText("" + count);
}
}
else {
wait5 --;
}
if (magnets.size() >= 5) {
magnets.remove(0);
}
magnets.add(magnet);
double sum = 0;
for (int i = 0; i < magnets.size(); i++) {
sum += magnets.get(i);
}
average = sum/magnets.size();
average = magnets.get(2);
//mHumidity.setText(String.format("%.0f%%", humidity));
}
private int[] mPressureCals;
private void updatePressureCals(BluetoothGattCharacteristic characteristic) {
mPressureCals = SensorTagData.extractCalibrationCoefficients(characteristic);
}
private void updatePressureValue(BluetoothGattCharacteristic characteristic) {
if (mPressureCals == null) return;
double pressure = SensorTagData.extractBarometer(characteristic, mPressureCals);
double temp = SensorTagData.extractBarTemperature(characteristic, mPressureCals);
mTemperature.setText(String.format("%.1f\u00B0C", temp));
mPressure.setText(String.format("%.2f", pressure));
}
}
关于Android 和低功耗蓝牙 (BLE),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35728193/
具体的软硬件实现点击 http://mcu-ai.com/ MCU-AI技术网页_MCU-AI人工智能 卷积神经网络(CNN)通过从原始数据中自动学习层次特征表示,在图像识别任务中取得了巨大成功。虽然
具体的软硬件实现点击 http://mcu-ai.com/ MCU-AI技术网页_MCU-AI人工智能 血压的测量和预测是心脏病患者和有心脏问题的人的一个重要条件,应该保持持续的控制。在这项研究中,基
具体的软硬件实现点击 http://mcu-ai.com/ MCU-AI技术网页_MCU-AI人工智能 心血管疾病是最严重的死亡原因之一,每年在全世界造成严重的生命损失。持续监测血压似乎是最可行的选择
大家好,我是痞子衡,是正经搞技术的痞子。今天痞子衡给大家介绍的是 恩智浦MCX系列MCU的新品MCXN947 。 自 2015 年恩智浦和飞思卡尔合并成新恩智浦之后,关于它们各
我正在开发一个应用程序,该应用程序接受语音输入,并将该输入与 list 中的已知项目进行匹配。 list 中的每个项目都有一个别名列表,以便长标题的项目可以与较短的名称相匹配。 例如: class P
两个双模蓝牙设备连接时,必须使用EDR,不能并联使用LE。然后必须通过 EDR 链路传输 BT 低功耗 GATT 配置文件。这是我从规范中读到的内容。 但是 iOS EDR 堆栈(在没有 MFi 许可
我正在尝试为 S3 开发蓝牙 4.0 应用程序。问题是,手机的行为就像它甚至没有蓝牙 4.0。它不会发现 4.0 设备,并且无法通过 4.0 设备发现。我在手机设置和应用程序中都尝试过,使用 Broa
我正在寻找一种与 Adafruit bluefruit LE(nRF8001 芯片组)板进行交互的方法,在 Windows 桌面应用程序中使用 c#(据我所知,我无法使用 Windows.Device
我是一名优秀的程序员,十分优秀!