【问题标题】:Continuous and Simultaneous read and write ble data communication连续同步读写数据通信
【发布时间】:2020-01-29 14:04:07
【问题描述】:

我无法将数据从 ble 设备读取到 Android 应用程序。如果我进行连续和同时的数据通信,则任何一种方式都会断开蓝牙连接。

我正在尝试从 ble 设备连续接收 30 字节的数据。我尝试更改 mtu 大小但没有用。如果我开始从应用程序发送 30 字节的数据,则从 ble 设备到应用程序的数据接收将被停止。我无法同时进行数据通信。有人可以帮我连续进行同步数据通信吗?我以 300 毫秒的速率向 ble 设备发送 30 个字节的数据,我必须以 1 秒的速率从 ble 设备接收 30 个字节的数据。我一次能够成功地读取或写入。但不是同时两个。

如果我将 mtu 大小固定为 20,那么我可以同时从 ble 设备读取 20 个字节。但我必须从 ble 设备读取 30 字节的数据。

我也想知道,有没有可能在ble上同时读写而不会丢失数据?

gatt 连接成功时我正在做 gatt.requestMtu(512)。

 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);
                gatt.requestMtu(512);
                Intent i = new Intent("status").putExtra("status",staticConnectionStatus);
                sendBroadcast(i);
            } else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
                intentAction = ACTION_GATT_DISCONNECTED;
                mConnectionState = STATE_DISCONNECTED;
                Intent intent = new Intent("status");
                intent.putExtra("status", staticConnectionStatus);
                sendBroadcast(intent);
                Log.d(TAG, "Disconnected from GATT server.");
                broadcastUpdate(intentAction);
            }
        }

    @Override
    public void onCharacteristicRead(BluetoothGatt gatt,
                                     BluetoothGattCharacteristic characteristic,
                                     int status) {


        if (status == BluetoothGatt.GATT_SUCCESS) {
            Log.d(TAG, "ACTION_DATA_AVAILABLE" + ACTION_DATA_AVAILABLE);
            broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);

            byte[] charValue = characteristic.getValue();
            byte flag = charValue[0];


        } else if (status == BluetoothGatt.GATT_FAILURE) {
            Log.d(TAG, "failed");
        }

        byte[] charValue = characteristic.getValue();
        byte flag = charValue[0];
    }
    @Override
    public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
        //gatt.requestMtu(185);
        broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);
        byte[] charValue = characteristic.getValue();
        byte flag = charValue[0];

    }
};



  public void writeRXCharacteristic(byte[] value) {


        if (mBluetoothGatt != null) {


//            try {
//                Thread.sleep(200);
//            } catch (InterruptedException e) {
//                e.printStackTrace();
//            }

            BluetoothGattService RxService = mBluetoothGatt.getService(UUID.fromString("0000FEFB-0000-1000-8000-00805F9B34FB"));

            if (RxService == null) {
//                showMessage("Rx service not found!");
                broadcastUpdate(DEVICE_DOES_NOT_SUPPORT_UART);
                return;
            }
            BluetoothGattCharacteristic RxChar = RxService.getCharacteristic(UUID.fromString("00000001-0000-1000-8000-008025000000"));

            if (RxChar == null) {
//                showMessage("Rx charateristic not found!");
                broadcastUpdate(DEVICE_DOES_NOT_SUPPORT_UART);
                return;
            }

            RxChar.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_DEFAULT);
            RxChar.setValue(value);

            if (mBluetoothGatt != null) {
                boolean status = mBluetoothGatt.writeCharacteristic(RxChar);
            } else {
                broadcastUpdate(DEVICE_DOES_NOT_SUPPORT_UART);
            }


        } else {
            broadcastUpdate(DEVICE_DOES_NOT_SUPPORT_UART);
        }

    }


//Im notifying the service UUID on services discovered
        BluetoothGattCharacteristic TxChar = RxService.getCharacteristic(UUID.fromString("00000002-0000-1000-8000-008025000000"));
    mBluetoothGatt.setCharacteristicNotification(TxChar, true);

【问题讨论】:

  • 发布您迄今为止尝试或完成的内容,这些信息不足以让任何人帮助您。
  • 您好,我无法从 ble 设备读取数据,因为我每秒从 ble 设备接收 30 字节的数据。我尝试设置 mtu 大小。但是没有用。有人可以帮我在 android@a_local_nobody 中同时读写数据
  • 您使用的是哪种协议?你用的是什么api?
  • 您的代码中很可能存在错误。将其添加到问题中,以便我们为您提供帮助。
  • 我看不到启用 RX 属性通知的代码。这可能是主要的缺失。

