Tjoms99 / xiao_sense_nrf52840_battery_lib

A battery management library for the XIAO BLE and XIAO BLE Sense board using Zephyr.
Apache License 2.0
21 stars 3 forks source link

Random Voltage readings - what am idoing wrong? #2

Closed helicocrasher closed 4 months ago

helicocrasher commented 4 months ago

Hi @Tjoms99 Thanks for the lib.

I am very new on Zephyr and was struggling wit a lot of code samples - I was unable to get most of the examples running. Not with you code :-) Cool.

But the output of the logging shows pretty random values. Any hint?

Cheers Felix

17:18:59.440 -> [00:08:39.338,806]  main: Battery at 3756 mV (capacity 44%)  17:18:59.440 -> [00:08:41.338,958]  main: Battery at 4149 mV (capacity 97%)  17:18:59.440 -> [00:08:43.339,111]  main: Battery at 3753 mV (capacity 44%)  17:19:01.476 -> [00:08:45.339,263]  main: Battery at 4140 mV (capacity 96%)  17:19:03.470 -> [00:08:47.339,416]  main: Battery at 3759 mV (capacity 44%)  17:19:05.461 -> [00:08:49.339,569]  main: Battery at 4113 mV (capacity 93%)  17:19:07.450 -> [00:08:51.339,721]  main: Battery at 3999 mV (capacity 74%)  17:19:09.445 -> [00:08:53.339,874]  main: Battery at 3762 mV (capacity 45%)  17:19:11.477 -> [00:08:55.340,026]  main: Battery at 4146 mV (capacity 97%)  17:19:13.467 -> [00:08:57.340,179]  main: Battery at 3756 mV (capacity 44%)  17:19:15.449 -> [00:08:59.340,332]  main: Battery at 4146 mV (capacity 97%)  17:19:17.440 -> [00:09:01.340,484]  main: Battery at 3756 mV (capacity 44%)  17:19:19.440 -> [00:09:03.340,637]  main: Battery at 4152 mV (capacity 98%)  17:19:21.435 -> [00:09:05.340,759]  main: Battery at 3762 mV (capacity 45%)  17:19:23.474 -> [00:09:07.340,881]  main: Battery at 4149 mV (capacity 97%)  17:19:25.463 -> [00:09:09.341,003]  main: Battery at 3798 mV (capacity 49%)  17:19:27.444 -> [00:09:11.341,125]  main: Battery at 3951 mV (capacity 69%)  17:19:29.473 -> [00:09:13.341,247]  main: Battery at 4146 mV (capacity 97%)  17:19:31.455 -> [00:09:15.341,369]  main: Battery at 3759 mV (capacity 44%)  17:19:33.447 -> [00:09:17.341,491]  main: Battery at 4149 mV (capacity 97%)  17:19:35.435 -> [00:09:19.341,613]  main: Battery at 3756 mV (capacity 44%)  17:19:37.475 -> [00:09:21.341,735]  main: Battery at 4143 mV (capacity 97%)  17:19:39.466 -> [00:09:23.341,857]  main: Battery at 3759 mV (capacity 44%)  17:19:41.459 -> [00:09:25.341,979]  main: Battery at 4149 mV (capacity 97%)  17:19:43.452 -> [00:09:27.342,102]  main: Battery at 3759 mV (capacity 44%)  17:19:45.445 -> [00:09:29.342,224]  main: Battery at 4068 mV (capacity 86%) 

Tjoms99 commented 4 months ago

Hey @helicocrasher, appreciate the good feedback. Not sure what's going on here, and I currently do not have a board I can troubleshoot with. Can you tell me a little bit more about your setup?

Do you have any other code running? More specifically, any code that also uses the same ADC as used to read the battery voltage? How are you powering your XIAO board; USB, battery, or both? How does your circuit look, do you have anything else attached to the XIAO board? Have you ever shorted the battery pins?

