I have an Android device broadcasting a BLE advertisement using the following commands of AltBeacon library:
ADVERTISE_MODE_LOW_LATENCY approx 1 Hz
ADVERTISE_MODE_BALANCED approx 3 Hz
ADVERTISE_MODE_LOW_POWER approx 10 Hz
I would like to increase this frequency more than 10 times per second. Is there a way to increase advertising frequency in Android? Or it is unchangeable?
You can reach it with stopping and starting advertisement with code like this:
while (true) {
beaconTransmitter.stopAdvertising()
beaconTransmitter.startAdvertising(beacon, object : AdvertiseCallback() }
The different options you have shown that work with the Android Beacon Library's BeaconTransmitter class are built-in to Android. Unfortunately there are no other higher frequencies of transmission offered by Android APIs.
However, on many newer devices you may start more than one advertiser at a time. If you have a device like this (Pixel, Nexus, Galaxy, Nokia) you can simply start more than one BeaconTransmitter instance at a time, each set to advertise 10Hz. If you start 10, you effectively get advertising at 100Hz.
Related
I created an android (java) application that uses the altbeacon library (github page) to detect beacons via the Bluetooth module.
The Beacons are configured with Eddystone UID, protocol with an advertising interval of 100ms and transmit power level of strong (10dBm).
What I would like to be able to do is to detect the RSSI value of the beacons with a frequency of 10Hz (i.e. 100ms).
I've already prepared a service that implements the altbeacon library, the relevant part are showed below:
mBeaconManager = BeaconManager.getInstanceForApplication(this);
beaconRegion = new Region("beacon_region", null, null, null);
// use Eddystone protocol
mBeaconManager.getBeaconParsers().add(new BeaconParser().
setBeaconLayout(BeaconParser.EDDYSTONE_UID_LAYOUT));
mBeaconManager.setAndroidLScanningDisabled(true);
mBeaconManager.setForegroundScanPeriod(100l); // scan frequency
mBeaconManager.setForegroundBetweenScanPeriod(0);
and the callback didRangeBeaconsInRegion from which I see the beacons and get the RSSI value is this:
#Override
public void didRangeBeaconsInRegion(Collection<Beacon> beacons, Region region) {
Log.i(BeaconDataCollectorService.class.getSimpleName(), String.format("Found %s beacons in range", beacons.size()));
}
What's my problem?
Running the app, I notice that within didRangeBeaconsInRegion, I often don't see all the beacons.
I ran the data collection for a few seconds, creating a csv format of the data obtained, where you can see that I often have 0s (indicating that the beacon was not detected); I put the sharing of this csv on pastebin (https://pastebin.com/zkUZC5R4)
How can I improve the scan frequency by always being able to detect all the beacons?
altbeacon version used:
implementation 'org.altbeacon:android-beacon-library:2.16.3'
Android version: 9
Thanks
Unfortunately, the library is not designed to do this, as the ranging APIs are modeled after iOS equivalents which give aggregate detections at fixed intervals as opposed to access to individual packets when they arrive.
The main reason you often get 0 beacons detected with such a short scan period is because the scan is turned on and off every 100ms, and it takes 10ms or so to start and stop. This gives a good probability of missing the detection.
Here's the good news: If the library ever detects two beacon packets in the same scan period then it will stop turning the scan off and your detection rate will improve. But getting it to detect two beacons in 100ms is nearly impossible of your beacon advertises at a nominal 10Hz.
One thing you might try is to start by setting the scan period to 1 second. After you have detected a finite number of your beacons for 10 secs or so, there is a very good chance you will have detected two beacons in one scan cycle and then you can switch to a scan period of 100ms and get a higher detection rate.
You will never get a 100% detection rate for two reasons:
Not all beacon packets transmitted are received due to collisions and radio noise. At close range 80-90% is typical.
"BLE advertisers do not advertise at regular intervals. They randomize when their packets are sent to avoid collisions. A nominal 10Hz transmitter might have anywhere between 70ms and 140ms between individual packets, so for fixed scan cycles of 100ms sometimes there will be 0, 1 or 2 Packers eligible to be received.
If you really need to get callbacks on every detection, you might try setting up a NonBeaconBleScanCallback in the BeaconManager, then calling BeaconManager.clearBeaconParsers(). This will cause all beacons detections to be sent to that callback immediately when detected. You will then have to construct a new BeaconParser for use inside that callback to decode the beacon from the raw packet. Use beaconParser.parse(...)
I use android phone to detect a beacon using startScan method, the interval time of beacon adversing is 800ms, but I got the beacon data from callback of startScan every 3~10 seconds. My expectation is I can get the data every 1 second.
Below is my codes. So is there any other ways to get my expectation. Or someone can explain why the interval time is not the same as the adversing time ?
ScanSettings.Builder builder = new ScanSettings.Builder()
.setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY);
// scan filters has been set the right value.
bluetoothLeScanner.startScan(scanFilters, builder.build(), scanCallback);
Nothing about the code shown is a problem. I can confirm your expectation is met with equivalent code in other apps on other devices. This suggests a problem with :
Your BLE device not advertising as often as you expect
Your Android phone (possible but unlikely)
Some other aspect of your code that you did not show in your question.
Is you BLE device a beacon? If so, I suggest:
Install BeaconScope on the same phone, scan for your beacon, then check the PPS rating (Packets Per Second -- scan for at least 30 seconds until the measurement stabilizes). If you see a value of 0.1-0.3 then the problem is NOT with your code and must be (1) or (2). If you see a much higher PPS value, the problem is with some other aspect of your code not shown.
Use a second Android phone with BeaconScope as a transmitter and transmit a beacon at the 10 Hz default rate. Does your app get a packet every 100-200ms? If so, you have confirmed the problem is with your BLE device not transmitting as much as you expect.
If your BLE device is not a beacon you can at least perform the second test.
It's recommended to use 'SCAN_MODE_LOW_LATENCY' mode only hen the application is running in the foreground.
Incase you are in background, you can run a sticky foreground service and set a periodic frequency of 1 sec for your service.
Also scanning Ble for every 1 sec might be extremely heavy for the app.
Hello I am poor at English.
I use Android Beacon Library
implementation 'org.altbeacon:android-beacon-library:2.15.2'
My Android application gradle imformation
compileSdkVersion 28
minSdkVersion 21
targetSdkVersion 28
My Beacon manager information
beaconManager.getBeaconParsers().add(new BeaconParser().setBeaconLayout("m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24"));
beaconManager.setForegroundScanPeriod(1100L);
beaconManager.setBackgroundScanPeriod(1100L);
beaconManager.setForegroundBetweenScanPeriod(0);
beaconManager.setBackgroundBetweenScanPeriod(0);
beaconManager.enableForegroundServiceScanning(notificationcompatBuilder_Scannging.build(),456);
beaconManager.setEnableScheduledScanJobs(false);
BeaconManager.setDebug(true);
regionBootstrap = new RegionBootstrap(this, myBeaconRegion);
Error
I want to develop all day beacon scanner application.
So I use regionBootstrap to scan in background.
It looked like it was working.
However time passed and Exit Event suddenly occurred and Enter Event occurred shortly after.
I think scan does not work for a few seconds and I have conducted a test on this.
Error Test 1
one smartphone , two beacons
Error1
One beacon signal is not detected for more than 10 seconds while another beacon signal is detected.
So I think scan work well and it is a problem of beacon.
Error Test 2
two smartphone , two beacons
smartphone 1
enter image description here
smartphone 2
enter image description here
In smartphone 1 Logcat, Also One beacon signal is not detected for more than 10 seconds while another beacon signal is detected.
In smartphone 2 Logcat, Unscanned beacon is being scanned at the same time.
So beacon does not problem and I can't find reason.
Error Test 3
Added test
two smart phone
My beacon transmit the signal about once every three seconds.
In smart phone 1, download the other beacon application which has beacon signal transmit and transmit at 1Hz.
In smart phone 2, by using my application, watch the signal.
enter image description here
The beacon signal of smart phone 1 increase markedly, but the same problem arose.
Does anyone know about this matter?
I want a help...
Please
I suspect that the beacons you are using to test are not transmitting frequently enough. Manufacturers often reduce the transmission rate to save battery. When the transmission rate gets below 1Hz, this can cause problems, because not 100% of beacon packets transmitted are received by any phone. Radio noise often causes packets to be missed. If one device misses a few packets in a row (it happens sometimes) it causes a region exit event.
The solution is to increase the frequency at which the beacons transmit. With some manufacturers this is configurable. With others, it is not. If it is not configurable, you may need to buy different beacons
You can test if this is the problem by using an Android beacon simulator app on one of the devices. Try my BeaconScope app, which will advertise at 10Hz by default.
This library return result only when a specific event is triggered, not for all beacon scanned.. if you need this I suggest you to use the standart android standard beacon library, if you want to know more about this and how to implements comment this post and I'll edit it with the implementation
I am attempting to intermittently scan for nearby beacons and store off every received beacon with a particular manufacturer code. How do I use the altbeacon Library to start and stop scanning for altbeacons with a specific manufacturer code and store off every received beacon during each scan? I would like for the scanner to scan for 20 seconds every 5 minutes after the activity has been created.
#davidgyoung
For the manufacturer code 268 (hex 0x0112), you can match this with the following BeaconParser setup code:
beaconManager.getBeaconParsers().clear();
beaconManager.getBeaconParsers().add(new BeaconParser().setLayout("m:0-3=1201beac,i:4-19,i:20-21,i:22-23,p:24-24,d:25-25"));
Note that in the layout string, the two hex bytes of the manufacturer code are put as the first part of the "matching" m expression m:0-3=1201beac. They are in reverse "little endian" order because this is how they appear in the packet. So 0x0112 becomes m:0-3=1201. Similarly if you were using radius networks 0x0118 company code, you would use m:0-3=1801.
The regular ranging APIs will return you a list of all beacons that match this. To scan for 20 seconds out of every 5 minutes, simply use:
beaconManager.setForegroundScanPeriod(20000l); // 20,000 ms
beaconManager.setForegroundBetweenScanPeriod(280000l);// 280,000 ms + 20,000 ms = 5 minutes
I've got a problem. I'm developing an android application that scans for wireless accesspoints/routers. I've been testing a couple of devices and I'm getting scan rates of 2, 1, 0.5, 0.1 etc. scans per second.
My goal is to reach 10 scans per second because a router can send beacons 10 times a second. And we need this for our application.
Is there away to make this possible? Perhapse hack a rom and replace the wifi drivers? I've been looking in to this but I can't find anything about this frequentie inside the driver.
The driver used is BCM4329 driver, I can't find any datasheets of the BCM4329 so it's kinda hard to figure this out.
Thanks in advance.
flitjes
I'm not familiar with driver development but I know it's one of the hardest thing in computer science so unless you have good knowledge in linux kernel development I would forget about it.
Moreover, you still need to scan the 12 Wi-fi channels to be sure that you are detecting all access points. An access point broadcasts a beacon every 100ms * 12 channels = 1.2 seconds. Spending less time than that and you risk missing access points.
You don't need to change anything in the device driver, Android makes it available to you to scan for access points. See the documentation.
Although requesting that many scans will probably not be very good for the battery life and the responsiveness of your app...
Your assumption that beacon rate is 10 per second is incorrect. This is really an AP configuration parameter, although 10 per sec is default in most. Besides that, APs do not send beacons simultaneously, if this happens, it's called a collision and a back-off algorithm is used for retransmission. In addition, even scanning 10 times per second doesn't make it certain for you to capture all beacons, like was pointed out in the previous answers.
if u use 4339 driver, you could not set the scan rate in driver or android api which is fixed in 4339 firmware, scan is about all channels && time u spend on each channel, according to the 80211 spec, which is part of mac && phy. in this case u just need to get the beacon, so u should use passive scan and use fixed channel && MaxChannelTime u want.
u have to ask broadcom for speical fw to figure out your problem,
IEEE
Std 802.11-2012 page 978
10.1.4.2 Passive scanning
If the ScanType parameter indicates a passive scan, the STA shall listen to each channel scanned for no
longer than a maximum duration defined by the MaxChannelTime parameter.