标签: java android bluetooth-lowenergy


【解决方案1】:

这里有一些可比较的 Kotlin 代码,它们适用于串行连接并增加了 MTU 大小。我删除了错误处理、日志记录和一些特定于应用程序的代码。

它使用两个特性: - command 特性用于将数据从手机发送到设备。 - feedback特性用于接收设备发送的数据。

注意它的工作方式:

  • 创建工作连接会经历几个阶段,并等待每个阶段完成,然后再开始下一个阶段:连接、发现服务、增加 MTU。
  • 发现服务后,特征将保存在实例变量中。
  • 更改 MTU 回调后连接就绪。
  • 更改 MTU 后启用通知。
  • 通过setCharacteristicNotification 启用通知。无需摆弄描述符。
import android.bluetooth.BluetoothGatt
import android.bluetooth.BluetoothGattCallback
import android.bluetooth.BluetoothGattCharacteristic
import android.bluetooth.BluetoothProfile

class BleConnection(private val device: BluetoothDevice) : Connection {

    private var deviceGatt: BluetoothGatt? = null
    private var commandCharacteristic: BluetoothGattCharacteristic? = null
    private var feedbackCharacteristic: BluetoothGattCharacteristic? = null

    private val gattCallback = object: BluetoothGattCallback() {    
        override fun onConnectionStateChange(gatt: BluetoothGatt?, status: Int, newState: Int) {
            this@BleConnection.onConnectionStateChange(gatt, newState)
        }
        override fun onServicesDiscovered(gatt: BluetoothGatt?, status: Int) {
            this@BleConnection.onServicesDiscovered(gatt)
        }
        override fun onCharacteristicChanged(gatt: BluetoothGatt?, characteristic: BluetoothGattCharacteristic?) {
            this@BleConnection.onCharacteristicChanged(characteristic)
        }
        override fun onMtuChanged(gatt: BluetoothGatt?, mtu: Int, status: Int) {
            this@BleConnection.onMtuChange(gatt)
        }
    }

    // Start to connect
    override fun connect() {
        deviceGatt = device.connectGatt(null, false, gattCallback)
    }

    // The connection state has changed
    private fun onConnectionStateChange(gatt: BluetoothGatt?, newState: Int) {
        when (newState) {
            BluetoothProfile.STATE_CONNECTED -> {
                gatt!!.discoverServices()
            }
            BluetoothProfile.STATE_DISCONNECTED -> {
                ...
            }
        }
    }

    // GATT services have been discovered
    fun onServicesDiscovered(gatt: BluetoothGatt?) {    
        for (service in gatt!!.services) {  
            if (service.uuid == Constants.SERVICE_UUID) {
                feedbackCharacteristic = service.getCharacteristic(Constants.FEEDBACK_CHAR_UUID)
                commandCharacteristic = service.getCharacteristic(Constants.COMMAND_CHAR_UUID)
                 // Increase the MTU
                 gatt.requestMtu(256)
            }
        }
    }

    // The MTU has successfully been changed
    fun onMtuChange(gatt: BluetoothGatt?) {
        gatt!!.setCharacteristicNotification(feedbackCharacteristic, true)
        // ... notify that connection is fully established and ready
    } 

    // Characteristic has been changed (i.e. new data has been received)
    fun onCharacteristicChanged(characteristic: BluetoothGattCharacteristic?) {
        val data = characteristic!!.value
        // ... process the received data
    }

    // may only be called after the connection has been fully established
    // (see onMtuChange() )
    override fun sendData(command: ByteArray) {
        commandCharacteristic!!.value = command
        deviceGatt!!.writeCharacteristic(commandCharacteristic!!)
    }    
}

【讨论】:

  • 你能告诉我30字节的同时数据通信是否可行?我只能从设备读取 20 字节的数据。
  • 我已经成功完成了。但我不知道你的设备的详细信息。它也需要支持它。然后我再次得到这样的印象,即这些设备是/使用 UART 转 BLE 模块(如 HM-10)。如果是这样,您正在处理没有消息或数据包概念的数据流。所以你应该能够加入更小的数据块,直到你收到 30 个字节。
猜你喜欢
  • 1970-01-01
  • 2014-02-03
  • 2023-03-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多