I shorted the battery pins by mistake, which fried the ADC, and then I got some weird values. I can not quite remember how it looked though. You will also fry the ADC if you have set GPIO_BATTERY_READ_ENABLE to low while trying to read ADC values.

helicocrasher commented 4 months ago

Hi @Tjoms99 thanks for the fast reply.

My setup is really simple - just a LiPo battery soldered to the xiao and current meter in the V_Batt line, to measure the current in and out. No other code than your code with some slight modifications.

Concerning GPIO_BATTERY_READ_ENABLE - yes, I initially oversaw the active low statement. The ADC readings were rather high.. So I disconnected the battery, and set GPIO_BATTERY_READ_ENABLE to high. (= low output level) I think frying the ADC is rather not possible with the 1M resistor driving the ADC input, the current of max 1microA is too low. When disabling charging the ADC values seem very reasonable. seems to work.

BTW: The charge current selection description on the Seeed getting started Wiki is not correct. Correct is:

So if I may comment: Independent of the BQ version used the functions battery_charge_start() and battery_charge_stop() will not start or stop charging. They might switch the LED "red_CHG" on or of if the BQ25101 has not activated the LED.

I am still confused as I once saw stable ADC readings during charging ... but have now clue rigt now.

Cheers

helicocrasher commented 4 months ago

right now .. it works fine:-) The Charging LED is on - not driven by the nRF SW (so it looks like BQ25101 version is popukated) The ADC readings are steady and rising :-)

