У меня есть код, который я использую для передачи данных датчика с ESP32 через Bluetooth Low Energy на Raspberry Pi. Я заметил, что данные, которые я получаю на приемнике после первых 4 байтов, неверны и содержат случайные значения, но это не влияет на каждый пакет. Я использую FreeRTOS для работы с несколькими датчиками и BLE одновременно.
Я подтвердил, что получаю пакеты с неверными данными после первых 4 байтов в Wireshark. В приведенном ниже коде я также распечатываю данные, которые собираюсь передать, и то, что я вижу на этом последовательном мониторе Arduino, несовместимо с тем, что я вижу в Wireshark, когда я ищу поврежденные пакеты, то есть на последовательном мониторе отображаются данные, которые я ожидаю увидеть
Я пытался обновить библиотеки BLE, увеличив размер стека для моих задач FreeRTOS на случай переполнения стека. Я также попытался сравнить пакеты, которые я вижу на Wireshark, с данными, которые я передаю до и после моих вызовов bletify, и мои данные в буфере выглядят нормально, но пакеты, которые я получаю на Wireshark, неверны. Я также попытался увеличить размер MTU на случай, если мои пакеты были слишком большими. Мое лучшее предположение на данный момент заключается в том, что это как-то связано с ОСРВ, потому что я следовал примерам https://github.com/nkolban/esp32-snippets, и на форумах, посвященных функциональности BLE ESP32.
Любая помощь или указатели в правильном направлении будет принята с благодарностью.
Вот так я настраиваю Сервис и Характеристики BLE
void init_BLE() {
Serial.println("Starting setup");
btStart();
BLEDevice::init("esp32");
BLEDevice::setMTU(64); // debug with larger MTU size
bleServer = BLEDevice::createServer();
bleServer->setCallbacks(new MyServerCallbacks());
/*
BLE SERVICE SETUP
*/
BLEService *bleService = bleServer->createService(BLE_SERVICE_UUID);
bleCharacteristic = bleService->createCharacteristic(
BLE_CHARACTERISTIC_UUID,
BLECharacteristic::PROPERTY_NOTIFY |
BLECharacteristic::PROPERTY_READ
);
bleCharacteristic->addDescriptor(new BLE2902());
bleService->start();
//Advertising
BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
pAdvertising->addServiceUUID(BLE_SERVICE_UUID);
pAdvertising->setScanResponse(true);
pAdvertising->setMinPreferred(0x0);
BLEDevice::startAdvertising();
}
Это как я передаю по Bluetooth
void valueToByteArray(void* val, size_t val_size, uint8_t *byte_arr) {
/*
Takes an arbitrary value and its size, then copies it into the byte array
*/
for (int c_pos = 0; c_pos < val_size; ++c_pos) {
byte_arr[c_pos] = *((uint8_t*)val + c_pos);
}
}
/*
BLE Publishing Task
*/
void bleTaskHandler(void* pvParameters) {
//Delay Var
TickType_t lastUnblock; // used to prevent bluetooth stack congestion
EventBits_t uxBits; //used to keep track of sensor events
//Packet Counter
static uint16_t counter = 0;
// Send
bool send_buffer = false;
//Packet Storage
uint8_t ble_buffer[20]; //
//imu variables
struct imuReading xyztReading;
//rht variables
struct rhtReading rht;
//adc variables
float adcVal;
init_BLE();
while (true) {
send_buffer = false;
uxBits = xEventGroupWaitBits(eg, ADC_TASK_BIT | IMU_TASK_BIT | RHT_TASK_BIT, pdTRUE, pdFALSE, (TickType_t) pdMS_TO_TICKS(5));
/*
Everything below here is just for getting data and putting it on the buffer
I've removed the extra members in the packet to simplify things. I still see the problem with this reduced version.
*/
if ( (IMU_TASK_BIT & uxBits) != 0 ) {
if (uxQueueMessagesWaiting(imuStack) != 0) {
xQueueReceive(imuStack, &xyztReading, portMAX_DELAY);
if (_bleConnected) {
//fitting the data in one packet requires that the numbers be sent in a contiguous
//format
// x(16 bits)->y(16 bits)->z(16 bits) in memory
valueToByteArray(&xyztReading.xVal, sizeof(uint16_t), &ble_buffer[X_BUFFER_POS]);// x values first in memory
valueToByteArray(&xyztReading.yVal, sizeof(uint16_t), &ble_buffer[Y_BUFFER_POS]);
valueToByteArray(&xyztReading.zVal, sizeof(uint16_t), &ble_buffer[Z_BUFFER_POS]);
send_buffer = true;
}
}
}
/*
Send the data if the buffer was updated
*/
if (send_buffer) {
valueToByteArray(&counter, sizeof(counter), &ble_buffer[COUNTER_BUFFER_POS]);
++counter;
char buff[2];
for (int i = 0; i < 20; ++i) {
sprintf(buff, "%02X", ble_buffer[i]);
Serial.print(buff);
}
Serial.println(" end packet");
bleCharacteristic->setValue(ble_buffer, 20); //send full 20 byte buffer
bleCharacteristic->notify();
}
//disconnecting
if (!_bleConnected && _bleConnectedOld) {
Serial.println("disconnected");
vTaskDelayUntil(&lastUnblock, pdMS_TO_TICKS(500));
bleServer->startAdvertising();
_bleConnectedOld = _bleConnected;
}
//connecting
if (_bleConnected && !_bleConnectedOld) {
Serial.println("connected");
_bleConnectedOld = _bleConnected;
vTaskDelayUntil(&lastUnblock, pdMS_TO_TICKS(500)); // wait for ble stack to catch up
}
}
}
Это то, что я получаю, когда строю график своих данных.
Imgur
Я ожидаю, что линия z будет гладкой без разрывов, так как ничего не движется.
Кроме того, всякий раз, когда я получаю пакет с поврежденными данными, следующий пакет полностью отбрасывается. Я проверил это с помощью счетчика пакетов в каждом пакете. Я бы получил последовательность вроде 5,6, мусор, 9,10 ...
Любая помощь или совет приветствуется!
Изменения: добавлено в недостающую информацию
#define X_BUFFER_POS (0)
#define Y_BUFFER_POS (2)
#define Z_BUFFER_POS (4)