How to remove 133(0X85) GATT Error

Thread Starter

rayyanalvi

Joined Jul 23, 2022
4
Hi, I am working with Arduino Nano 33 BLE. I have a code that sends data to an app via Bluetooth successfully but fails after a few reads and gives "error 133(0X85) GATT error".
C++:
//#include "mbed.h"

#include <Arduino_LPS22HB.h>

#include <Arduino_LSM9DS1.h>

#include <PDM.h>

#include <Arduino_APDS9960.h>

#include <Arduino_HTS221.h>

#include "ble/BLE.h"

//#define BLE_ROLE_PERIPHERAL;

//#include "events/EventQueue.h"

using namespace mbed;

/*------------GLOBAL VARIABLES-------------*/

const static char DEVICE_NAME[] = "SMARTSOLE";                     // Device name when detected on Bluetooth

static events::EventQueue event_queue(10 * EVENTS_EVENT_SIZE);  // Create Event queue

static const uint16_t MAX_ADVERTISING_PAYLOAD_SIZE = 78;        // Advertising payload parameter

const ble::phy_set_t CodedPHY(ble::phy_t::LE_CODED);            // Creating a Coded Phy set

static const uint16_t uuid16_list[]        = {0xFFFF}; //Custom UUID, FFFF is reserved for development

const float analogInPin1 = A0; // change here to read another analog input

const float analogInPin2 = A1;

const float analogInPin3 = A2;

float voltage1, voltage2, voltage3;

float senseAve1,senseAve2,senseAve3;

float vout1,vout2,vout3;

float  ForcePos1, ForcePos2, ForcePos3;

float cf = 2032.5203; // calibration factor

float GND_CONTACT_T = millis();



float weight1,weight2,weight3;


uint16_t force2ServiceUUID  = 0xA005;

uint16_t forceServiceUUID  = 0xA000;

// position1FCharUUID       = 0xA001;

//uint16_t position2FCharUUID      = 0xA002;

#define POSITION1FCharUUID      "1A3AC130-31EE-758A-BC50-54A61958EF81"

#define POSITION2FCharUUID      "FE4E19FF-B132-0099-5E94-3FFB2CF07940"

uint16_t position3FCharUUID      = 0xA003;


#define BLE_UUID_TEST_SERVICE               "9A48ECBA-2E92-082F-C079-9E75AAE428B1"

#define BLE_UUID_ACCELERATION               "2713"

//#define BLE_UUID_POSITION1F                    "1A3AC130-31EE-758A-BC50-54A61958EF81"

//#define BLE_UUID_POSITION2F              "FE4E19FF-B132-0099-5E94-3FFB2CF07940"

const char* deviceServiceUuid = "19b10000-e8f2-537e-4f6c-d104768a1214";


/* Set Up custom Characteristics */

static uint8_t readValue[10] = {weight1};

ReadOnlyArrayGattCharacteristic<uint8_t, sizeof(readValue)> readChar(POSITION1FCharUUID, readValue,GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY);

static uint8_t writeValue[11] = {weight2};

WriteOnlyArrayGattCharacteristic<uint8_t, sizeof(writeValue)> writeChar(POSITION2FCharUUID, writeValue);




/* Set up custom service */

//GattCharacteristic *characteristics[] = {&writeChar};

GattCharacteristic *characteristics[] = {&readChar, &writeChar};

GattService        forceService(forceServiceUUID, characteristics, sizeof(characteristics) / sizeof(GattCharacteristic *));







//void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *)

//{

//  BLE::Instance(BLE::DEFAULT_INSTANCE).gap().startAdvertising();

//}


class LRDemo : public ble::Gap::EventHandler {

public:

  //  /* Class constructor */

    LRDemo(BLE &ble, events::EventQueue &event_queue) :

        _ble(ble),                                      // BLE API Class

        _event_queue(event_queue),

        _service_uuid("b77a2543-ddc5-4e16-8955-15a29123e4e0"),

        _data_service(_service_uuid, _data_service_characteristics, 4),                 

