我正在构建一个无线 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;
}
}
您使用的蓝牙是低功耗蓝牙 (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/