Не получает полный пакет при отправке данных с STM32 на Android через Bluetooth - PullRequest
0 голосов
/ 23 января 2019

Я отправляю данные акселерометра с микроконтроллера STM32 на модуль Bluetooth HC-06, и я разработал приложение для Android для получения данных.

На STM32 я создаю 3-байтовый пакет (uartBuffer), который имеет следующую структуру: [0] counter, [1] xdata, [2] ydata. Затем я отправляю эти данные через UART в модуль HC-06. HAL_UART_Transmit(&uartHand, uartBuffer, 3, 10); // {uartHandle, data, dataSize, timeout}

На Android у меня нет проблем с подключением к устройству и т. Д. Однако, когда я получаю пакет, он не приходит вместе. Он всегда приходит в конце концов (также в правильном порядке), но я мог бы получить пакет только с 1-м байтом, затем пакет с последними 2-мя байтами, а иногда и другие комбинации, как видно на рисунке logcat ниже. Значение, которое всегда увеличивается на единицу (то есть 20, 21, 22 и т. Д.), Является первым байтом пакета, отправленного STM32.

Android logcat

Я проверил это с разными частотами дискретизации до 100 Гц и с более крупными пакетами (до 5 байтов). Я никогда не теряю байтов, но расположение пакетов дополнительно делится на более высокие частоты дискретизации и размеры данных.

Вот класс ConnectedThread, который выполняет чтение данных в методе run.

`
private class ConnectedThread extends Thread {

    private final BluetoothSocket mmBTSocket;
    private final InputStream mInStream;
    private final OutputStream mOutStream;

    public ConnectedThread(BluetoothSocket mSocket) {
        Log.d(TAG, "ConnectedThread: Starting");

        mmBTSocket = mSocket;
        InputStream mTempIn = null;
        OutputStream mTempOut = null;

        try {
            mTempIn = mmBTSocket.getInputStream();
            mTempOut = mmBTSocket.getOutputStream();
        } catch (IOException e) {
            Log.e(TAG, "Failed to get I/O Stream", e);
        }
        mInStream = mTempIn;
        mOutStream = mTempOut;
    }


    public void run(){
        byte[] mBuffer = new byte[3]
        int mBytes = 0; // bytes returned from read
        String mIncomingMessage = new String();
        mIncomingStringBuilder = new StringBuilder();

        while (true) {
            try {
                mIncomingStringBuilder.setLength(0);
                mBytes = mInStream.read(mBuffer, 0, 3);
                for (int i=0; i<mBytes; i++) {
                    mIncomingMessage = String.valueOf(mBuffer[i]);
                    mIncomingStringBuilder.append(mIncomingMessage + ",");
                }
                Log.d(TAG, "run: ConnectedThread - InputStream: " + mIncomingStringBuilder);
                Intent incomingMessageIntent = new Intent("incomingMessage");
                incomingMessageIntent.putExtra("theMessage", mIncomingStringBuilder.toString());
                LocalBroadcastManager.getInstance(mContext).sendBroadcast(incomingMessageIntent);
            } catch (IOException e) {
                Log.e(TAG, "error reading from inputStream, e);
                break;
            }
        }
}
`

Итак, мои вопросы:

1) Почему я не получаю полные пакеты в той же структуре, как они отправляются из STM32? Комментатор здесь упоминает здесь , что:

Соединение Bluetooth является потоковым, а не пакетным. Нет гарантии или попытки сохранить пакетирование. Таким образом, любое количество записей может привести к любому количеству операций чтения, только поток байтов гарантированно будет правильным. Если вам нужно обнаружить пакеты, вам нужно предоставить собственную структуру пакетов для переноса данных.

Это правда? Может ли Bluetooth действительно не сохранить полную структуру пакета? Кто-нибудь может это проверить?

2) Если это так, то каков наилучший метод создания пакета, который для Android легко обнаружить начало и конец? Я предполагаю, что мне нужен байт синхронизации / запуска. Как я могу гарантировать, что этот байт синхронизации не встречается в моих данных акселерометра? Должен ли я использовать 2 последовательных байта синхронизации? Достаточно ли контрольной суммы в конце пакета для обнаружения ошибок в пакете?

3) И наконец, является ли хорошей практикой использование только подключенного нити на Android для получения байта, преобразования в строку и отправки в основное действие, чтобы можно было бесплатно получать следующее как можно быстрее? Тогда в основной деятельности я бы восстановить пакет? Или это будет слишком много работы для основной деятельности?

Заранее спасибо за помощь.

...