        //_adv_handle(ble::INVALID_ADVERTISING_HANDLE),   // Advertising parameter

        _adv_data_builder(_adv_buffer),

         characteristic1("b77a2543-ddc5-4e16-8955-15a29123e4e4"),

          characteristic2("b77a2543-ddc5-4e16-8955-15a29123e4e2"),

        characteristic3("b77a2543-ddc5-4e16-8955-15a29123e4e3"),

        characteristic4("b77a2543-ddc5-4e16-8955-15a29123e4e4")

        {

          _data_service_characteristics[0] = &characteristic1;

          _data_service_characteristics[1] = &characteristic2;

          _data_service_characteristics[2] = &characteristic3;

          _data_service_characteristics[3] = &characteristic4;

          }              // Advertising parameter


    /* Class destructor */

    ~LRDemo() {

        if (_ble.hasInitialized()) {

            _ble.shutdown();

        }

    }


    void start() {

        _ble.gap().setEventHandler(this);               // Assign GAP events to this class

        _ble.init(this, &LRDemo::eek:n_init_complete);     // Initialize Bluetooth

        _event_queue.dispatch_forever();                // Wait for event forever

    }

  private:

    /** Callback triggered when the ble initialization process has finished */

    void on_init_complete(BLE::InitializationCompleteCallbackContext *params) {

      if (params->error != BLE_ERROR_NONE) {

        Serial.println("Ble initialization failed.");

        delay(100);

        return;

      }


    

      Serial.println("Ble initialized.");

       _ble.gattServer().onUpdatesEnabled(

        makeFunctionPointer(this, &LRDemo::when_update_enabled));

//    _ble.gattServer().onUpdatesDisabled(

//        makeFunctionPointer(this, &LRDemo::when_update_disabled));

    ble_error_t err = _ble.gattServer().addService(_data_service);

    if (err) {

      Serial.println("Error %u during demo service registration");

      return;

    }


    //_ble.gap().startScan(ble::scan_duration_t(500));

      start_advertising();

    }

 


void when_update_enabled(GattAttribute::Handle_t handle) {

    currentCount = 0;

    Serial.println("update enabled on handle");

    if (_update_sensor_event == 0) {

      _update_sensor_event = _event_queue.call_every(

          250 /* ms */, callback(this, &LRDemo::update_sensor_value));

      Serial.println("BNO Reader started");

      delay(250);

    }

  }


  /**

     Handler called after a client has cancelled his subscription from

     notification or indication.


     [USER=120004]@Param[/USER] handle Handle of the characteristic value affected by the change.

  */

  void when_update_disabled(GattAttribute::Handle_t handle) {

    Serial.println("update disabled on handle");

    if (_update_sensor_event != 0) {

      _event_queue.cancel(_update_sensor_event);

      Serial.println("Counter:");

      _update_sensor_event = 0;

    }

  }


void start_advertising()

    {


      /* Create advertising parameters and payload */

      ble::AdvertisingParameters adv_parameters(

        ble::advertising_type_t::CONNECTABLE_NON_SCANNABLE_UNDIRECTED,    // Advertising Type here : connectable non scannable undirected = connectable with exetended advertising

        ble::adv_interval_t(ble::millisecond_t(500)),           // Min Advertising time in ms

        ble::adv_interval_t(ble::millisecond_t(500)),           // Max Advertising time in ms

        false                                                   // Legacy PDU : Needed to be OFF in Long Range Mode

      );

      adv_parameters.setPhy(ble::phy_t::LE_CODED, ble::phy_t::LE_CODED);  // Set Advertising radio modulation to LE_CODED Phy (=Long Range)

      adv_parameters.setTxPower(8);                                       // Set radio output power to 8dbm (max)

      _ble.gap().setPreferredPhys(&CodedPHY, &CodedPHY);                  // Set preferred connection phy to LE_CODED (=long range)



      /* now we set the advertising payload that gets sent during advertising without any scan requests */


      //_adv_data_builder.clear();

      _adv_data_builder.setFlags();

      _adv_data_builder.setName(DEVICE_NAME);


      /* Setup advertising */

      _ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME)); // add name

      _ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list)); // UUID's broadcast in advertising packet



      /* Add our custom service */


    // _ble.addService(forceService);

