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.
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!
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()
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.
@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?
@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.
Because I'm lazy 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
@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.
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.
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.
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?
@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”!