Sharing of one BLE Device possible for multiple Datafields

Hi,

my question is something related to: https://forums.garmin.com/developer/connect-iq/f/discussion/265024/multiple-data-fields-from-single-ble-connection

I have one BLE Device. It should be accessed by multiple different data fields.

Each data field is responsible to handle its own connection (this differs from the other referenced post)

I thought if one data field is not active, that it will disconnect from the BLE device (and gives the new active data field the chance to connect.)

But this does not work.

The first data field will connect, and keeps the BLE connection active during it is in background.

Is there any possibility to close the BLE connection when the data field is not active, or any other ideas?

Thanks in advance.

Best Regards Sven

  • All data fields added to an activity are active. Their constructor is called, and compute is called every second, even if they are not visible because they are on another page.

    Not sure how you imagined this. Are you displaying data sent via BT? Why do you need more than one DataField? 

  • Thanks for feedback, and sorry for late reply as I was off some days:

    "Not sure how you imagined this"

    => I tried it out, I created two DataFields nearly same code accessing the same BLE device. The first DataField gets the BLE device, the second can not connect as there is already a connection.

    "Are you displaying data sent via BT? Why do you need more than one DataField?"

    => I have one BLE device which is something like a gateway. It collects a lot of boat data (similar to the Garmin GNT-10) The amount of data does not fit to one DataField, so I need multiple DataFields for different kind of data which is send by this central gateway.

  • So either you can modify the code of the device to act as it was multiple devices, and broadcast parts of the data via a different address, or you'll need to think of a different way...

    I haven't done this but I read in the forum that others have similar issues and they do something like:

    1. let's say you have now a full screen DF, and there's some more (but not much) data that doesn't fit, you could add the same DF to the next page under a different layout (let's say "2 fields"), and differentiate between the full screen and the half screen "instance" of the DF by the width/height and display the necessary data accordingly. This won't work if the dimensions * the  of the fields in the layout are identical. (On non-rectangle watches you might be able to see some differences with getObscurityFlags() but it's less reliable and won't work on rectangle devices)

    2. you can have a "timer" (no need for real timer, just compare the seconds) and switch between 2 or more "virtual pages" and let's say every 3 second display something else. It has the obvious disadvantage that you might need to wait to see what you want.

    2.b. some add some spice to this and also look at the time the DF became visible. This way you can send "input" to the DF by clicking the up/down buttons. This switches the pages, and if you detect that your DF was switched to rapidly twice within 1 seconds then you interpret it as a request to change the page you display. This way when you go up/down between multiple pages "slowly" you'll still see the same virtual page you saw last time, but if you want to switch to the next virtual page then you click up and then down quickly, and then display the next page.

    3. on newer watches (and edges) you might be able to use onTap

  • Thanks for fast and extensive feedback and options, I really appreciate this!

    I also thought about similar options. I will check if it possible for the BLE device to accept multiple connections, this would directly solve the topic. As the development of the BLE firmware is on my hand this is a possible option.

    Option 1: I need to think about it. It sounds like a workaround. My scope is just watch with round screen, so in general a option.

    Option 2: No option as sometimes I have to focus on dedicated values

    Option 3: This I will try out, if this. is a practical MMI solution.

    In general I think this is a generic problem. as DataFields does not have Input capabilities.

    Maybe is there any API that gives feedback if the DataField is active on the screen or in background?

    If yes I could try to release the connection as long as the DataField is in background, reconnect if is the active screen again (Depends how fast the reconnection to the BLE Device can be established.)

  • Some BLE sensors support multiple connections, but from what I've seen most don't.  Things like the HRM 200 do, but that's so it can be connected to a watch and phone at the same time.  I've never seen a case with the same garmin can connect to the same sensor twice at the same time.

    I think by "background" you mean on a data screen you aren't looking at with that data field. Buy you may want to consider using background services, where each runs at most every 5 minutes, can run at most 30 seconds at a time, and does the pair/read data/unpair during that 30 seconds.  Even if you have two running every 5 minutes, they will run one after the other, so both won't be at the exact same time.

  • You do know if your DF is visible because onUpdate is only called then. compute is called always, even when not visible

  • Thanks for the feedback,

    maybe I need to be more precise:

    With background I mean the DataField, that is part of the current activity (can be selected via up/down), but not on the screen now. The active DataField I mean the DataField that is currently displayed.

    Maybe some details on my project:

    A ESP32 collects boat realtime and sensor data via NME0183, and forward it to BLE as a gateway.

    The data relates to different categories. The different categories implemented in different DataFields.

    eg. one is for Depth and Water Temperature, the next one for speed and trip counter the next for voltage environment data.

    I want to navigate thru the different DataFields via Up/Down like the other pages in the activity.

    There is no processing or storing of the data needed inside the DataField if it is not on the screen. It just needs to display the received Data on the screen, when the DataField is on the screen

    If I understand you correctly you would "release" the connect for some time, but this is not possible due to realtime data.

    If I could identify if a DatField is "On the screen", than I could just connect to the BLE if needed.

  • Look at using background services.  "real" backgrounding.  What prevents a user from using two of your data fields on the same data screen?

    Here's a watch face I did years ago with a background service to get BLE data from a Thingy52 which could help:

    https://forums.garmin.com/developer/connect-iq/f/discussion/8182/a-very-simple-wf-with-a-background-that-talks-ble-to-the-thingy52

    Same basics if you want to use a background service in a data field.

  • Sorry, seems again I withheld an important part of my current concept. A DataField is not used as one Data element in my case. It is used as a single let me call it "page" with its own layout and multiple values in it.

    So you are right I can not prevent to have multiple DataFields in one screen, but because of the "full screen" oriented layout it makes no sense in my case.

    Thanks for the Link, I will check this. In the past all my problems posted in this forum where finally answered by you....

  • If I could identify if a DatField is "On the screen", than I could just connect to the BLE if needed.

    You *kind of* can, as flocsy said.

    While a CIQ data field is visible, onUpdate will be called roughly once per second. While it isn't visible, onUpdate will not be called.

    Additionally, onShow and onHide may be called when the user scrolls to/away from your data field. I wouldn't really want to rely on this, as the behaviour can vary from device to device. For example, iirc, on old devices like FR935, onShow is called zero times when the user scrolls away from your data field, while on a newer device like FR955, onShow is called multiple times when the user scrolls away.

    You could have an algorithm like this, which only relies on onUpdate():

    - in onUpdate() (called roughly once per second while the data field is on the screen), save System.getTimer() to a class variable named lastUpdate. System.getTimer returns the system uptime in milliseconds.

    - in compute() (called roughly once per second), check System.getTimer() and compare it to lastUpdate. If System.getTimer() - lastUpdate is greater than some threshold (say, 5000 ms), assume that the data field is no longer on the screen, and disconnect the BLE connection. Set a class variable to indicate this state (e.g. disconnected = true)

    - also in compute(), if disconnected is true, and onUpdate() is called for 5 consecutive seconds, try to connect with BLE again

    This might be tricky in practice, but it could work. You might want to tweak the 5 second threshold to make the disconnect/reconnect actions more or less responsive. It probably has to be around 1.5 seconds to avoid false disconnects though.

    The one problem I can see from the user's pov is that even if you make the threshold as small as possible, the user still has to wait for the BLE connection to be established before they will see data, after they scroll to a given data field.