//

     _ble.gap().startAdvertising();

  

    }


void update_sensor_value() {

  HTS.begin();

  BARO.begin();

  IMU.begin();

  APDS.begin();

  float pressure = BARO.readPressure();

    int numReads = 50;

    float senseSum1 = 0;

    int senseSum2 = 0;

    int senseSum3 = 0;

    for(int k = 0; k < numReads; k++) {

      senseSum1 += analogRead(A0);

      delay(1);

      senseSum2 += analogRead(A1);

      delay(1);

      senseSum3 += analogRead(A2);

      delay(1);

    }

    bool accelAvailable;

    float accelX = -1;

    float accelY = -1;

    float accelZ = -1;

    if ((accelAvailable = IMU.accelerationAvailable())) {

        IMU.readAcceleration(accelX, accelY, accelZ);

    }

 

    bool gyroAvailable;

    float gyroX = -1;

    float gyroY = -1;

    float gyroZ = -1;

    if ((gyroAvailable = IMU.gyroscopeAvailable())) {

        IMU.readGyroscope(gyroX, gyroY, gyroZ);

    }

 

    bool magAvailable;

    float magX = -1;

    float magY = -1;

    float magZ = -1;

    if ((magAvailable = IMU.magneticFieldAvailable())) {

        IMU.readMagneticField(magX, magY, magZ);

    }

    float senseAve1 = senseSum1 / numReads;

    float senseAve2 = senseSum2 /numReads;

    float senseAve3 = senseSum3 /numReads;

    vout1 = (senseAve1 * 5.0) / 1056;

    vout2 = (senseAve2 * 5.0) / 1056.0;

    vout3 = (senseAve3 * 5.0) / 1056.0;

     ForcePos1= vout1 * cf ;

     ForcePos2 = vout2 *cf;

     ForcePos3 = vout3 *cf;

     float altitude = 44330 * ( 1 - pow(pressure/101.325, 1/5.255) );

    ++currentCount;

    float first[5];

    float second[5];

    float third[5];

    float forth[5];

    first[0] = HTS.readTemperature();

    first[1] = HTS.readHumidity();

    first[2] = altitude;

    first[3] = 0;

    second[0] = ForcePos1;

    second[1] = ForcePos2;

    second[2] = ForcePos3;

    second[3] = GND_CONTACT_T;

    third[0] = accelX;

    third[1] = accelY;

    third[2] = accelZ;

    third[3] = 0;

    forth[0] = magX;

    forth[1] = magY;

    forth[2] = magZ;

    Serial.print("Weight1");

    Serial.println (first[ ]);



 

    //memcpy(second, first, sizeof(second));

    //memcpy(third, first, sizeof(third));

    //memcpy(forth, first, sizeof(forth));

 

    //memcpy(second, first, sizeof(second));

    //memcpy(third, first, sizeof(third));

   // memcpy(forth, first, sizeof(forth));


    characteristic1.set(_ble.gattServer(), first);


    characteristic2.set(_ble.gattServer(), second);

 

    characteristic3.set(_ble.gattServer(), third);

 

    characteristic4.set(_ble.gattServer(), forth);

 

  }


  private:

//  /* Event handler */


  void

