首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >BLE上的加速度计数据不是同步发送的。

BLE上的加速度计数据不是同步发送的。
EN

Stack Overflow用户
提问于 2021-11-18 12:46:15
回答 1查看 209关注 0票数 0

我是发送温度,湿度,压力和加速度计的数据通过BLE,从阿杜伊诺 (外围)到覆盆子Pi 4 (中央)。我为每个加速维(accX, accY, accZ)创建了BLE特性,并且我订阅了这些特性。

然而,我为每一个特征放置计数器,并意识到数据不是按顺序发送的:

代码语言:javascript
复制
18 Nov 12:27:35 - [info] [BLE Connect:bf9be48b4648f12e] x = 233
18 Nov 12:27:35 - [info] [BLE Connect:bf9be48b4648f12e] y = 230
18 Nov 12:27:35 - [info] [BLE Connect:bf9be48b4648f12e] z = 236

因此,x被读233倍y 230倍,反之亦然。在理想的情况下,它们应该是相同的。

我正在张贴我的全部Arduino代码减去注释,因此我认为可能需要:

代码语言:javascript
复制
#include <ArduinoBLE.h>
#include <Arduino_HTS221.h>
#include <Arduino_LPS22HB.h>
#include <Arduino_LSM9DS1.h>
  
#define BLE_UUID_ENVIRONMENTAL_SENSING_SERVICE    "181A"
#define BLE_UUID_TEMPERATURE                      "2A6E"
#define BLE_UUID_HUMIDITY                         "2A6F"
#define BLE_UUID_PRESSURE                         "2A6D"
#define BLE_UUID_ACCELEROMETER_SERVICE            "1101"
#define BLE_UUID_ACCELEROMETER_X                  "2101"
#define BLE_UUID_ACCELEROMETER_Y                  "2102"
#define BLE_UUID_ACCELEROMETER_Z                  "2103"

#define BLE_DEVICE_NAME                           "Hako"
#define BLE_LOCAL_NAME                            "Hako"

BLEService environmentalSensingService(BLE_UUID_ENVIRONMENTAL_SENSING_SERVICE);
BLEService accelerometerService(BLE_UUID_ACCELEROMETER_SERVICE);


BLEShortCharacteristic temperatureCharacteristic(BLE_UUID_TEMPERATURE, BLERead | BLENotify);
BLEUnsignedShortCharacteristic humidityCharacteristic(BLE_UUID_HUMIDITY, BLERead | BLENotify);
BLEUnsignedLongCharacteristic pressureCharacteristic(BLE_UUID_PRESSURE, BLERead | BLENotify);
BLEShortCharacteristic accelerometerCharacteristic_X(BLE_UUID_ACCELEROMETER_X, BLERead | BLENotify);
BLEShortCharacteristic accelerometerCharacteristic_Y(BLE_UUID_ACCELEROMETER_Y, BLERead | BLENotify);
BLEShortCharacteristic accelerometerCharacteristic_Z(BLE_UUID_ACCELEROMETER_Z, BLERead | BLENotify);

#define ENV_SENSOR_UPDATE_INTERVAL                (1000)
#define ACC_SENSOR_UPDATE_INTERVAL                (1000)

typedef struct __attribute__((packed))
{
  float temperature;
  float humidity;
  float pressure;
  bool updated = false;
} env_sensor_data_t;

env_sensor_data_t envSensorData;

typedef struct __attribute__((packed))
{
  float accX;
  float accY;
  float accZ;
  bool updated = false;
} acc_sensor_data_t;

acc_sensor_data_t accSensorData;

#define BLE_LED_PIN                               LED_BUILTIN


void setup()
{
  Serial.begin(9600);
  while (!Serial);
  Serial.println( "BLE Example - Environmental Sensing Service (ESS)" );
  pinMode( BLE_LED_PIN, OUTPUT );
  digitalWrite( BLE_LED_PIN, LOW );
  // Without Serial when using USB power bank HTS sensor seems to needs some time for setup
  delay(10);
  if (!HTS.begin()) {
    Serial.println("Failed to initialize humidity temperature sensor!");
    while (1);
  }
  if (!BARO.begin()) {
    Serial.println( "Failed to initialize pressure sensor!" );
    while (1);
  }
  if (!IMU.begin()) {
    Serial.println("Failed to initialize IMU!");
    while (1);
  }
  if (!setupBleMode()) {
    while (1);
  }
  else {
    Serial.println( "BLE initialized. Waiting for clients to connect." );
  }
}

void loop() {
  bleTask();
  if (envSensorTask()) {
    envPrintTask();
  }
  if (accSensorTask()) {
    accPrintTask();
  }
}

