-
Reinstall bootloader from appstore, it uses .boot0 file.
Now make your app use
.boot1
instead of.boot0
The info file is only for making a normal app that is listed by the app loader app. You might need your app as a
clock
, and also as a.boot1
file. An app being a clock just means that it is loaded by the bootloader(.boot0 AND .bootcde) App, by default.Depending on how your device is reset/loaded, it won't always execute the
.bootcde
which is the clockLoader. But sometime it will. That is why I suggest a.boot1
and anormal app clock
which are identical code. This could be a workaround for you. Ofc there can be other ways to solve this too.But this method might cause your code to load twice, in the normal case. So we have to think about it a bit more. Probably you would delete the file :
.bootcde
if you are relying on.boot1
file as a clock loader instead.EDIT: I just realized there is a
.bootrst
file that overrides.bootcde
behaviour, AND runs upon reset too. So instead of deleting.bootcde
, and instead of writing to.boot1
, you could try writing to.bootrst
. Then when you want to revert back to normal behaviour , delete the.bootrst
file. Now the Bootloader app's.boot0
will load and then.bootrst
(Your App) will load.Conslusion: Write your app to
.bootrst
, the bootloader app(.boot0) should not try to load a clock now. Bear in mind as above has said, all this tinkering can be risky for bricking the device (If you lose access to DFU screen). If you do still have access to DFU screen, you should be fine. -
-
-
I noticed that the auto-completion tab in IDE is able to output more fields than a call to eg.:
Object.getOwnPropertyNames(Bangle)
Object.getOwnPropertyNames(Bangle.__proto__)
Specifically, some object-like fields:
Bangle.on
Bangle.removeListener
etcSimilarly for a Promise object, I do not see the
.then
function as child object. How can I get full listing via javascript?The auto-complete is able to show all of these fields from a promise instance:
>p. constructor apply bind call replaceWith catch then clone emit hasOwnProperty length on removeAllListeners removeListener toString valueOf
How do I get these items into a javascript list?
-
-
-
https://codeberg.org/Freeyourgadget/Gadgetbridge/issues/3439
This thread mentions using, the debug page in GadgetBridge menu, after Debug, scroll down, press orange button "Add test device manually", Choose bangle.js and enter correct MAC address.
-
-
This behaviour seems to have started with the update to Android 13. I can not say that for sure, since the device also has changed from Pixel 4a to Pixel 6a at that time, but I suspect the hardware has nothing to do with this. Installing the Bangle.js build from the Playstore (I used Aurora from FDroid to do that) has worked and the notification access permission can be set to on as expected. Both versions of GB from FDroid do not work on that device for me, the changing of the setting is just not allowed.
From another graphene user.
From this thread : https://forum.espruino.com/conversations/382553/#16818510 -
Are you using whitelist feature in settings of bangle?
Some tips:
Make sure you are disconnected from it on other devices/apps before trying others.
Experiment with enabling pin and disabling pin, in watch settings
Ensure whitelist in the watch settings is off for now.
Use a default clock or long press and go to recovery menu and useClean Boot
, see if that helps.
Toggle your bluetooth on and off on phone, unpair if already paired. Reinstall gadgetbridge, ensure it has correct permissions.
Ensure programmable and connectable is set to true in watch settings.
Ensure your watch has up to date firmware and apps. Try fresh install if haven't.
Test if nrf DFU app detects your watch in dfu mode. (long press button, then release midway), it shows as DfuTarg -
Some flags @fanoush used in another post :
https://chat.openai.com/share/00d40811-6adb-40a7-b4aa-4265109be5b6 -
@user140377
Hey, this morning I created this :https://github.com/espruino/Espruino/issues/2445
Can you test it? I am curious, also its great coincidence that you revived this thread on the same day i raise that issue. If unrelated. :P
-
What I can tell others from my experience:
hrmSportMode setting should be best left at -1.This is because
hrmSportMode: 0
is real heart rate approximation for values between 50-90. Values above this are mostly impossible to predict with an algorithm considering the values this device produces.hrmSportMode: 1
is a boosted heart rate from acceleration heuristics, but if you leave it on when you are not moving much it creates false positives. That explains moments of hr persisting above 100 when we are at 60. This mode NEEDS movement for it to make any sense. ( perhaps if it didn't trigger so easily from just being stationary it could be improved, it has hard-coded ppg delta change and the ppg moves a lot for no apparent reason on macro scale ).Using
hrmSportMode: -1
gives us best of both worlds, if we move a lot within a 20 second window period, we become1
, and then 20 seconds later, we are back to0
.So ye, the
0
mode is really good for normal relaxed heart rate values. I tried to create an algorithm that is as good as it and it took me A LOT of effort just to get close. The difference was small and so I don't think I will even bother to release it. I will however collect some more data over the coming days.When testing, remember to use
Bangle.dbg()
to notice the sportsMode changing because of the auto-1
inBangle.getOptions().hrmSportMode
I believe the algorithm relies on something similar to :
http://sim.okawa-denshi.jp/en/OPseikiLowkeisan.htm after looking at the decompilation. So its a frequency-domain based solution? I guess.The method I have been testing recently was a threshold based peak detection on the time-domain.
I'm personally grateful we have something that works so well, considering how the signal looks, its kind of a miracle.
-
So if the HRM isn't pointing at anything the LED brightness isn't going to be the 'real' brightness you see.
Not sure which part this is response to. Keep in mind these tests were often done with
hrmGreenAdjust
false, andhrmWearDetect
false, although, you only have to lift the watch a tiny bit to peek at the led without triggering wear detect.@Gordon Welcome Back, hope you had a merry holiday period.
-
-
-
Created using : https://github.com/espruino/BangleApps/tree/master/apps/hrmaccevents and gnuplot file above.
Longer recording. ( Did some bike activity at end, real HR went way above 100 ). Shows ppgOffset in green, which is when the ledCurrent is adjusted. I now just have to get some chest strap comparison data.
-
gnuplot -e "load 'plotscript.gnu'"
# 5 = beats
# 6 = confidence
# 7 = hrm.raw=(ppg+offset)*2
# 9 = ppg
# 10 = offsetset datafile separator "," filename = system("echo 'hrm1.csv'") first_timestamp = system("awk -F',' 'NR==2 {print $1}' hrm1.csv") set xlabel 'Time (seconds)' set ytics nomirror set ylabel 'ppg' plot filename using (($1 - first_timestamp) / 1000.0):7 with p title 'raw' axes x1y1 replot filename u (($1 - first_timestamp) / 1000.0):10 with l t 'offset' axes x1y1 set y2tics nomirror set y2label 'beats' replot filename using (($1 - first_timestamp) / 1000.0):5 with p title 'beats' axes x1y2 # Pause to keep the plot window open pause -1
-
{ "vcPPG": 1419, "vcPPGoffs": 0, "isWearing": true, "adjusted": false, "vcPre": [ 4, 0 ], "vcPS": 15, "vcEnv": [ 0, 0, 0 ], "vcIRQ": 4, "vcRaw": new Uint8Array([0, 4, 130, 4, 0, 15, 5, 128, 224, 87, 55, 103]).buffer, "raw": 2838, "bpm": 60, "confidence": 80, "filt": -26624, "avg": 2929 }
Look at the object from
hrm-raw
event. I noticed in halemmerich's code that he logs alsoe.vcPPG
. I wonder how this value differs fromraw
.I conclude that
hrm.raw
is the sum of thee.vcPPG
ande.vcPPGoffs
, then multiplied by 2.proof:
int v = vcInfo.ppgValue + vcInfo.ppgOffset; if (vcType == VC31B_DEVICE) v <<= 1; // on VC31B the PPG doesn't vary as much with pulse so try and bulk it up here a bit hrmCallback(v);
-
@Graham_Jones My sensor only begins to work at
LedCurrent : 7
, I used your app and have to swipe down until its 7, else I get readings of0
. Strange you don't have that? unless its lighting related? Even 7 is sometimes too high, requirement seems to vary.Also your app, I can't see a graph, its empty below it.
It seems that the
photodiode
reading increases the closer to 0 I go with LED current.
LedCurrent: 0 , Average: 5800
LedCurrent: 1 , Average: 5000
LedCurrent: 2, Average: 3200
LedCurrent: 3, Average: 1600
LedCurrent: 4, Average: 800Some kind of effect like that. Its interesting that, I didn't notice this before, thanks to your app :)
I think the real max value is 8190, despite it being stored in a 16 bit short?
Probably whyauto adjust ON is the best
. Hopefully its keeping it within good bounds? Like sometimes my ledCurrent: 0 creates too high values ,so it only reads 8190 cos of some clamp somewhere.
Based on this idea, perhaps the target
photodiode
value should be half way between 0 and 8190 ,8190/2 == 4095
I will try in different lighting condition. Even in dark room, the conditions are same for me. The 0x80 last bit of the LedCurrent value is a PpgGain btw, so at values between 129->136, I get some numbers , but it seems gain is bad because the swings are higher so you need to adjust led more often.
Would be nice to see if @user140377 has anything similar to this ( the low LED current requirement ), we could compare to figure if any of our bangles are different/defective.
What I like others to test:
To be clear:
if my LEDcurrent(reg 0x17) are above some very low number, eg. 5,
The signal of the photodiode drops to 0.
And there is an inverse scaling, the closer LEDcurrent is to 0, the Higher the photodiode valuesAlso, confirm your output of :
Bangle.hrmRd(0)
is33
, confirming you have thevc31B
device and not thevc31
.@Graham_Jones There are hrm->csv recorder apps already on the app store (namely the "recorder" app by gordon (seems beats only), or "HRM Accelerometer event recorder" by halemmerich, your app store is a bit out of date. Just in case you did not know.
https://github.com/espruino/BangleApps/tree/master/apps/hrmaccevents
-
-
-
Can you elaborate what this is?