onConnectionComplete(const ble::ConnectionCompleteEvent &event) override {

  //_ble.gap().startScan(ble::scan_duration_t(500));

    Serial.print("Connection Interval: %d, Connection Latency: %d, Supervison ");

    delay(100);

//              "Timeout %d\n");

//  Serial.print  ( event.getConnectionInterval().valueInMs());

//   Serial.print  (event.getConnectionLatency().value());

//    Serial.print  (event.getSupervisionTimeout().valueInMs());

//    Serial.println("MIN: Connection Interval: %d, Connection Latency: %d, "

//              "Supervison Timeout %d\n");

//   Serial.println (event.getConnectionInterval().min().valueInMs());

////              event.getConnectionLatency().min(),

////              event.getSupervisionTimeout().min().valueInMs());

//    Serial.println("MAX: Connection Interval: %d, Connection Latency: %d, "

//              "Supervison Timeout %d\n");

////              event.getConnectionInterval().max().valueInMs(),

////              event.getConnectionLatency().max(),

////              event.getSupervisionTimeout().max().valueInMs());

//

//    auto toConnIntervalTTime = [](int timeInMs) {

//      return (timeInMs * 1000) / ble::conn_interval_t::TIME_BASE;

//    };

//

//    auto err = _ble.gap().updateConnectionParameters(

//        event.getConnectionHandle(), event.getConnectionInterval().min(),

//        event.getConnectionInterval().min(), event.getConnectionLatency(),

//        event.getSupervisionTimeout());

//    Serial.println("Error: %d");

//    Serial.println( err);

  }


  void

  onDisconnectionComplete(const ble::DisconnectionCompleteEvent &) override {

     delay(250);

    _ble.gap().startAdvertising();

    delay(100);

  }

 

    private:

    /* Class variables declaration*/

    BLE &_ble;

    events::EventQueue &_event_queue;

     UUID _service_uuid;


  GattCharacteristic *_data_service_characteristics[4];


  // demo service

  GattService _data_service;

  GattServer *_server;

  int _update_sensor_event = 0;


    uint8_t _adv_buffer[MAX_ADVERTISING_PAYLOAD_SIZE];  // Advertising parameters

    ble::advertising_handle_t _adv_handle;              //

    ble::AdvertisingDataBuilder _adv_data_builder;


   class NotifyFloatCharacteristic : public GattCharacteristic {

  public:

    NotifyFloatCharacteristic(const UUID &uuid)

        : GattCharacteristic(

              /* UUID */ uuid,

              /* Initial value */ {0},

              /* Value size */ sizeof(float) * 5,

              /* Value capacity */ sizeof(float) * 5,

              /* Properties */

              GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY | BLE_GATT_CHAR_PROPERTIES_READ,


              /* Descriptors */ NULL,

              /* Num descriptors */ 0,

              /* variable len */ false) {}

    ble_error_t set(GattServer &server, const float value[5]) const {

      return server.write(getValueHandle(), (uint8_t *)value, sizeof(float) * 5,

                          false);

    }

  };

  NotifyFloatCharacteristic characteristic1;

  //delay(250);

  NotifyFloatCharacteristic characteristic2;

  //delay(250);

  NotifyFloatCharacteristic characteristic3;

  //delay(250);

  NotifyFloatCharacteristic characteristic4;

  //delay(250);

  int currentCount = 0;


 


};


/** Schedule processing of events from the BLE middleware in the event queue. */

void schedule_ble_events(BLE::OnEventsToProcessCallbackContext *context) {

    event_queue.call(Callback<void()>(&context->ble, &BLE::processEvents));

 

}


/*====================== MAIN CODE ======================*/



int main() {
Serial.begin(9600);
BLE &ble = BLE::Instance();
ble.onEventsToProcess(schedule_ble_events);
Serial.print("Starting BLE Server\n");
LRDemo demo(ble, event_queue);
// Starting delay - 100 msec
// Delay between each evet - 200msec
demo.start();

return 0;
}
void setup(){
/* Setup Debugging */
Serial.begin(9600);
// while(!Serial);
//
// /* Low Power */
// digitalWrite(LED_PWR, LOW); // Turn off power LED
// digitalWrite(PIN_ENABLE_SENSORS_3V3, LOW); // Turn off sensors
// NRF_POWER->DCDCEN = 0x00000001; // Enable DCDC
// /* */
//
// BLE &ble = BLE::Instance(); // Create the BLE object in order to use BLE_API function
// ble.onEventsToProcess(schedule_ble_events); // Set event schedule
//
// LRDemo demo(ble, event_queue); // Create LRDemo Object
// demo.start(); // Start Bluetooth Long Range
// delay(100);
}

void loop(){}

/*=======================================================*/
 
Last edited by a moderator:
Top