espruino / EspruinoTools

JavaScript library of tools for Espruino - used for the Web IDE, CLI, etc.
Apache License 2.0
150 stars 89 forks source link

Sporadic connection to Bangle.js #130

Closed jurelik closed 3 years ago

jurelik commented 3 years ago

Hi there,

I'm trying to use EspruinoTools to develop an app for my Bangle.js watch and avoid the Web IDE. I have, however, been experiencing a sporadic appearance of the Bangle.js watch using the espruino --list command, which translates into using the espruino -d Bangle and espruino -p xx:xx:xx:xx:xx:xxcommand as well, as the cli just won't be able to find the watch every now and then. This means I have to execute the same command multiple times and hope I manage to establish a connection.

I've been doing some digging and found a reference to this issue here: https://github.com/espruino/EspruinoTools/issues/111#issuecomment-555030429

I have tried and messed around with serial_noble.js file mentioned in that comment but I'm having trouble getting results. I might be modifying the wrong values though, so any help with that would be much appreciated.

I am using MacOS Mojave 10.14.6.

gfwilliams commented 3 years ago

Hi - I'm not sure that comment applies as much now - you could try altering the timeout here:

https://github.com/espruino/EspruinoTools/blob/gh-pages/bin/espruino-cli.js#L739

There's a second one for connecting here: https://github.com/espruino/EspruinoTools/blob/gh-pages/bin/espruino-cli.js#L679

So that's the number of times getPorts is called waiting until the port is found.

Were you using WiFi and maybe downloading/streaming at the time? Often laptops use the same aerial for WiFi and Bluetooth so if you're using WiFi a lot it can really hurt Bluetooth performance (and vice versa).

Also, it might be worth trying setAdvertising({},{interval:50}) on the Bangle and seeing if that helps your connection? If so at least it'll narrow it down.

jurelik commented 3 years ago

Hi Gordon, thank you for the fast response.

It seems like the npm version of the EspruinoTools module does not match the github version. The main() function inside my espruino-cli.js file looks completely different and doesn't contain var timeout among other variables. I therefore can't change line 739 to see if that would fix anything. It is a bit odd though, because both the npm and github versions have their version set to 0.1.32 in package.json.

I did find var timeout on line 679 though, but changing it to a higher number didn't fix the problem.

The problem does get fixed when I run NRF.setAdvertising({},{interval:50}) though! Will this change impact my battery life in a significant way or cause any other issues?

gfwilliams commented 3 years ago

Ahh - probably the latest EspruinoTools hasn't been pushed. I bump the version before pushing, so you'd expect that they would be the same.

You could try running the version from GitHub to see if it improves matters even without changing anything?

setAdvertising does have a noticeable effect on battery life when running off a coin cell (maybe 12 months -> 2 months) but on Bangle.js you're honestly not going to notice any difference at all.

jurelik commented 3 years ago

Ah, don't know why I haven't thought of that.

I have replaced the espruino-cli.js with the new version and the improvement is definitely noticeable! It does still feel a bit like a game of chance but the odds have definitely improved. I have tried the following:

Would you mind explaining how often the setAdvertising setting gets reset? Does calling reset() or holding down BTN3 for a long time reset it or is this something that just gets reset on a BTN1 + BTN2 hold? The reason I'm asking is because I don't mind setting it up manually once in a while but it might get tedious if I have to do it every time I reset the watch. Is there any chance the default interval could be changed in the future considering the battery life shouldn't be affected much by this?

gfwilliams commented 3 years ago

Does calling reset() or holding down BTN3 for a long time reset it or is this something that just gets reset on a BTN1 + BTN2 hold?

Yes, it will do - however making it permanent is pretty easy pasting require("Storage").write(".boot3","NRF.setAdvertising({},{interval:50})") will ensure that everything but a BTN1+2 reboot with BTN1 held will come up with the better advertising speed.

You can also just paste NRF.setAdvertising({},{interval:50})") into https://banglejs.com/apps/#custom%20boot%20code

Is there any chance the default interval could be changed in the future considering the battery life shouldn't be affected much by this?

Yes - 375ms was a good compromise for Puck.js, but on Bangle.js it makes sense to increase this. 50ms feels a bit antisocial to other Bluetooth LE devices, but I've just raised it to 200ms in https://github.com/espruino/Espruino/commit/9bb75a121b3e5dad369a4bfd27a41221603014f7 - so cutting edge builds will have it.

It's worth noting that for most people, getting a connection going is not a problem - so it feels like maybe your Mac's bluetooth isn't as good as it could be for some reason.

jurelik commented 3 years ago

Thanks for the above! I'll try out both of the methods you mentioned and pick one to use.

Changing the default interval to 200ms sounds like a reasonable change. I'd love to hear from other Mac users to see if they encounter something similar or if it is indeed just my machine that's acting up. Either way, I'd consider the problem solved considering we know how to fix the issue - feel free to close this.

Thanks for your help and keep up the good work!

gfwilliams commented 3 years ago

Thanks!