使用其位nRF52840通过蓝牙低功耗以固定速率传输数据

问题描述 投票:0回答:1

我正在构建一个无线 ppg 传感器作为我的高级工程设计项目的模块,但我正在努力通过蓝牙获得足够的数据传输速率。在这里您可以看到我尝试将 10 秒的数据保存到缓冲区(采样频率为 125Hz)。然后我通过蓝牙将每个数据打印到我的移动设备。

该芯片的蓝牙规格估计数据传输速率约为 2mbps,尽管如此,传输所有 1250 个整数仍需要近 4 分钟。

如何加快打印时间,使我的数据传输率为 125Hz,并且我不需要为每 10 秒的数据输入等待 4 分钟?

我更希望实时打印数据,但尝试在不收集缓冲区的情况下打印数据会导致信号间隙。至少对于我目前拥有的 10 秒缓冲区来说是连续的,但目标是在从传感器读取数据后立即打印。我已经有一个 iOS 应用程序设置,可以将数据解析为 10 秒的块并将它们输入到我的神经网络中,因此不需要以 10 秒的块的形式发送数据。

#include <bluefruit.h>
#include <Wire.h>
#include "MAX30105.h"

MAX30105 particleSensor;
BLEUart bleuart; // Add BLE UART service

void setup() 
{
  Serial.begin(230400);
  Serial.println("Initializing...");

  // Start I2C
  Wire.begin();
  
  // Initialize sensor
  if (!particleSensor.begin(Wire, I2C_SPEED_FAST)) 
  {
    Serial.println("ERROR: MAX30102 not found.");
    while (1);
  }
  Serial.println("MAX30105 initialized.");

  // Configure sensor
  particleSensor.setup(0x1F, 8, 2, 3200, 69, 4096); // Configure with specific settings

  Bluefruit.begin();
  Bluefruit.setTxPower(4);
  Bluefruit.Periph.setConnInterval(9, 16);

  // Initialize BLE UART service
  bleuart.begin();

  // Start advertising
  startAdv();
}

void startAdv(void)
{
  Bluefruit.Advertising.addFlags(BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE);
  Bluefruit.Advertising.addTxPower();
  Bluefruit.Advertising.addService(bleuart); // Include BLE UART service
  Bluefruit.Advertising.addName();
  Bluefruit.Advertising.restartOnDisconnect(true);
  Bluefruit.Advertising.setInterval(32, 244);
  Bluefruit.Advertising.setFastTimeout(30);
  Bluefruit.Advertising.start(0);
}

void loop() {
  static unsigned long lastSample = 0;
  unsigned long currentTime = micros();
  static unsigned int numSamples = 0;
  static unsigned long last1250 = 0;

  // Buffer for 1250 compressed values
  static uint16_t dataBuffer[1250] = {0}; // Using uint16_t since I'm only storing the middle 5 digits

  if (currentTime - lastSample >= 8000) {  
    // Get sensor data
    uint32_t irValue = particleSensor.getIR(); 

    // Compress the value
    uint16_t compressedValue = (irValue % 100000) / 10; // Keep only the middle 5 digits
    Serial.println(compressedValue);
    // Store the compressed value in the buffer
    if (numSamples < 1250) {
      dataBuffer[numSamples] = compressedValue;
      numSamples++;
    }

    lastSample = currentTime;
  }

  if (numSamples >= 1250) {
    // Print elapsed time for 1250 samples to Serial
    Serial.print("Starting Bluetooth Transfer (1250 samples collected), Time: ");
    Serial.println(micros() - last1250);
    last1250 = micros();

    // Transmit the buffer data
    for (int i = 0; i < 1250; i++) {
      bleuart.println(dataBuffer[i]);
    }
    Serial.println("Bluetooth Transfer Complete");

    // Reset counters
    numSamples = 0;
  }
}
c++ c arduino bluetooth bluetooth-lowenergy
1个回答
0
投票

您使用的蓝牙是低功耗蓝牙 (BLE)。 BLE 允许设备在大部分时间关闭发射器,这就是它“低能耗”的原因。

这意味着当您执行

bleuart.println(dataBuffer[i]);
操作时,它会在后台打开无线电,建立连接,发送(默认情况下)20 个字节,然后关闭无线电。 因此,如果您要发送
125
的值,当您使用
println
时,它会将其转换为 ASCII,因此将是三个字节,从而产生有效负载:
3532310000000000000000000000000000000000
每次打开和关闭无线电时的有效负载效率低下。

将值(例如 125)写为

7d
的单字节值会更有效。这意味着您可以为相同的有效负载发送 20 个值,同时打开和关闭无线电的开销。

您还可以让您的应用程序协商更大的有效负载 (MTU),这将在相同的无线电开销下实现更大的吞吐量。

通过 BLE 使用“UART”服务可能不是您项目的最有效选择。如果您使用的是心率,那么可能值得使用蓝牙标准来传输此类信息。这将允许您利用大量已有的示例或使用遵循标准的应用程序。

https://www.bluetooth.com/specifications/specs/heart-rate-service-1-0/

© www.soinside.com 2019 - 2024. All rights reserved.