ESP32 отправляет пакеты со случайными данными после первых 4 байтов - PullRequest
0 голосов
/ 11 июля 2019

У меня есть код, который я использую для передачи данных датчика с 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)
...