I would like to build up a 'smart' battery for my RaspberryPi 3 and integrate it trough the OS. The electronics part is the easy task in this game. The complicate task (for me) is to find out how to share data coming from the 'smart' part of the battery package with the OS. There are many layers of software involved in handling such data but I think that most of them are already running in Raspbian (or any other distro running on Raspberry). I figured out (probably in a too semplicistic way) that I just needed to write up a 'driver' that:

  • Read data from SPI or I2C bus (coming from the battery logic)
  • packing them in a proper way
  • share them with OS

Am I wrong? What's the correct way to approach it?

  • The 'smart battery' is a battery capable to provide by proper means (a bus like I2C, SPI etc) his own health status including (but not limited to) voltage level, left capacity (current)... there are many ICs designed specifically to provide such infos while monitoring a battery. Such ICs often have an I2C or SPI bus to inteface with.
    – weirdgyn
    Jan 24, 2017 at 7:20
  • I believe you're approaching this generally correct in concept. There's a full project of what you're looking for here: github.com/aboudou/picheckvoltage Jan 28, 2017 at 20:02
  • @ShawnGordon There's a bit of a contradiction there. I agree the approach of the linked project is generally correct, however, it is not what the OP has proposed, unless "integrate it trough [sic] the OS" is totally superfluous.
    – goldilocks
    Jan 28, 2017 at 20:20
  • @ShawnGordon I checked pichekvoltage before starting this thread and discarded it just because it was not an integrated solution.
    – weirdgyn
    Jan 28, 2017 at 20:45

2 Answers 2


Based on what you've said, it sounds like it would be a fairly simple piece of software.

What's the correct way to approach it?

Not by "integrating it through the OS".

What you want is a userland application. While all such applications of course depend on the OS in order to function, they are not integrated with it in the same sense as a hardware driver.

If you are accessing a device via SPI or I2C, there's already a kernel driver for that; you would be making use of the userspace interface to it (or alternately, one of the pure userspace libraries specific to the pi, that work by mmap'ing kernelspace -- but you do not have to understand that part).

More specifically, you probably want a daemon service which monitors the state of the battery and responds to it accordingly.

  • This's for sure a possible approach. BUT I think that we are loosing something along the way. It's a fact that almost any desktop manager (KDE, GNOME etc) has it's own battery monitor suited to show the battery status of laptop computer. This 'application' (that of course should be a userland application) maybe talks 'directly' with every battery of every different laptop but more probably reads data shared in some other way from an inner OS layer (a driver or something else).
    – weirdgyn
    Feb 6, 2017 at 18:41
  • 1
    Alright, that's what you meant by "share data with the OS" (try to be clear and explicit; if you want to integrate with existing battery monitors, say so). Anyway, normal hardware access is always through the kernel, and that includes laptop batteries. I dunno whether that's part of ACPI or it's own thing (those kinds of questions should go to U&L), but userland apps like GUI monitors will access state through sysfs (e.g /sys/class/power_supply/...). To duplicate that for such monitors requires you create a kernel module.
    – goldilocks
    Feb 7, 2017 at 10:54
  • 1
    A sort of exception to "hardware access is always through the kernel" are devices attached to buses that have a userland interface such as SPI or I2C. Doing that will be simpler than writing a kernel module, but you won't get sysfs nodes.
    – goldilocks
    Feb 7, 2017 at 10:54

You could use another approach: an AD (analog to digital) converter like the PCF8591 or ADS1115 reading batttery voltage and a Python sketch reading the data via i2c.

You would write your Python script to be always runnning (while(1)) and make the OS run it at startup. Since you are in Python the possibilites are endless. Here is the tutorial for the ADS1115: https://learn.adafruit.com/adafruit-4-channel-adc-breakouts/python-circuitpython .

I am pretty sure you could share Python information with the systems as well, to fullfill your needs.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.