Need Help Sending BLE UART Broadcast


#1

So I’ve been playing with all the current BLE examples that are available and they all work.

Now what I’m needing help with is creating a simple code template for broadcasting messages out over BLE UART so I can see this data stream using an app like Adafruit’s BlueFruit Application on my phone or tablet.

I know how to create formatted payloads for sending out Particle.Publish() events from my Photons, Electrons, and Borons.

Can somebody share a simple code snippet showing how we can broadcast a payload over BLE that’s similar to how we broadcast a payload out via Particle.Publish()?

I mainly would just like a easy way to broadcast something like:

Floats / for things like Voltage, Temp, Humidity, GPS coordinates…
Integers / for things like SOC 0-100…
Char / For sending out Text Characters and messages.

If anybody is up for this I’m sure it would be appreciated by all us not so advanced guys who are excited about the BLE features but are having trouble taking advantage of it.

@rickkas7 @ScruffR @bsatrom


#2

The Xenon running the BLE System Log app broadcasting every second consumes 3.5mA. Turning the RGB LED brightness down to 0 bringing the power consumption down to 2.5mA! Pretty impressive!


#3

BLE UART is not meant for broadcasting.
UART is a one-to-one connection.
If you want to broadcast you may rather opt for advertising the data.


#4

I’m glad you say that actually because I was thinking all the BLE connections were one-to-one only but with broadcasting it can be one-to-all messaging and that’s a new concept I need to wrap my head around and test out.

How would you go about broadcasting let’s say a payload containing The following data: 12.85v-10.97A-130.97W-78.9F-100%-FULL

Can we view a BLE Advertising Payload transmission burst using the Adafruit Bluefruit app the same way we use that app to see BLE UART Serial data?

For now I’m just wanting to make something simple like like have a INA219 voltage & current sensor connected to a Xenon and be able to broadcast the Voltage, Current, Wattage readings I can use something like the Bluefruit app to view the advertised readings every second.

What do you think is the best method to do this? It’s more complicated than setting up a simple Particle.Publish()


#5

I guess this would be the example that should get you started
https://docs.particle.io/tutorials/device-os/bluetooth-le/#device-nearby-beacon

However, you need to consider the limited space for advertising data (31 bytes minus some used by the default data leaving you with 24 bytes).
If you intended to add a device name that would count against that limit (plus 2 extra bytes).
With a custom app you’d also calculate the wattage instead of transferring it.


Try this

#include "Particle.h"

void setAdvertisingData();

float   volt;
float   amp;
float   watt;
float   temp;
uint8_t percent;

void setup() {
  setAdvertisingData();
  BLE.setAdvertisingInterval(130);                  // Advertise every 100 milliseconds. Unit is 0.625 millisecond intervals.
}

void loop() {
  static uint32_t ms = 0;
  
  if (!digitalRead(BTN))                            // use MODE button to reset the dummy data
    ms = 
    percent = 
    volt = 
    amp = 
    watt = 
    temp = 0;
  
  if (millis() - ms < 1000) return;
  ms = millis();
  
  if (percent < 100) percent += 5;
  volt    += 1.5;
  amp     += 2.5;
  watt     = volt * amp;
  temp    += 0.5;
  
  setAdvertisingData();
}

struct customData {
  uint16_t companyID;
  char     data[25];
};

void setAdvertisingData() {
  int                retVal = 0;
  customData         cd;
  BleAdvertisingData advData;

  cd.companyID = 0xFFFF;                            // undefined company ID for custom data

  memset(&cd.data, 0x00, sizeof(cd.data));
  retVal = snprintf(cd.data, sizeof(cd.data)-1, "%.1fV%.1fA%.1fW%.1fF%u", volt, amp, watt, temp, percent);
  Serial.printlnf("%s (%d)", cd.data, strlen(cd.data));
  if (retVal < 0 || sizeof(cd.data)-1 < retVal) {
    strcpy(cd.data, "too long! press MODE");
  }
  advData.appendCustomData((uint8_t*)&cd, 2 + strlen(cd.data));

  BLE.advertise(&advData);
}

I’m using Android nRF Connect App for continous scanning to see the changing readings.

If you sent the data raw (not as string - dropping the units in the process) and chose the minimal datatype required (e.g. instead of float an int16_t for “centiVolt” and “centiAmpere”) you could get more data in that constrained space.


BLE advertising only in listening mode
#6

Thank you! I’ll give this a try and report back.


#7

@RWB, do understand that the shorter the advertisement period, the more power the device will consume. @ScruffR, why the 100ms advertising interval when the data is only refreshed every 1000ms?


#8

Have you tested the difference? I’m seeing 2.5ma when broadcasting every 1 second using the log handler BLE example. In system manual.


#9

@RWB, with the device on all the time, that current sounds about right. You may want to consider disabling the RGB LED. If you sleep and wake every second to advertise then average consumption will be lower. I have not had the chance to test this yet.


#10

Because I’m lazy :blush: and I just took Rick’s original demo and took that part as is since the update interval nor the advertisment rate was the focus of the code.
However, I also wanted to have my test app see the ASAP :wink:


#11

I set the RGB LED brightness to 0 and that is what provided the 2.5mA. With the LED WHITE the current jumps up 1mA to 3-3.5mA.


#12

@RWB, if current consumption important? If so, advertise for 1 second (to make sure central gets the advertisement), sleep 1 second (or more), then repeat. That should bring the average current down.


#13

Yes, lots to play with and test now that the BLE is out.

I’m loving the low power levels and range you can get with BLE + External antenna.

Next thing I want to figure out how the iBeacon works, want to use that for advertising, like in a restaurant too push customers to a special offer webpage and gather their contact info so the restaurant can follow up later.

Something like this makes sense.


#14

I have the NRF connect app installed but how exactly are you seeing the data updates using the app?

Here is what I see when connected to the Xenon running the code above.

I can connect to the Xenon but I see no data updating.


I’m confused :neutral_face:


#15

You don’t need to connect to the device to get the advertising data you are just scanning.


#16

So are you just seeing the Hex data change? Or should it show up in Readable text?


#17

You can change the format to UTF8 to make it human readable.
Just tap the hex string and see the Select data format popup with the O Text (UTF-8) option appear.


#18

Man I still can’t get or see any changing data using the Nordic Connect app on iOS or Android. Can you share a screenshot of what it looks like on your end?


#19

Will do tomorrow - it’s late here :wink: :zzz:


#20

@RWB, @ScruffR, when I run the code @ScruffR and using nRF Connect on my Samsung A5, I see the serial output from the Xenon with the expected data. When the Xenon is booted with the nRF app running, I see the BLE device and I can see the data (payload) changing a few times and then it “locks up” with the “too long! press MODE” message, as expected since the voltages, etc. are fabricated and not real values. When I press the mode button, the data again changes as expected. Now, we just need to make the data “real”!