Skip to content

Commit

Permalink
nRF52840: jsvReadVRef now reads VDDH value (not VDD, which is almost …
Browse files Browse the repository at this point in the history
…always internally regulated)
  • Loading branch information
gfwilliams committed Nov 30, 2023
1 parent ed7e003 commit eabd13c
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 0 deletions.
1 change: 1 addition & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
Graphics: fix drawing image in string inside cliprect when rotated (fix #2435)
Bangle.js: Add wakeOnDoubleTap to Bangle.setOptions, "lock" event now has second argument giving a reason (if known)
nRF5x: On SDK15 ensure nonconnectable+nonscannable advertisements are not sent as extended
nRF52840: jsvReadVRef now reads VDDH value (not VDD, which is almost always internally regulated)

2v19 : Fix Object.values/entries for numeric keys after 2v18 regression (fix #2375)
nRF52: for SD>5 use static buffers for advertising and scan response data (#2367)
Expand Down
9 changes: 9 additions & 0 deletions targets/nrf5x/jshardware.c
Original file line number Diff line number Diff line change
Expand Up @@ -2791,8 +2791,14 @@ JsVarFloat jshReadVRef() {
config.acq_time = NRF_SAADC_ACQTIME_3US;
config.gain = NRF_SAADC_GAIN1_6; // 1/6 of input volts
config.mode = NRF_SAADC_MODE_SINGLE_ENDED;

#ifdef NRF52840
config.pin_p = 0x0D; // Not in Nordic's libs, but this is VDDHDIV5 - we probably want to be looking at VDDH
config.pin_n = 0x0D;
#else
config.pin_p = NRF_SAADC_INPUT_VDD;
config.pin_n = NRF_SAADC_INPUT_VDD;
#endif
config.reference = NRF_SAADC_REFERENCE_INTERNAL; // 0.6v reference.
config.resistor_p = NRF_SAADC_RESISTOR_DISABLED;
config.resistor_n = NRF_SAADC_RESISTOR_DISABLED;
Expand All @@ -2810,6 +2816,9 @@ JsVarFloat jshReadVRef() {
f = nrf_analog_read() * (6.0 * 0.6 / 16384.0);
} while (nrf_analog_read_interrupted);
nrf_analog_read_end(adcInUse);
#ifdef NRF52840
f *= 5; // we were on VDDHDIV5
#endif

return f;
#else
Expand Down

6 comments on commit eabd13c

@d3nd3
Copy link
Contributor

@d3nd3 d3nd3 commented on eabd13c Dec 20, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi! I notice this affects the voltage, no longer being approximate to 3.3V!
I have like 2.44V from this read out now.
What is this change and how do I compute battery voltage estimation now.
Previously was used :
lcars.app.js#L330C5-L330C5

I need to update this now?

@gfwilliams
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe just replace the code with what we actually do inside Bangle.js? https://github.com/espruino/Espruino/blob/cfbc4040d/libs/banglejs/jswrap_bangle.c#L2817-L2821

Battery full voltage on Bangle.js 2 as a default is 0.3144 although it can be read out of batFullVoltage in the settings file if it's defined.

jshReadVRef as it was just didn't make any sense. It'd pretty much always return 3.3v so you might as well have just replaced it with a constant (you could still do that if you wanted).

@gfwilliams
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually forget that - looks like on Bangle.js 2 particularly VDDH isn't connected so gives random values, so I've reverted the change (just for Bangle.js 2, not for other nRF52840)

@d3nd3
Copy link
Contributor

@d3nd3 d3nd3 commented on eabd13c Jan 2, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The formula that I used to derive the battery voltage was what I believe to be :
v = a * r * 3.3


Where:
a = analogRead(3)
r = 4 ( because its connected to 4 ohm resistors )
3.3 ( because this is the operational signal )
Equivalent to:
v = 3.3*4*a
v = 13.2 * a


This formula worked well for me with bangle 1 and 2, where I would replace 4 with 2, for bangle 1
, because it has 2 ohm resistor instead of 4.


It turns out that your formula :
v = 4.2 * a / 0.3144
equivalent to:
v = 4.2 * 3.18*a
v = 13.356 * a


If we assume the 3.3 is fixed, we get 13.356/3.3 = 4.0472

So your calculation has slightly more resistance.

You can see how its extremely similar to 4 * a * 3.3.


So your formula uses 13.356 (4.0472 resistance), mine uses 13.2 ( 4 resistance ).
1.2% more.

Is your formula more correct than mine? I know its trivial, but it interests me.

@gfwilliams
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We're not 100% sure on the resistors used in the potential divider (I haven't measured them) but they're never entirely accurate so they vary by device (probably by around 5%). That's why we now have the calibration option.

The values chosen for Bangle.js 2 are based on looking at a bunch of watches and trying to choose the correct value based on what I saw, so I'd argue that my formula is marginally more accurate for most users, although it's always possible that yours is better for your device.

@bobrippling
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cross referencing to the issue in BangleApps

Please sign in to comment.