2017-08-30 8 views
0

Ich möchte Beschleunigungsmesser Werte über BLE zu einer iOS App mit einem nordischen nRF52 senden. Die App funktioniert perfekt mit Standard-BLE-Diensten (HeartRate-Messung, Thermometer usw.), aber nicht, wenn ich versuche, einen benutzerdefinierten BLE-Beschleunigungssensor zu definieren. Was muss ich bei der Definition von UUIDs und anderen Dingen konkret tun? Jede Hilfe würde sehr geschätzt werden, danke.BLE Beschleunigungsmesser

Unten ist meine benutzerdefinierte Accelerometer-Klasse, und die main.cpp hochgeladen die nRF52 darunter.

#ifndef __BLE_ACCELEROMETER_SERVICE__ 
#define __BLE_ACCELEROMETER_SERVICE__ 

#include "ble/BLE.h" 

#define UUID_ACCELEROMETER_SERVICE "00000000-0000-1000-7450-BE2E44B06B00" 

#define UUID_X_CHARACTERISTIC  "00000000-0000-1000-7450-BE2E44B06B01" 
#define UUID_Y_CHARACTERISTIC  "00000000-0000-1000-7450-BE2E44B06B02" 
#define UUID_Z_CHARACTERISTIC  "00000000-0000-1000-7450-BE2E44B06B03" 

/** 
* @class AccelerometerService 
* @brief BLE Custom Accelerometer Service. This provides the x, y and z values of the SEEED 101020051 Grove accelerometer connected to the Nordic nRF52 DK. 
*/ 

class AccelerometerService 
{ 
public: 

    /** 
    * @brief Add the Accelerometer Service to an existing BLE object, initialize with values for x, y and z readings, represented as doubles. 
    * @param _ble Reference to the BLE device 
    * @param _x Initial value for the x axis 
    * @param _y Initial value for the y axis 
    * @param _z Initial value for the z axis 
    */ 
    AccelerometerService(BLE &_ble, double _x = 0, double _y = 0, double _z = 0) : 
    ble(_ble), 
    x(_x), 
    y(_y), 
    z(_z), 
    xAngleCharacteristic(UUID_X_CHARACTERISTIC, &x, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY), 
    yAngleCharacteristic(UUID_Y_CHARACTERISTIC, &y, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY), 
    zAngleCharacteristic(UUID_Z_CHARACTERISTIC, &z, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY) { 

     GattCharacteristic *readings[] = {&xAngleCharacteristic, &yAngleCharacteristic, &zAngleCharacteristic, }; 
     GattService   accelerometerService(UUID_ACCELEROMETER_SERVICE, readings, sizeof(readings)/sizeof(GattCharacteristic *)); 

     ble.addService(accelerometerService); 
    } 

    /** 
    * @brief Update the x axis rotation with a new value. 
    * @param _x - New x value from accelerometer 
    */ 
    void update_x(uint8_t _x) { 
     x = _x; 
     ble.gattServer().write(xAngleCharacteristic.getValueHandle(), &x, 1); 
    } 

    /** 
    * @brief Update the y axis rotation with a new value. 
    * @param _z - New y value from accelerometer 
    */ 
    void update_y(uint8_t _y) { 
     y = _y; 
     ble.gattServer().write(yAngleCharacteristic.getValueHandle(), &y, 1); 
    } 

    /** 
    * @brief Update the z axis rotation with a new value. 
    * @param _z - New z value from accelerometer 
    */ 
    void update_z(uint8_t _z) { 
     z = _z; 
     ble.gattServer().write(zAngleCharacteristic.getValueHandle(), &z, 1); 
    } 


protected: 

    /** 
    * A reference to the underlying BLE instance that this object is attached to. 
    * The services and characteristics will be registered in this BLE instance. 
    */ 
    BLE &ble; 

    /** 
    * The current x axis rotation, represented as a double 
    */ 
    uint8_t x; 
    /** 
    * The current y axis rotation, represented as a double 
    */ 
    uint8_t y; 
    /** 
    * The current z axis rotation, represented as a double 
    */ 
    uint8_t z; 

    /** 
    * A ReadOnlyGattCharacteristic that allows access to the peer device to the 
    * x axis rotation value through BLE. 
    */ 
    ReadOnlyGattCharacteristic<uint8_t> xAngleCharacteristic; 
    /** 
    * A ReadOnlyGattCharacteristic that allows access to the peer device to the 
    * y axis rotation value through BLE. 
    */ 
    ReadOnlyGattCharacteristic<uint8_t> yAngleCharacteristic; 
    /** 
    * A ReadOnlyGattCharacteristic that allows access to the peer device to the 
    * z axis rotation value through BLE. 
    */ 
    ReadOnlyGattCharacteristic<uint8_t> zAngleCharacteristic; 
}; 


#endif /* __BLE_ACCELEROMETER_SERVICE__ */ 

Unten ist die main.cpp-Datei, die ich über mbed.org verwende.

#include "mbed.h" 
#include "ble/BLE.h" 
#include "AccelerometerService.h" 

DigitalOut led1(LED1); 
DigitalOut led2(LED2); 

