我有一些代码用于通过蓝牙低功耗将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)