Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add nrf51xx battery status #117

Open
wants to merge 16 commits into
base: dev
Choose a base branch
from

Conversation

dkgs2000
Copy link

Support for reporting battery information on nrf51xx:

Relevant issue #100

NOTE: this is only the hardware part. Since i have some design questions i wanted to do this in parts.

Technical details:

I use the "status" byte (index 6) in the advertisement data to report the status. Currently only the first 2 highest bits.
I update the battery information every key exchange wake cycle.
All the code for the battery service is copied from here

Questions:

  1. When using a single key - there is no wake cycles... so the battery information will never be updated.
  • We can add another wake timer to handle the battery information. But the we have to make uint8_t *raw_data; accessible (global?)
  • We can apply the wake timer also for single key. Maybe change some parameters and make the setAndAdvertiseNextKey function more efficient.
  1. What should we do if the board doesn't support it? Since I dont have a physical nrf52xx board to test so i made sure my changed are for the nrf51xx only. What should i report when the board doesnt support battery information?

  2. Should i really use only 2 bit? The original project uses the rest of the 6 bits for a counter (irrelevant to us). We can use more data to get the exact % of the battery. Do we want to reserve the bits to something else?

  • Maybe for a "capabilities" bitmap? to report if the board support or doesn't support battery information?

I am very willing to dev this feature so plz tell me how should i progress from here.

@dchristl
Copy link
Owner

dchristl commented Sep 6, 2024

Hello @dkgs2000 ,

thanks for your work. Without changes to the remote station (front end), your change unfortunately offers no added value. This should be added before I can merge it. Have you actually checked whether the information can be retrieved from Apple at all? Simply transmitting via Bluetooth is useless if the information cannot be transmitted to and retrieved from the Apple servers. If so, where can this information be found in the report?

Kind Regards,
Danny

@dkgs2000
Copy link
Author

dkgs2000 commented Sep 7, 2024

Hey Danny! Thanks for replying :)

We already fetch the relevant data. I have check it on my local setup and also found a relevant code here

The status byte is the last (10th) byte of the decrypted & decoded payload array.
I have also added a commit as an example to how it can be read and added to the flutter frontend.
Sadly, I have 0 experience with flutter / dart :(

As I said, this PR still requires work on the 3 questions I have added in the first comment. Once they are answered and I fixed the firmware code to act accordingly - I think the GUI part is easy. either I'll learn flutter, or someone else could complete the job with my guidance.

Note that I added my own recommended solutions to each question.

Let me know how would you like this to progress :)

@dchristl
Copy link
Owner

dchristl commented Sep 9, 2024

I first wanted to know whether the entire route generally works before I got stuck into the questions and answered them ;)

When using a single key - there is no wake cycles... so the battery information will never be updated.
We can add another wake timer to handle the battery information. But the we have to make uint8_t *raw_data; accessible (global?)
We can apply the wake timer also for single key. Maybe change some parameters and make the setAndAdvertiseNextKey function more efficient.

Here we have a somewhat bigger problem. Rotating the keys (i.e. the additional wake cycle) consumes an insane amount of power, which is why I don't use it myself (any more). An nrf51 with one key lasts about a year, with several not even a month. Unfortunately, even with the help of the Nordic forum, I haven't managed to find a good and energy-saving solution. But I have to admit that I'm not a firmware programming pro. If you add a timer now, then a device with only one key will probably only last 1 month. Maybe you know your way around better and can make it more energy-efficient, otherwise I don't see much success for the feature, as CR2477 batteries are usually not very cheap.

What should we do if the board doesn't support it? Since I dont have a physical nrf52xx board to test so i made sure my changed are for the nrf51xx only. What should i report when the board doesnt support battery information?

Almost all compatible boards (except the NRF5X) do not support this ;) Any distinct information (i.e. 000000 ) should be fine. They can be filtered out in the UI.

Should i really use only 2 bit? The original project uses the rest of the 6 bits for a counter (irrelevant to us). We can use more data to get the exact % of the battery. Do we want to reserve the bits to something else?
Maybe for a "capabilities" bitmap? to report if the board support or doesn't support battery information?

I don't quite understand that? If you don't have any more information, then just leave it out. If you have the exact battery level, then add it (possibly in steps of ten or 5 to accommodate them in 6 bits). As I said, this feature is only supported by a fraction of the boards. Can you give me a few examples of what is now being sent and received?
i.e.
Battery low , 15 % -> 110011 (11 = battery low, 10 = 3 -> 3 x 5 )
Battery medium , 30 % -> 010110 (01 = battery medium, 100 = 6 -> 6 x 5 )
Battery high, 100% -> 1010100 (10 = battery high, 10100 = 20 -> 20 x 5 )

These are just examples and I don't know how what is possible in detail.

PuNS3c and others added 4 commits September 9, 2024 23:56
Added another row under the ListItem subtitle to represent a battery status with Icon and text.

Edited Acessory and Registry so they support that.
@dchristl
Copy link
Owner

FYI: Have you seen #120? This seems to me to be a good and significantly improved firmware alternative. When I have time, I'll try it out and take a look at the energy consumption

@dkgs2000
Copy link
Author

Cool! look promising. It looks like it doesn't support battery status update out-of-the-box all though there are many references in the code. Like this one. But the update_battery_level() function isn't actually fully implemented.

The SDK upgrade to version 12 is actually very important because in version 12.2 there is an SDK implementation of the es_battery_voltage_get(). In this PR i implement it on my own.

About the power consumption problem - as you said, whats taking power is waking the board. When switching keys we wake up every 30 minutes. If We'll create a new timer for the battery level update we can wake the board only once a day, week or even month. So I don't think it will have a huge effect on the power consumption.

To answer your question about the status byte - We use the 2 highest bits of the status byte to represents 4 level of battery status (level high, medium, low and critical). We don't need more than 4 value. I will also implement using another bit to represent boards the actually support this feature so we can use it in the GUI.

Note that thanks to @PuNS3c we now have full GUI support with icons to show the latest battery level of the tag.

What is missing in this PR currently (I'll be working on that):

  • Add another timer that wakes the board every X (I suggest 2 weeks) to update the battery level.
  • Add a bit to say whether the board supports battery status or not.

If you decide to use the firmware from #120 - I'll make sure to implement the battery update in the new firmware. The flutter code for battery icons will be the same :)

@dkgs2000
Copy link
Author

Done! I flashed the firmware on my tag and I'm getting good reports. I think its safe to merge it do dev branch now.
I'll let you know if any problems occur or i experience something weird.

@pix
Copy link

pix commented Sep 17, 2024

If you decide to use the firmware from #120 - I'll make sure to implement the battery update in the new firmware. The flutter code for battery icons will be the same :)

That sounds great! I'd be happy to chat if you're interested in implementing it. I'd like to make it optional, though, so that byte can be used for something else as well (hence the current implemented stubs)

es_battery_voltage_get() is nice indeed.

@T-REX-XP
Copy link

Maybe it's off-topic, but can somebody add Ota to the fw? It will be really useful to use it to flash the new version of the fw without uart. Thanks in advance.

@pix
Copy link

pix commented Oct 4, 2024

That sounds great! I'd be happy to chat if you're interested in implementing it. I'd like to make it optional, though, so that byte can be used for something else as well (hence the current implemented stubs)

es_battery_voltage_get() is nice indeed.

I pushed preliminary support using es_battery_voltage_get (reused key timer, updating ~ once a day +/- the key rotation interval)

Compile and seems to work on both nrf51 & nrf52.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants