0

I'm working on a simple project, that involves an Arduino sending accelerometer data to a Cordova-based phone app using BLE.

I've got my Arduino wired up correctly, I think - I can see the data in the serial monitor.

However, when I send the data with BLE - each axis value has it's own characteristic - it looks like the phone app is only receiving a notification for the first axis.

Here's my .ino:

#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BNO055.h>
#include <utility/imumaths.h>
#include <SPI.h>
#include <BLEPeripheral.h>

#define BLE_REQ     10
#define BLE_RDY     2
#define BLE_RST     9

float
    x1 = 0,
    y1 = 0,
    z1 = 0;

Adafruit_BNO055 bno = Adafruit_BNO055(55);

// create peripheral instance
BLEPeripheral ble = BLEPeripheral(BLE_REQ, BLE_RDY, BLE_RST);

// create service
BLEService srv = BLEService("FF10");

BLEFloatCharacteristic charX = BLEFloatCharacteristic("FF11", BLENotify);
BLEFloatCharacteristic charY = BLEFloatCharacteristic("FF12", BLENotify);
BLEFloatCharacteristic charZ = BLEFloatCharacteristic("FF13", BLENotify);

void setup(void)
{
  Serial.begin(9600);

  ble.setLocalName("TestApp");  // Advertised in scan data as part of GAP
  ble.setDeviceName("TestApp"); // Advertised in generic access as part of GATT
  ble.setAdvertisedServiceUuid(srv.uuid());

  ble.addAttribute(srv);
  ble.addAttribute(charX);
  ble.addAttribute(charY);
  ble.addAttribute(charZ);

  ble.begin();

  /* Initialise the sensor */
  if (!bno.begin())
  {
    Serial.print("Could not initialize the BNO055");
    while (1);
  }

  delay(1000);

  bno.setExtCrystalUse(true);

}

void loop(void)
{

  imu::Vector<3> v;
  float x, y, z;

  v = bno.getVector(Adafruit_BNO055::VECTOR_LINEARACCEL);

  x = v.x();
  y = v.y();
  z = v.z();

  Serial.print("-20.0,"); //set lower scale
  Serial.print(x);  // x acceleration
  Serial.print(",");
  Serial.print(y);  // y acceleration
  Serial.print(",");
  Serial.print(z);  // z acceleration
  Serial.println(",20.0"); //set upper scale

  ble.poll();

  // only notify if the acceleration value is > 0.20

  if (abs(x1 - x) > 0.20)
  {
    x1 = x;
    charX.setValue(x);
  }
  if (abs(y1 - y) > 0.20)
  {
    y1 = y;
    charY.setValue(y);
  }
  if (abs(z1 - z) > 0.20)
  {
    z1 = z;
    charZ.setValue(z);
  }

}

As I mentioned - the data looks OK in the serial monitor. And my Cordova app is connecting to the Arduino peripheral, and receiving notifications.

But, only for the first axis.

If I comment out this line:

// charX.setValue(x);

... then the Cordova app only receives notifications for the second axis.

Likewise, if I comment out both of these lines:

// charX.setValue(x);
// charY.setValue(y);

... then the Cordova app only receives notifications for the third axis.

In other words - it's as if the Cordova app can only receive one notification at a time.

Since I need the app to receive data for all three axis' - how can I fix this?

[UPDATE]

In the current design - the Arduino app is updating all three characteristics on every loop. Since the Cordova phone app only seems to notice one - I wondered if maybe it's only able to process one notification per "cycle". So, I changed my Arduino app to this:

(Assumes I have a global int variable called i that's initialized to 0:

  if (i == 0) {
    charX.setValue(x);
  } else if (i == 1) {
    charY.setValue(y);
  } else if (i == 2) {
    charZ.setValue(z);
  }

  i++;
  if (i == 3) {
    i = 0;
  }

With this change - the Cordova app registers every notification, so it's "working". However, this approach is less than ideal, because there's a delay with each notification, since it's only updating one dimension every loop cycle.

So, I'm wondering if there's a better way to do this.

Thanks in advance.

  • 1
    debug by removing all code that is related to the accelerometer .... retain code for BLE communication ... send fixed values to the Cordova app – jsotola Jul 12 '18 at 18:44
  • @jsotola - thanks for the suggestion. I've tried that, and it's clear that the problem isn't related to the accelerometer. If I send hard-coded values on each loop - I still get the same error. Long story short - the Arduino should update all three characteristics with each loop. However, my Cordova app only receives one of those notifications. – mattstuehler Jul 12 '18 at 19:17
  • are you sure that the phone app actually expects more than one value? – jsotola Jul 12 '18 at 21:09
  • @jsotola - yup. The phone app does listen for all three notifications. I'm wondering if there's a timing issue. The Arduino app will update all three characteristics on every loop, so it's effectively sending out three notifications on every loop. Maybe that's 'too fast' for the phone app? Is it possible that the phone app can only process one notification 'per cycle', or something like that? See the update I made above for more detail... – mattstuehler Jul 13 '18 at 13:03

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Browse other questions tagged or ask your own question.