bool envSensorTask() {
  static long previousMillis = 0;
  unsigned long currentMillis = millis(); 
  if (currentMillis - previousMillis < ENV_SENSOR_UPDATE_INTERVAL) {
    return false;
  }
  previousMillis = currentMillis;
  envSensorData.temperature = HTS.readTemperature();
  envSensorData.humidity = HTS.readHumidity();
  envSensorData.pressure = BARO.readPressure() * 1000; // kPa -> Pa
  envSensorData.updated = true;
  return envSensorData.updated;
}

bool accSensorTask() {
  static long previousMillis2 = 0;
  unsigned long currentMillis2 = millis();
  float x = 0.00, y = 0.00, z = 0.00;
  if (currentMillis2 - previousMillis2 < ACC_SENSOR_UPDATE_INTERVAL) {
    return false;
  }
  previousMillis2 = currentMillis2;
  if(IMU.accelerationAvailable()){
    IMU.readAcceleration(x, y, z);
    accSensorData.accX = x;
    accSensorData.accY = y;
    accSensorData.accZ = z;
    accSensorData.updated = true;
  }
  return accSensorData.updated;
}

bool setupBleMode() {
  if (!BLE.begin()) {
    return false;
  }

  BLE.setDeviceName(BLE_DEVICE_NAME);
  BLE.setLocalName(BLE_LOCAL_NAME);
  BLE.setAdvertisedService(environmentalSensingService);
  BLE.setAdvertisedService(accelerometerService);

  environmentalSensingService.addCharacteristic(temperatureCharacteristic);
  environmentalSensingService.addCharacteristic(humidityCharacteristic);
  environmentalSensingService.addCharacteristic(pressureCharacteristic);
  accelerometerService.addCharacteristic(accelerometerCharacteristic_X);
  accelerometerService.addCharacteristic(accelerometerCharacteristic_Y);
  accelerometerService.addCharacteristic(accelerometerCharacteristic_Z);
  
  BLE.addService(environmentalSensingService);
  BLE.addService(accelerometerService);

  temperatureCharacteristic.writeValue(0);
  humidityCharacteristic.writeValue(0);
  pressureCharacteristic.writeValue(0);
  accelerometerCharacteristic_X.writeValue(0);
  accelerometerCharacteristic_Y.writeValue(0);
  accelerometerCharacteristic_Z.writeValue(0);

  BLE.setEventHandler(BLEConnected, blePeripheralConnectHandler);
  BLE.setEventHandler(BLEDisconnected, blePeripheralDisconnectHandler);

  BLE.advertise();

  return true;
}

void bleTask()
{
  const uint32_t BLE_UPDATE_INTERVAL = 10;
  static uint32_t previousMillis = 0;
  uint32_t currentMillis = millis();
  if (currentMillis - previousMillis >= BLE_UPDATE_INTERVAL) {
    previousMillis = currentMillis;
    BLE.poll();
  }

  if (envSensorData.updated) {
    // BLE defines Temperature UUID 2A6E Type sint16 ( see XML links )
    // Unit is in degrees Celsius with a resolution of 0.01 degrees Celsius
    int16_t temperature = round(envSensorData.temperature * 100.0);
    temperatureCharacteristic.writeValue(temperature);

    // BLE defines Humidity UUID 2A6F Type uint16
    // Unit is in percent with a resolution of 0.01 percent
    uint16_t humidity = round(envSensorData.humidity * 100.0);
    humidityCharacteristic.writeValue(humidity);

    // BLE defines Pressure UUID 2A6D Type uint32
    // Unit is in Pascal with a resolution of 0.1 Pa
    uint32_t pressure = round(envSensorData.pressure * 10.0);
    pressureCharacteristic.writeValue(pressure);
    envSensorData.updated = false;
  }

  if (accSensorData.updated) {
    // BLE does not define accelerometer UUID
    // Alls units is in G
    int16_t accelerometer_X = round(accSensorData.accX * 100.0);
    accelerometerCharacteristic_X.writeValue(accelerometer_X);
    
    int16_t accelerometer_Y = round(accSensorData.accY * 100.0);
    accelerometerCharacteristic_Y.writeValue(accelerometer_Y);

    int16_t accelerometer_Z = round(accSensorData.accZ * 100.0);
    accelerometerCharacteristic_Z.writeValue(accelerometer_Z);
 
    envSensorData.updated = false;
  }
}

