3

I am attempting communication with an arduino using an Adafruit Bluefruit LE (a bluetooth 4 module), everything is set up and paired and all that, but I'm having trouble with the ValueChanged event on my GattCharacteristic, it stops firing after somewhere between 30 and 40 times.

Below is the setup code for this:

public class Bluetooth
{
    async public void Initialize()
    {
        var devices = await DeviceInformation.FindAllAsync(GattDeviceService.GetDeviceSelectorFromUuid(new Guid("6E400001-B5A3-F393-E0A9-E50E24DCCA9E")), null);

        GattDeviceService firstService = await GattDeviceService.FromIdAsync(devices[0].Id);

        GattCharacteristic rxCharacteristic = firstService.GetCharacteristics(new Guid("6E400003-B5A3-F393-E0A9-E50E24DCCA9E")).First();

        await rxCharacteristic.WriteClientCharacteristicConfigurationDescriptorAsync(GattClientCharacteristicConfigurationDescriptorValue.Notify);

        rxCharacteristic.ValueChanged += rxCharacteristicValueChanged;
    }

    private void rxCharacteristicValueChanged(GattCharacteristic characteristic, GattValueChangedEventArgs e)
    {
        Console.WriteLine(e.CharacteristicValue.ToArray()[6]);
    }
}

Is there some kind of buffer I need to clear or something like that? It doesnt look like its buffer related, because If I halve the data being sent, I dont get twice the calls, but I could be wrong. The Arduino reports that it is still sending data (through a serial link, I can see that the bluetooth library is still attempting to send data, at any rate. I am not sure how I would verify that the data is actually getting sent)

Any help would be appreciated, even suggestions on things to check.

Patrick
  • 697
  • 2
  • 9
  • 19
  • What else is your program? Please show [a minimal, complete code example](http://stackoverflow.com/help/mcve) that reliably demonstrates the problem. For what it's worth, I have done something similar and _not_ noted any interruption in notifications, even after an extended period of time. In my code, I do subscribe to the `ValueChanged` event before changing the configuration instead of after, but I don't see why that would matter. All I can think of is that in your program, you execute some other code that somehow interferes with/disables notifications. – Peter Duniho Feb 05 '15 at 01:54
  • @PeterDuniho There shouldnt be anything else in the code that interferes. It is a fairly standard openTK setup. I will work on getting a minimal example, but I've got a fair amount of unrelated code here so it will probably take a little while. – Patrick Feb 05 '15 at 02:04
  • @PeterDuniho Ok that is weird, commented out a fair amount of code and now it works. There shouldn't be anything that interferes here. I guess process of elimination then. – Patrick Feb 05 '15 at 02:07
  • Yup...that's one major value of a minimal, complete code example. It forces you go through that process of elimination. When done correctly, it often leads to the person with the question solving the problem all on their own. In those cases where it does not, then you at least wind up with a good code example with which to present your question, and your question can be more specific than just "why doesn't this work", i.e. you can point exactly to the part of the code that is causing the problem and ask for help with that part. – Peter Duniho Feb 05 '15 at 02:10
  • @PeterDuniho unfortunately it doesn't seem that simple in this case. It appears to be related to the number of things I am rendering to the screen. The more things rendered, the less callbacks I get. What I don't get is how these two things are related to each other. I was under the impression that the callbacks for the bluetooth device were in another thread completely. – Patrick Feb 05 '15 at 02:27
  • @PeterDuniho Alright, I have a more minimal example that still demonstrates the problem. unfortunately its still 10 files, and several hundred lines. How should I post it? – Patrick Feb 05 '15 at 03:08
  • Sorry to say (and granted, I am far from the last word on the question), but I think that if the problem is reproducible _only_ with a code example of several hundred lines of code, it may be "too broad" for StackOverflow. Do please note that "minimal" is an absolute, like "unique" or "best"...something either is or isn't. So if your current example is merely "more minimal", it may yet be possible to create a true minimal example. :) When you say "rendered", what are you actually using for output? From your code example, I was under the impression this was a console program. – Peter Duniho Feb 05 '15 at 04:23
  • Sounds GC related given your code. Make `firstService` or something else a field-level instance. Also make sure the issue is no on the Arduino side. My BlendMicro had some seriously crap 'supportware' that I had to fix. – leppie Feb 05 '15 at 04:59
  • @PeterDunniho, as I mentioned, it uses opentk, which is an opengl wrapper. Most of the code is support code and is reasonably logically laid out. I will however keep reducing it later tonight and post my results. – Patrick Feb 05 '15 at 11:12
  • @leppie that is an interesting idea, I will try it later. Thank you for taking a look. – Patrick Feb 05 '15 at 11:14
  • 2
    @leppie you are a gentleman and a scholar, that was the problem. Make it an answer and I will accept it. – Patrick Feb 05 '15 at 21:07

2 Answers2

9

Sounds GC related given your code.

Make firstService or something else a field-level instance.

leppie
  • 115,091
  • 17
  • 196
  • 297
  • Hi. What is the changed version of your code ? what do you mean by making field level instance? – mr. Apr 04 '17 at 13:58
  • I mean if i use multipe ble device with same value change event, how can i use field-level instance? – mr. Apr 04 '17 at 14:04
  • hi @Patrick i have similar problem can you give me any advice? – mr. Apr 05 '17 at 07:01
1

This is scoping issue, it seems that the GattCharacteristic object is disposed of after an unknown amount of time...

Make your characteristic a global, problem solved.

"You may find that your application stops receiving updates from the device after a period of time. This is a scoping issue where objects are being disposed of that shouldn't. This is because the GattCharacteristic is disposed of before it should be, set the characteristic as a global rather than relying on it being copied in."

Gerard Wilkinson
  • 1,512
  • 14
  • 33
  • Unfortunately, the problem is not solved by doing so. The event stops being called if there wasn't a notification for ~2 Seconds. If notifications keep flowing, the event keeps being called. Periodically sending `GattClientCharacteristicConfigurationDescriptorValue.Notify` to `CharacteristicProperties` also _fixes_ the problem. Looks more like a Win10 issue? – kazu May 04 '18 at 09:50