paypal / gatt

Gatt is a Go package for building Bluetooth Low Energy peripherals
BSD 3-Clause "New" or "Revised" License
1.14k stars 285 forks source link

BLE, scanning interval #96

Closed wopol closed 4 years ago

wopol commented 6 years ago

Hi everyone. I would like use this library to my project but i have problem with scan interval. I would like scanning all ble devices in range ma scanner(raspberry pi) online. My device emit advertising packet every 350ms, but in my simple application i see this packet every 2-4 s. have any idea why ?

andrei-pavel commented 6 years ago

If you're interested in improving the successful scan frequency, consider advertisement shuffling in which you advertise as two or more beacon types alternatively. I've witnessed this being a breakthrough in a project.

If battery or packet storming are not issues with your setup, consider reducing frequency as low as possible, 20ms if you can. Magic numbers like 350 make no sense to me for performance.

Try these two and report back? Otherwise, are you interested only in the reason for the discrepancy? I could list the few.

roylee17 commented 6 years ago

The more recent endeavor for BLE on Go could be found at

https://github.com/currantlabs/ble

or

https://github.com/go-ble/ble

Example for tuning advertising/scanning parameter can be found in the examples.

https://github.com/currantlabs/ble/blob/master/examples/blesh/lnx.go

Hope this helps

wopol commented 6 years ago

@roylee17 - Thanky for yor response. I think that it will help me. I'am testing "ble" library, and i am satisfied. Performance is very well. I am just wondering about one thing. Very often i recived packet from the same device almost at the same times(please see logs below). Should i care about this ?

11:56:57.086 - id 43667-9401, Rssi:[-87] 11:56:57.088 - id 43667-9401, Rssi:[-87] 11:56:57.256 - id 9771-15599, Rssi:[-57] 11:56:57.258 - id 9771-15599, Rssi:[-57] 11:56:57.721 - id 43667-9401, Rssi:[-81] 11:56:57.723 - id 43667-9401, Rssi:[-81] 11:56:57.885 - id 9771-15599, Rssi:[-56]

@andrei-pavel Thank you for tips. Unfortunately in my project i can't use advertisement shuffling, but scanning interval for 1 s is enough for me. Also i would like save battery level, therefore i think that 20 ms scanning interval is good, but that's not always the case. In my opinion this this case good describs this photo: https://support.kontakt.io/hc/en-gb/article_attachments/200523562/interval_post_path.png.

I am interesting why there are so big difference between emit interval and recive. If you know, I'd like to hear it.

roylee17 commented 6 years ago

The duplicates are normal. For example, if you're scanning for 1s and the device advertises every 250ms for 50ms, then you will see 3 advertising events reported.

There is an scanning parameter/option to control if the dups are reported or not.

wopol commented 6 years ago

Important for my is to receiving advertisement packet constantly. If I use dups parameters to avoid duplicate, i should get only one packet, but that is not always the case. If i set dup on false, i always received two packets from one device. Packets are received almost the same time.

roylee17 commented 6 years ago

I see. Those two packets are actually "advertising packet" and "scan response".

In ble, we report it as two separate events (as HCI does). But the second event MAY provide more data available, as by default we only extract the common fields that are available on both MacOS and Linux.

type Advertisement interface {
    LocalName() string
    ManufacturerData() []byte
    ServiceData() []ServiceData
    Services() []UUID
    OverflowService() []UUID
    TxPowerLevel() int
    Connectable() bool
    SolicitedService() []UUID

    RSSI() int
    Address() Addr

If you need more flexibility, you can convert ble.Adevertisement into adv.Packet for packet manipulation.

ex:

func advHandler(a ble.Advertisement) {

   p, ok := a.(*adv.Packet)
   if !ok {
       // only supported on Linux
   }
   // refer to ble/linux/adv/packet.go for examples of extracting data fields from raw packets.
wopol commented 6 years ago

I catch that, Yes, you have right. Beacon additionally send response scan packet. This should be it. Thank you.