But I do not know how why its sometimes working and sometimes not ... bad contact?? :-(

01:43:24.791 -> [00:00:02.284,362]  battery: Initialized 01:43:24.791 -> [00:00:02.284,393]  main: Initialized 01:43:24.791 -> [00:00:03.285,797]  battery: ADC read failed (error -16) 01:43:24.791 -> [00:00:03.285,827]  main: Battery at 3813 mV (capacity 51%)  01:43:24.791 -> [00:00:04.286,041]  main: Battery at 3816 mV (capacity 51%)  01:43:24.791 -> [00:00:05.286,102]  main: Battery at 3816 mV (capacity 51%)  01:43:24.791 -> [00:00:06.286,254]  main: Battery at 3807 mV (capacity 50%)  01:43:24.791 -> [00:00:07.286,376]  main: Battery at 3813 mV (capacity 51%)  01:43:24.791 -> [00:00:08.286,529]  main: Battery at 3813 mV (capacity 51%)  01:43:24.791 -> [00:00:09.286,651]  main: Battery at 3810 mV (capacity 50%)  01:43:26.790 -> [00:00:10.286,804]  main: Battery at 3813 mV (capacity 51%)  01:43:26.790 -> [00:00:11.286,926]  main: Battery at 3816 mV (capacity 51%)  01:43:28.793 -> [00:00:12.287,078]  main: Battery at 3819 mV (capacity 51%)  01:43:28.793 -> [00:00:13.287,200]  main: Battery at 3816 mV (capacity 51%)  01:43:30.788 -> [00:00:14.287,353]  main: Battery at 3816 mV (capacity 51%)  01:43:30.788 -> [00:00:15.287,475]  main: Battery at 3816 mV (capacity 51%)  01:43:32.813 -> [00:00:16.287,628]  main: Battery at 3816 mV (capacity 51%)  01:43:32.813 -> [00:00:17.287,750]  main: Battery at 3816 mV (capacity 51%)  01:43:34.789 -> [00:00:18.287,902]  main: Battery at 3813 mV (capacity 51%)  01:43:34.789 -> [00:00:19.288,024]  main: Battery at 3816 mV (capacity 51%)  01:43:36.801 -> [00:00:20.288,177]  main: Battery at 3819 mV (capacity 51%)  01:43:36.801 -> [00:00:21.288,299]  main: Battery at 3816 mV (capacity 51%)  01:43:38.783 -> [00:00:22.288,452]  main: Battery at 3816 mV (capacity 51%)  01:43:38.783 -> [00:00:23.288,574]  main: Battery at 3816 mV (capacity 51%)  01:43:40.800 -> [00:00:24.288,726]  main: Battery at 3813 mV (capacity 51%)  01:43:40.800 -> [00:00:25.288,848]  main: Battery at 3816 mV (capacity 51%)  01:43:42.790 -> [00:00:26.289,001]  main: Battery at 3819 mV (capacity 51%)  01:43:42.790 -> [00:00:27.289,123]  main: Battery at 3813 mV (capacity 51%)  01:43:44.813 -> [00:00:28.289,276]  main: Battery at 3816 mV (capacity 51%)  01:43:44.813 -> [00:00:29.289,398]  main: Battery at 3822 mV (capacity 52%)  01:43:46.817 -> [00:00:30.289,550]  main: Battery at 3819 mV (capacity 51%)  01:43:46.817 -> [00:00:31.289,672]  main: Battery at 3822 mV (capacity 52%)  01:43:48.812 -> [00:00:32.289,825]  main: Battery at 3816 mV (capacity 51%)  01:43:48.812 -> [00:00:33.289,947]  main: Battery at 3822 mV (capacity 52%)  01:43:50.789 -> [00:00:34.290,069]  main: Battery at 3822 mV (capacity 52%)  01:43:50.789 -> [00:00:35.290,222]  main: Battery at 3810 mV (capacity 50%)  01:43:52.807 -> [00:00:36.290,344]  main: Battery at 3822 mV (capacity 52%)  01:43:52.807 -> [00:00:37.290,496]  main: Battery at 3816 mV (capacity 51%)  01:43:54.794 -> [00:00:38.290,649]  main: Battery at 3816 mV (capacity 51%)  01:43:54.794 -> [00:00:39.290,771]  main: Battery at 3810 mV (capacity 50%)  01:43:56.780 -> [00:00:40.290,924]  main: Battery at 3816 mV (capacity 51%)  01:43:56.780 -> [00:00:41.291,046]  main: Battery at 3819 mV (capacity 51%)  01:43:58.784 -> [00:00:42.291,198]  main: Battery at 3813 mV (capacity 51%)  01:43:58.784 -> [00:00:43.291,320]  main: Battery at 3816 mV (capacity 51%)  01:44:00.776 -> [00:00:44.291,473]  main: Battery at 3816 mV (capacity 51%)  01:44:00.776 -> [00:00:45.291,595]  main: Battery at 3813 mV (capacity 51%)  01:44:02.818 -> [00:00:46.291,748]  main: Battery at 3819 mV (capacity 51%)  01:44:02.818 -> [00:00:47.291,870]  main: Battery at 3819 mV (capacity 51%) 

Tjoms99 commented 4 months ago

Good that it is working! If you manage to reproduce the issue and have a fix, feel free to submit a pull request:)

I agree that the design choices / documentation provided by SEEED STUDIO are ok at best, misleading at worst, and generally confusing:) Addressing some of your comments:

Battery Charging If you were testing using this library, remember that the the GPIO's is configured to be active low in battery_init():

BTW: The charge current selection description on the Seeed getting started Wiki is not correct.


ret |= gpio_pin_configure(gpio_battery_dev, GPIO_BATTERY_CHARGING_ENABLE, GPIO_OUTPUT | GPIO_ACTIVE_LOW);
ret |= gpio_pin_configure(gpio_battery_dev, GPIO_BATTERY_READ_ENABLE, GPIO_OUTPUT | GPIO_ACTIVE_LOW);
ret |= gpio_pin_configure(gpio_battery_dev, GPIO_BATTERY_CHARGE_SPEED, GPIO_OUTPUT | GPIO_ACTIVE_LOW);

Looking into the schematic and then this code might get you confused here. This is a design choice I made as my brain likes to think "HIGH = FAST" and "LOW = SLOW" charge:) This could probably be changed to be more aligned with the datasheet. 