void envPrintTask() {
  Serial.print( "Temperature = " );
  Serial.print( envSensorData.temperature );
  Serial.println( " °C" );

  Serial.print( "Humidity    = " );
  Serial.print( envSensorData.humidity );
  Serial.println( " %" );

  Serial.print( "Pressure = " );
  Serial.print( envSensorData.pressure );
  Serial.println( " Pa" );

  Serial.print(temperatureCharacteristic.subscribed());
  Serial.print(humidityCharacteristic.subscribed());
  Serial.println(pressureCharacteristic.subscribed());
}

void accPrintTask() {
  Serial.print("AccX = ");
  Serial.print(accSensorData.accX);
  Serial.println(" G");

  Serial.print("AccY = ");
  Serial.print(accSensorData.accY);
  Serial.println(" G");

  Serial.print("AccZ = ");
  Serial.print( accSensorData.accZ );
  Serial.println(" G");

  Serial.print(accelerometerCharacteristic_X.subscribed());
  Serial.print(accelerometerCharacteristic_Y.subscribed());
  Serial.println(accelerometerCharacteristic_Z.subscribed());
}

void blePeripheralConnectHandler(BLEDevice central) {
  digitalWrite(BLE_LED_PIN, HIGH);
  Serial.print(F( "Connected to central: " ));
  Serial.println(central.address());
}

void blePeripheralDisconnectHandler( BLEDevice central ) {
  digitalWrite(BLE_LED_PIN, LOW);
  Serial.print(F("Disconnected from central: "));
  Serial.println(central.address());
}

我正在通过Node.js环境通过@废品/贵族库读取Pi上的数据。

我只会张贴相关的部分,在那里我订阅的特点,然后我阅读的数据。您可以在最后看到计数器

代码语言:javascript
复制
for (const [key, character] of Object.entries(ALL.characteristics)) {

                    // Check the notify bit, if not set, set it. //
                    if (character.properties.includes("notify")) {
                        const descriptors = await character.discoverDescriptorsAsync().catch(e => send(e));
                        for (const [key, descriptor] of Object.entries(descriptors)) {
                            node.log(descriptor);
                            let descriptorData = await descriptor.readValueAsync().catch(e => send(e));
                            if (descriptorData[0] === bufferChecker[0] || descriptorData[1] === bufferChecker [1]) {
                                node.log(`The ${character.name} ${character.uuid} notify bit is disabled.`);
                                node.log("Enabling notification bit...");
                                descriptor.writeValueAsync(notifySetter).catch(e => send(e));
                                node.log (`Notification for ${character.name} characteristic is enabled.`);
                            } else {
                                node.log(`The ${character.name} ${character.uuid} notify bit is already enabled.`);
                                return;
                            }
                        }
                    } else {
                        node.log(`Notification is not allowed for ${character.name} characteristic.`)
                    }
                }

                for (const [key, character] of Object.entries(ALL.characteristics)) {
                    character.on('data', (data) => {
                        if (character.uuid === '2a6d') {
                            data = data.readUInt32LE() * decimalSetter[1];
                            environmentalData.payload[character.name] = data.toFixed(2);
                            counterPres++;
                        } else if (character.uuid === '2a6e') {
                            data = data.readUInt16LE() * decimalSetter[0];
                            environmentalData.payload[character.name] = data.toFixed(2);
                            counterTemp++;
                        } else if (character.uuid === '2a6f') {
                            data = data.readUInt16LE() * decimalSetter[0];
                            environmentalData.payload[character.name] = data.toFixed(2);
                            counterHum++;
                        } else if (character.uuid === '2101') {
                            data = data.readInt16LE() * decimalSetter[0];
                            accData.payload[character.name] = data.toFixed(2);
                            counterAccX++;
                        } else if (character.uuid === '2102') {
                            data = data.readInt16LE() * decimalSetter[0];
                            accData.payload[character.name] = data.toFixed(2);
                            counterAccY++;
                        } else if (character.uuid === '2103') {
                            data = data.readInt16LE() * decimalSetter[0];
                            accData.payload[character.name] = data.toFixed(2);
                            counterAccZ++;
                        }
                        node.log("x = " + counterAccX);
                        node.log("y = " + counterAccY);
                        node.log("z = " + counterAccZ);
                        // Sends Temp., Hum., and Pres. data together.
                        if ( (counterHum + counterPres + counterTemp) % 3 == 0 && (counterHum + counterPres + counterTemp) !== 0){
                            send(environmentalData);
                        }
                      });
                    // Character data event listener END //
                }

我在Arduino论坛也问了同样的问题。

EN

回答 1

Stack Overflow用户

发布于 2021-11-18 21:26:59

外围设备GATT服务器仅在测量值确实发生变化时才发送数据。这种行为可以节省能源和带宽。因此,我认为你的观察是完全正常的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70020111

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档