-
I can now reproduce the problem. It seems to independent of the bangle code as well as GPS reception. Forcing the problem to appear takes cutting of BT reception enough for a disconnect. The behaviour after is very similar to having a breakpoint in the loop of the
dispatchThread
in GBBtLEQueue
and just leaving that hanging.
Normal execution looks like this:nodomain.freeyourgadget.gadgetbridge.service.btle.BtLEQueue: about to add: 20:30:52: Transaction task: gps with 8 actions nodomain.freeyourgadget.gadgetbridge.service.btle.BtLEQueue: About to run action: 1. März, 20:30: WriteAction on characteristic: 6e400002-b5a3-f393-e0a9-e50e24dcca9e nodomain.freeyourgadget.gadgetbridge.service.btle.actions.WriteAction: writing to characteristic: 6e400002-b5a3-f393-e0a9-e50e24dcca9e: 0x10.....
After disconnecting bluetooth from the outside the GPS sending looks like this:
nodomain.freeyourgadget.gadgetbridge.service.btle.BtLEQueue: about to add: 19:51:53: Transaction task: gps with 7 actions
No WriteAction executing, just the next GPS update arriving and queuing up the next transaction task.
This is the only log line seeming relevant for this problem after the forced disconnect:
nodomain.freeyourgadget.gadgetbridge.service.devices.banglejs.BangleJSDeviceSupport: Services discovered, but device state is already INITIALIZED for device: Device Bangle.js 773e, FF:3B:5A:19:77:3E, initialisiert, so ignoring
Save for BT disconnects the GPS from GB works really well now. @Gordon any idea what could be the problem here or where to search further? I'm a bit out of my depth regarding the BT LE stuff in GB.
-
-
https://espruino.github.io/BangleApps/?id=powermanager now has some logging capability for power use troubleshooting. It can show you code executed by timeouts and intervals and some estimation for hardware use.
-
I'm searching for a method to stress test the GPS via GadgetBridge changes in https://github.com/espruino/BangleApps/pull/2534 together with the latest GadgetBridge nightly.
There is a test script, which exercises all states, that runs fine.
Yesterday I had somehow reached the state of GadgetBridge still sending GPS events (seen in logcat) but the Bangle was not reacting at all. That was about half an hour after starting to use GPS. First theory was GPS cutting out on the phone and somehow getting the internal state on the bangle out of order.
To simulate bad GPS I have devised a top notch high end RF testing bench (put the phone into grounded aluminium foil) and created about a thousand disconnects from GPS over 8 hours. The bangle code worked without failure the whole time.Sooo... Has anyone other ideas for testing this?
-
Had a run using the app and it works quite well. I have some minor nitpicks and a few ideas:
- 3 digit pulse overdraws on the ring on the right side, so the ring probably needs to be drawn again after the pulse has been updated
- The alert screen should show the pulse, that would make it easier to find a maximum without recording. The number on the other page is difficult to read going all out :)
- A lock indicator on the Karvonnen page would be nice
- Vibration on changing zones could be helpful
- Maybe find a way to switch page without unlocking? Since the accelerometer is always active maybe there could be a threshold where you could give the watch a hearty whack to switch while it is not triggered by running/biking?
- 3 digit pulse overdraws on the ring on the right side, so the ring probably needs to be drawn again after the pulse has been updated
-
Then how about leaving it as is, renaming to
Run+
, specifying only Bangle 2 in metadata and just wait for somebody to implement additional screens there before thinking about how to split them out? That could also be a base to try out minimizing RAM usage by loading/unloading the screens inside the app to make it work on Bangle 1.
Gettingexstats
to store on exit is probably useful anyway, since not being able to switch apps on a longer activity like biking is a bit limiting currently. -
-
I can have a look at splitting the additional page out :) Since the code is already in it's own file it probably is relatively easy. I suspect the combined code is to heavy for Bangle 1, so some changes have to be made anyway to keep Run feasible for Bangle 1. It seems to be very tight on memory as @Humpelstilzchen can not run it now. This of course depends on other installed widgets/boot code using memory, so maybe it is still working now for others.
Will have a try this evening and do a pull on your repo if successful @Ganblejs. -
-
While trying things out for my current power manager app changes, I found this thread and was intrigued by @Gordon 's last edit. Some experimentation lead to:
const systickMax = peek32(0xE000E014); print("Max:", systickMax); let t, systickNow, tLater, systickLater, systickDiff; setInterval(() => { tLater = Date.now(); systickLater = peek32(0xE000E018); systickDiff = systickLater - systickNow; if (systickDiff < 0) systickDiff += systickMax; t = Date.now(); systickNow = peek32(0xE000E018); }, systickMax/64000); setInterval(() => { let cpuPercentage = 100 - E.clip(systickDiff/systickMax*100,0,100); g.drawString("CPU used: " + cpuPercentage.toFixed(2) +"% " + systickDiff,0,0,true); }, 2000);
Is this actually a valid way to guesstimate CPU-usage? On an bangle without boot code this shows 6-7% non-idle time while being connected to bluetooth. That drops down to 2.5% without bluetooth. Since there is a bit of stuff ongoing every 250/2000ms, that seems to be believable to me. Scrolling around in the launcher can get up to 100% as long I am actively scrolling.
Am I correct in assuming that the systick overflows every 262ms? 16.7 million ticks at 64000 ticks every ms? -
I have tested a bit:
- Seems to work fine on dark theme, light theme needs dark fonts and light background arc for the zones.
- On my daily driver bangle the pulse number jumped to the top left and number stacked on each other. That must have been something other installed, on my other bangle that was not the case.
I still get an error when there are no settings:
Uncaught Error: Cannot read property 'min' of undefined at line 3 col 292 in run_karvonnen ...or",20);}let minhr=hrmSettings.min;let maxhr=hrmSettings.max;function calc... ^ in function "show" called from line 38 col 216 in run.app.js ...(settings.HRM,exs.stats.bpm);}
- Seems to work fine on dark theme, light theme needs dark fonts and light background arc for the zones.
-
There are very involved processes to electroplate plastics, based on a conductive paint as the first layer. In this case the matte copper look of the conductive paint is already quite nice, but he manages to electroplate enough copper on there to be able to sand it down and polish it before doing a final pass with palladium. https://www.youtube.com/watch?v=vsrlrH3omZc
-
Maybe just give the run app a mechanism to eval additional pages which can be selected by swiping but are installed as separate apps. Just to keep run as slim as possible by default. An example for this would be the Recorder app. That searches for all files named
*.recorder.js
and evals those. The resulting objects are in an array and could just provide a draw method to be called if the page is swiped to.
I had a short run and I had two problems:- The settings do not seem to have defaults, app crashes accessing the undefined settings object
- Swiping works fine, but the display was not updated but seemed complete otherwise
- The settings do not seem to have defaults, app crashes accessing the undefined settings object
-
-
My bangle ran out of battery and I used the chance to get some more info on the charging.
Green is the current drawn during charging at 5.1V, blue is mAh as counted by my usb measurement gadget with the dotted part being guessed from time and current because it stops counting below 50mA. Red is a guesstimate of mAh ending up in the battery using 3.8V and 90% charging circuit efficiency.
I guess towards the end most of the "charging" current went into producing heat so red and blue probably could taper of a bit earlier.
Actual gross capacity should be 200mAh, so getting roundabout 170mAh in there is not bad. There is probably some unused capacity left after turning off, even if the electronics can not work anymore. -
I think the nightly version already does not have those anymore, at least I have not seen them for a while now. Nightlies can be found in the GadgetBridge nightly repo: https://freeyourgadget.codeberg.page/fdroid/repo/. This is of course for somewhat adventurous users :)
-
-
At first glance I would suspect #L176 being called on every lock and then setting a new timeout without clearing the old one. It should be a fairly tiny memory leak if this is the reason, the timeout only can accumulate over 45 seconds.
-
-
The Chargie seems very cool. Thanks for dropping that name, I had searched for something like that a few months ago without success. I use a Palm Phone with a 770mAh battery and that degraded to about half its tiny capacity in 2 years of use. Charging daily or currently twice a day and using 100%-0% every day will do that fast. The Bangle with its week long runtime will probably degrade more by age than by charging.
As for the Bangle, a workaround would be charging from a powerbank. Many of those cut off the charging when the current is low. The Bangle draws miniscule amounts of current at the end of charge so depending on the powerbank that might hit your target charge level on cut off. Some reviews check the minimal amount of current needed to keep the power on, that would be your charging cut off value ;). -
Default in Gadgetbridge is currently 10s, but since that is configurable, we must handle even longer pauses between events. Should be easy by just storing the time between two events and just ignoring the case where the user changes Gadgetbridge config to a significantly higher value while phone GPS is used.
-
You can just use the library to draw an arc like this:
g.clear(); const GU = require("graphics_utils"); let centreX = 0.5 * g.getWidth(); let centreY = 0.5 * g.getWidth(); let startAngle = GU.degreesToRadians(20); let endAngle = GU.degreesToRadians(135); let minRadius = 0.3 * g.getWidth(); let maxRadius = 0.45 * g.getWidth(); GU.fillArc(g, centreX, centreY, minRadius, maxRadius, startAngle, endAngle);
Gordons code does very similar things by constructing a polygon that approximates the arc.
-
That seems to be a valid compromise. We could just switch on the first Gadgetbridge GPS event, keep time until the next arrive to get the configured timeout and then set a timeout slightly longer to re-enable builtin GPS. That way no handling of connection events would be necessary and no internal keeping of state besides the expected time to next Gadgetbridge GPS event. Maybe even communicate the configured interval duration in the first or all GPS events to make this easier to do on the bangle.
-
This could also use
fillArc()
from graphics_utils lib for drawing the segments.
Maybe implementing calculations, averaging, sensor fusion or whatever else is needed for the state changes is best done in a library. Then build an app or widget around that library which is able to keep state all the time and handles persisting on reloads etc..
Some months ago I had implemented a version of the van Hees method for detecting inactivitiy by checking changes in the direction of accelerometer values. Maybe you can use that or parts of it. https://github.com/halemmerich/BangleApps/blob/libvanhees/apps/libvanhees/lib.js