The BQ (see the BQ section below) seems to be terminating the charging earlier when fast charging compared to slow charging. Could this be the case?
> Setting the P0.13 to a high level will disable charging (my finding when programming the Xiao BLE with PlatformIO) 

Quote from BQ datasheet 
> If left floating the
termination and pre-charge are set internally at 10/20% respectively.

**BQ2510x** 
 You are correct regarding the PreTerm; However, adjusting the preterm (P0.17) impacts how early or late in the charging process the chip decides to terminate the charging (if I am understanding it correctly). This is, as you already know, also decided by the DNP (which we do not know the value of, it might be floating as you said). Here are some more info from the BQ datasheet

>8.3.7 PRE_TERM – Pre-Charge and Termination Programmable Threshold
Pre-Term is used to program both the pre-charge current and the termination current threshold. The pre-charge current level is a factor of two higher than the termination current level. The termination can be set between 5 and 50% (recommended range) of the programmed output current level set by ISET. If left floating the termination and pre-charge are set internally at 10/20% respectively. The RPRE-TERM is ranged from 600 Ω to 30 kΩ and the minimum termination current can be programmed to 1 mA. The pre-charge-to-fast-charge, Vlowv threshold is set to 2.5 V.
RPRE-TERM = %Term × KTERM = %Pre-CHG × KPRE-CHG (2)
Where:
%Term is the percent of fast charge current where termination occurs;
%Pre-CHG is the percent of fast charge current that is desired during precharg
helicocrasher commented 4 months ago

Hi @Tjoms99 thank you for your reply. Good discusion, much appreciated.

I have done some more tinkering and left the code running - it still works. :-) I also gained confidence in the understanding of the charging HW. Here my conclusions:

  1. Current setting a) low level to P0.13 high charge current =100mA. b) high Z to P0.13 -> low charge current = 50mA. c) high level to P0.13 --> "charging with Zero charge current " is maybe not an inteded use case of th BQ25101 but could be of used under some circumstances.
  2. The BQ version used is the 25101 which is not having the PreTerm (no need to discuss that) festure but it has the charge status output. Low level --> charging & Charge LED on. High Z --> not charging & charging LED off. This signal on P0.17 can be read to know if the battery is being charged. If a battery is connected and not full and USB voltage supplied P9.17 will be LOW.

For these two point I will propose code changes and make them available. For number 1. --> Provide a current setting function [MaxChargeCurrrent50, MaxChargeCurent100, MaxChargeCurrentZero] default = MaxChargeCurrrent50 For number 2. --> remove the charge enable disable functions --> provide a charging status function "charging/not charging/(no battery connected)

Cheers

PS: I am also thinking about improving the charge level calculation during charging, but that is a larger topic ... maybe future

helicocrasher commented 4 months ago

@Tjoms99

in the meantime I understand that a connection error to the battery genrated the random voltage readings

Tjoms99 commented 4 months ago

Hi @helicocrasher, I am glad that it is still working!

For number 1. --> Provide a current setting function [MaxChargeCurrrent50, MaxChargeCurent100, MaxChargeCurrentZero] default = MaxChargeCurrrent50

PS: I am also thinking about improving the charge level calculation during charging, but that is a larger topic ... maybe future

I agree, both of these would be cool to have.

The BQ version used is the 25101 which is not having the PreTerm (no need to discuss that) feature but it has the charge status output.

I am not too sure about that... If you have a high confidence and can verify the operation, then sure! I was conflicted when looking at the datasheet and the wiki. The datasheet says BQ25100 and the wiki says BQ25101

Datasheet: https://files.seeedstudio.com/wiki/XIAO-BLE/Seeed-Studio-XIAO-nRF52840-Sense-v1.1.pdf Wiki: https://wiki.seeedstudio.com/XIAO_BLE/

in the meantime I understand that a connection error to the battery genrated the random voltage readings

If this is the case, I will then close this issue. If there is anything else, let us discuss that in a pull/merge request or in another issue:)

Happy tinkering!