ESP32发送前4个字节后的随机数据包

时间:2019-07-11 19:30:18

标签: arduino bluetooth-lowenergy freertos esp32

我有一些代码用于通过蓝牙低功耗将ESP32的传感器数据传输到树莓派。我已经注意到,我在接收器上获得的前4个字节之后的数据是错误的,并且包含随机值,但这不会影响每个数据包。我正在使用FreeRTOS同时使用多个传感器和BLE。

我已验证我在Wireshark的前4个字节之后收到的数据不正确的数据包。在下面的代码中,我还打印了要传输的数据,当我寻找损坏的数据包时,我在Arduino串行监视器上看到的内容与在Wireshark上看到的内容不一致,即串行监视器显示了我希望看到

我尝试过更新BLE库,以增加FreeRTOS任务的堆栈大小,以防堆栈溢出。我还尝试将Wireshark上看到的数据包与ble通知呼叫之前和之后传输的数据进行比较,并且缓冲区上的数据看起来还不错,但是我在Wireshark上收到的数据包是不正确的。我还尝试增加MTU大小,以防我的数据包太大。关于这一点,我最好的猜测是它与RTOS有关,因为我遵循了https://github.com/nkolban/esp32-snippets中的示例以及ESP32的BLE功能论坛。

任何帮助或指向正确方向的指针将不胜感激。

这就是我设置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();
}

这就是我通过蓝牙传输的方式


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,garbage,9,10 ...

任何帮助或建议都值得赞赏!

编辑:添加了缺少的信息

#define X_BUFFER_POS (0)
#define Y_BUFFER_POS (2)
#define Z_BUFFER_POS (4)

0 个答案:

没有答案