I finally found out that of the 31 bytes of the advertised payload, 5 bytes are used for information such as flags and data length, 16 bytes are used for UUID128, and only 10 bytes are available for data transfer. It seems that I still need to transfer data using the scan response as well. I am working on the code now.
Perhaps we can eliminate the UUID128 and only send the packet as a manufacturer specific data (MSD) packet. Use the manufacturer ID as the filter to receive the packets. Pretend to be one of the below companies:
BLE Company ID
Hi hobbya,
Thanks for the spot-on tips.
I was able to get 24 bytes of payload using filter.MSD().
Once I measure the current consumption, I will post the results comparing connecting vs. advertising.
Excellent msfujino !! Your examples will certainly benefit other users who are still struggling. It is always a pleasure to see how other fellow hobbyists develop their interesting applications.
@msfujino
I was able to get 24 bytes of payload using filter.MSD().
For non-connectable advertisements, the flag can be ignored. You can gain a few more bytes to the payload by not sending the flag.
I have considered a method to advertise a small amount of data (up to 24 bytes) added to the MSD(Manufacturer Specific Data) without connecting to Central. Peripheral advertises with data on them unilaterally, and Central retrieves it from the scan data without connection.
The experimental conditions were
BSP : Seeed nRF52 Boards 1.1.1
Board : Seeed nRF52 Boards / Seeed XIAO nRF52840 Sense
System ON Sleep : Using RTOS delay()
Task : Send 8 bytes of data every 10 seconds
Current reduction measure : Turn off the blue LED used for BLE, On-chip regulator is in DCDC mode, On-board Flash is OFF
Measurement: 3.00V applied from pppk2 to 3V3 pin of XIAO
The current consumption for normal connection and transmission was 261uA, and a significant reduction of 20uA when transmitting only by advertisement.
In this experiment, Peripheral advertises 10 times every 10 seconds to ensure that Central captures Peripheral in a reliable scan. The number of times is a tradeoff between reliability of data transfer and current consumption.
In the previous experiments I have posted, I used WFI() and TRC interrupt for System ON Sleep, but from this experiment, I used RTOS’s delay(), which consumes much less current.
While delay(), Peripheral consumes almost no current other than RTOS current since there is no BLE connection.
I think 4uA is comparable to Deep Sleep.
nRF52_XIAO_LightSleep_AdvScan.zip (4.4 KB)
Hi hobbya,
Thanks for the info on FLAGS.
The next topic is data transfer in the case of multiple peripherals.
If I understand correctly, the default advertising type set by Adafruit is: BLE_GAP_ADV_TYPE_CONNECTABLE_SCANNABLE_UNDIRECTED
Within an advertising interval, the peripheral will first transmit on ch37 and switch to receive mode to listen for any scan/connect request; it then will repeat the same again on ch38 and ch39.
If we do not need the packet to be scannable/connectable, we should be able to set the type to:
BLE_GAP_ADV_TYPE_NONCONNECTABLE_NONSCANNABLE_UNDIRECTED
I suppose the peripheral’s radio will only transmit on ch37, 38, 39 and will not enter receive mode. Not sure if this can further lower the power consumption. I do not have the tools with me to verify the idea but at least the code compiles and the packet can be received by the central.
Bluefruit.Advertising.setType(BLE_GAP_ADV_TYPE_NONCONNECTABLE_NONSCANNABLE_UNDIRECTED);
Bluefruit.Advertising.restartOnDisconnect(true);
Bluefruit.Advertising.setIntervalMS(100, 100); // in unit of ms
Bluefruit.Advertising.setFastTimeout(5); // number of seconds in fast mode
Bluefruit.Advertising.start(5);
I tried a simple test and 20uA is down to 17uA.
Thanks for the update. Indeed it will be interesting to see if the advertising performance is still acceptable with multiple peripherals in the surrounding.
Have a great weekend.
Wow, that’s epic and I’m lurking HARD for the multiple peripheral magic
can you answer or comment on this ;
If I have 4 BLE devices in a case. The devices could advertise there status WITHOUT any connection and my Central app could connect Only when the Status from an advertising peripheral indicates a need? (all while using the least battery)
Does this seem reasonable to you GURU’s
So even the Alarm conditions could be Boolean advertised data bits ?
I need to look over the BLE spec on the topic. I like the approach though over a scan & connect and NOTIFY for Alarm data *(you have to be connected to get it)
You guys are doing the Yomans Work , Thank You for sharing the enlightenment
it definitely inspires and helps MyCode.
GL
PJ
PJ the on-air behaviour of the BLE radio is governed by softdevice and the user has to choose a behaviour which meets his application.
There are 2 types of scanning method by the central: passive scanning and active scanning. The last example released by MJ was based on passive scanning. This means the central is waiting passively for updates transmitted by the peripheral. The peripheral transmits advertising data packets whenever itself wants to and will not care if the transmitted packets will reach the central. Since there is no handshaking between peripheral and central, the peripheral can operate under the lowest possible consumption. Passive scanning is a good match if the application can tolerate data loss and latency.
Active scanning allows the central to play a more active role. Upon receiving an advertising data packet, the central can send a “scan request” to peripheral and peripheral will transmit another advertising packet (scan response) which carries information not covered by the previous packet. Each advertising packet payload is limited to 31 bytes which includes both the overhead and real data. Active scanning allows 2 rounds of advertising or 62 bytes. If the application requires more data or if the central wants to transmit back to the peripheral, a connection is needed. Central will send a connection request to peripheral and once the connection is established the two ends can exchange information in either direction.
All the advertising packets by any BLE devices are transmitted over channel 37, 38, 39. So the peripheral has no idea if its advertising data collides with other users’ peripherals. The central also listens to whatever peripherals. This is why the BLE data rate is high and the packet length is short, it is to avoid collision. To make the central’s life easier, the advertising packet transmitted by the peripheral is divided into different types. For instance if it is non-connectable and non-scannable, central will not bother sending a scan request or connection request.
MJ’s first example is based on connection operation. The advertising packet is connectable and scannable. When the central sees the advertising packet, it will request a connection to collect the data. A connection guarantees the data to be securely exchanged between the two ends because they will negotiate to operate on the other RF channels, no longer limited to 37, 38, 39. It is not surprising that the consumption is higher as more handshaking is involved.
Going back to your question, you have to determine if you can tolerate loss of alarm update using passive scanning. There is no assurance that the central can receive the update every time since the 4 peripherals may compete to transmit to the central if they wake up at more or less the same time. The BLE protocol has automatically added a random delay to the advertising packet to reduce the chance of collision among devices. It is a good approach if there are not many advertising devices in the surroundings. In case collision happens and the advertising cycle is short say 10s then you still have the chance in the next 10s but if the cycle is 1 hour then you have to wait until next hour. In MJ’s example, the peripheral transmits for 1s over every 10s. The transmit interval is 100ms so there are 10 advertising packets sent out over 1s. You can increase the hit rate by extending the 1s duration or to lower the transmit interval (20ms minimum) and of course central will pick up duplicated packets. In other words passive scanning makes use of simple excessive advertising to increase success rate. You can work out the mathematics for the probability but it is more practical to adjust through trials in the actual environment.
That’s a very interesting discussion. I want to build a datalogger for outdoor/cave. To collect data, one will connect to the logger through BT/BLE with a smartphone. My initial idea was to add a button. You press the button and it is starting BT/BLE connection. But if I can avoid the button, I can simplify sealing. So, the logger can send through BLE an advertising packet each 60 s. If a smartphone in the vicinity act as central active scanner, it can start establishing connection and collect data (and configure the logger). Overall, I will stay with a low power consumption (~20 µA). Is my approach right?
Hi Eric_S,
If the battery capacity is small, it is recommended to use passive scan. Peripheral advertises unilaterally every 60 seconds and Central reads data in passive scan (without establishing a connection). If there is enough battery capacity, it is better to have an active scan and properly connected.
I have experimented with Central’s passive scanning of 4 Peripherals.While the advertisements from 4 Peripherals sometimes overlap, at least more than half of them seem to be captured by Central.
The settings that seem to be involved are as follows.
Data length is 28 bytes
Bluefruit.Advertising.setIntervalMS(100, 100);
Bluefruit.Advertising.setFastTimeout(1);
Bluefruit.Advertising.start(1);Bluefruit.Scanner.setIntervalMS(50, 25);
@PJ_Glasso , it seems I cannot edit my post after a certain period.
Just an amendment: in each round of transmission the peripheral transmits alternatively on ch37, 38, 39 the same advertising packet. So actually total 30 identical packets are transmitted over the 1s interval in MJ’s example.
I think, I didn’t explained well my project. Let say, I want to record temperature. Each hour, the board record a temperature and store it internally (in the QSPI Flash memory). One or two times a year, I will visit the logger on field. I will transfer data from the logger to a smartphone. So most of the time, the logger don’t transmit data. It is just waiting for a connexion. Once the connexion is established, I don’t care too much on power consumption (although it should not drain the battery in one minute). So, how can I set some kind of “wait for connexion” with a low power consumption?
Eric_S,
The easiest way would be to connect a switch to the board and wake it up with a switch interrupt to initiate the connection. Or the board should advertise periodically regardless of whether Central is around or not.
To my knowledge, I can’t think of a way to wake up a board that is sleeping from central.
If anyone has a better idea, please advise.
msfujino,
I first implemented the switch solution, on adafruit boards at that time but stopped development due to high power consumption. Now, with the XIAO board, I can do the same. But I would also like to avoid the switch. So advertising each minute all the time and, if a Central active is present, the Central may take the opportunity to establish a connexion after catching an advertising packet.
As XIAO advertises every minute, current consumption increases, is this acceptable? To reduce current consumption, it would be better to reduce the number of advertisements per minute.