static AccelerometerService *accelerometerServicePtr; 

// Function declarations 
void bleInitComplete(BLE::InitializationCompleteCallbackContext *); 
void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *); 

// Set device name and inital setup options 
static const char  DEVICE_NAME[]  = "nRF52"; 
static const uint16_t uuid16_list[]  = {0xFFFF}; 
static volatile bool triggerSensorPolling = false; 

static float   x = 10.0; // Dummy values for accelerometer for now 
static float   y = 15.0; 
static float   z = 18.0; 

/* 
* Initialization callback 
*/ 
void bleInitComplete(BLE::InitializationCompleteCallbackContext *params) 
{ 
    BLE &ble = params->ble; 
    ble_error_t error = params->error; 

    if (error != BLE_ERROR_NONE){ 
     printf("*** Error occured ***\n"); 
     return; 
    } 

    /* Ensure that it is the default instance of BLE */ 
    if(ble.getInstanceID() != BLE::DEFAULT_INSTANCE) { 
     return; 
    } 

    ble.gap().onDisconnection(disconnectionCallback); 

    // Setup primary service 
    accelerometerServicePtr = new AccelerometerService(ble, x, y, z); 

    // Setup advertising 
    ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); 

    // Advertising payload has a maximum of 31 bytes 
    // BLE only, no classic BT 
    ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | 
              GapAdvertisingData::LE_GENERAL_DISCOVERABLE); 
    // Add name 
    ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME)); 
    // UUIDs broadcast in advertising packet 
    ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list)); 
    // Set advertising interval 
    ble.gap().setAdvertisingInterval(100); //100ms 

    // Start advertising 
    ble.gap().startAdvertising(); 
} 

/** 
* Restart advertising on disconnection 
*/ 
void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *) 
{ 
    BLE::Instance(BLE::DEFAULT_INSTANCE).gap().startAdvertising(); 
} 

/** 
* This function is called when the ble initialization process has failed 
*/ 
void onBleInitError(BLE &ble, ble_error_t error) 
{ 
    /* Avoid compiler warnings */ 
    (void) ble; 
    (void) error; 
    /* Initialization error handling should go here */ 
} 

int main() 
{ 
    // Initialize program 
    printf("\n\r *** Starting Main Loop *** \r\n"); 

    BLE &ble = BLE::Instance(BLE::DEFAULT_INSTANCE); 
    ble.init(bleInitComplete); 

    while (ble.hasInitialized() == false) 
    { 
     while (true) 
     { 
      if (triggerSensorPolling && ble.gap().getState().connected) { 
       triggerSensorPolling = false; 

       accelerometerServicePtr->update_x(x); 
       accelerometerServicePtr->update_y(y); 
       accelerometerServicePtr->update_z(z); 
      } 
      else { 
       ble.waitForEvent(); // Infinite loop waiting for BLE interrupt events 
      } 
     } 
    } 
} 
+1

Es ist ein bisschen schwierig, Ihnen ohne weitere Details zu helfen. Was genau ist das Problem, dem Sie gegenüber stehen, z. B. Peripheriegeräte werben nicht, können Dienste nicht erkennen, trennen sich nach 30s usw.? –

+0

Der Central Manager findet das Peripheriegerät (nRF52) und stellt eine Verbindung her, aber wenn ich die Methode [peripheral discoverServices: nil] aufruft, passiert nichts. Ich habe sogar versucht, NSLog Debug-Anweisungen am Anfang der Peripheriegeräte didDiscoverServices ... -Methode zu setzen, aber nichts passiert. –

+0

Weitere Ideen? Vielen Dank! @JensMeter –

Antwort

1

Das ist falsch, Sie senden ein schlechtes Werbepaket. (0xFFFF == Insert 16-Bit-Service hier)

... 
uuid16_list[]  = {0xFFFF}; 
... 
... 
COMPLETE_LIST_128BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list) 

Es für Bluetooth sind reserviert 16 Bit Identifier, die den reservierten UUID Raum nutzen.

prüfen Diese Seite: What range of Bluetooth UUIDs can be used for vendor defined profiles?

Was Sie tun müssen, ist die vollständige UUID in der 128-Bit-Liste angeben.

Ich kann diese kompilieren, aber Lightblue ist für die Überprüfung Ihrer Werbedaten so etwas wie diese

char 128bitlist[] = {,0x00,0x00,0x00,0x00 ,0x00,0x00 ,0x10,0x00 ,0x74,0x50 ,0xBE,0x2E,0x44,0xB0,0x6B,0x00}; 
... 
... 
ble.gap().accumulateAdvertisingPayload (GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS, (uint8_t *) 128bitlist, 1); 

Ein hervorragendes Werkzeug versuchen. Es ist kostenlos und sehr informativ. Sie sollten die Werbung auf Android und IOS mit diesem Tool überprüfen.

Eine andere Sache zu prüfen ist, dass Sie das Werbepaket nicht überfüllen. Wenn der Gerätename zu lang ist, plus die 128-Bit-UUID, können Sie das Paket überfüllen und beschädigen. Versuchen Sie, den Namen zu entfernen oder wirklich kurz zu machen.

Verwandte Themen