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

feat: Add INA219 battery sensor #2380

Merged
merged 19 commits into from
Jun 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 54 additions & 5 deletions documentation/builders/components/power/batterymonitor.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
# Battery Monitor based on a ADS1015
# Battery Monitor

> [!CAUTION]
> Lithium and other batteries are dangerous and must be treated with care.
> Rechargeable Lithium Ion batteries are potentially hazardous and can
> present a serious **FIRE HAZARD** if damaged, defective or improperly used.
> Do not use this circuit to a lithium ion battery without expertise and
> training in handling and use of batteries of this type.
> present a serious **FIRE HAZARD** if damaged, defective, or improperly used.
> Do not use this circuit for a lithium-ion battery without the expertise and
> training in handling and using batteries of this type.
> Use appropriate test equipment and safety protocols during development.
> There is no warranty, this may not work as expected or at all!
> There is no warranty, this may not work as expected!

## Battery Monitor based on a ADS1015

The script in [src/jukebox/components/battery_monitor/batt_mon_i2c_ads1015/\_\_init\_\_.py](../../../../src/jukebox/components/battery_monitor/batt_mon_i2c_ads1015/__init__.py) is intended to read out the voltage of a single Cell LiIon Battery using a [CY-ADS1015 Board](https://www.adafruit.com/product/1083):

Expand All @@ -31,3 +33,50 @@ The script in [src/jukebox/components/battery_monitor/batt_mon_i2c_ads1015/\_\_i
>
> * the circuit is constantly draining the battery! (leak current up to: 2.1µA)
> * the time between sample needs to be a minimum 1sec with this high impedance voltage divider don't use the continuous conversion method!

## Battery Monitor based on an INA219

The script in [src/jukebox/components/battery_monitor/batt_mon_i2c_ina219/\_\_init\_\_.py](../../../../src/jukebox/components/battery_monitor/batt_mon_i2c_ina219/__init__.py) is intended to read out the voltage of a single cell or multiple LiIon Battery using a [INA219 Board](https://www.adafruit.com/product/904):

```text
3.3V
+
|
.----o----.
| | SDA
.-------------------------------o AIN o------
| | INA219 | SCL
| .----------o AOUT o------
--- | | |
Battery - Regulator + Raspi '----o----'
2.9V-4.2V| | |
| | |
=== === ===
```

## Configuration example

The battery monitoring is configured in the jukebox.yml file.

The "battmon" module has to be added to the modules setting.

```yaml
modules:
named:
# Do not change the order!
publishing: publishing
...
battmon: battery_monitor.batt_mon_i2c_ina219
```

The battmon module needs further configuration:

```yaml
battmon:
scale_to_phy_num: 1
scale_to_phy_denom: 0
warning_action:
all_clear_action:
```

The setting "scale_to_phy_denom" does not influence the INA219. However, the scale can be adjusted to fit multiple LiIon cells.
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# RPi-Jukebox-RFID Version 3
# Copyright (c) See file LICENSE in project root folder

import logging
import jukebox.plugs as plugs
import jukebox.cfghandler
from ina219 import INA219
from ina219 import DeviceRangeError
from components.battery_monitor import BatteryMonitorBase

logger = logging.getLogger('jb.battmon.ina219')

batt_mon = None


class battmon_ina219(BatteryMonitorBase.BattmonBase):
'''Battery Monitor based on a INA219
saeugetier marked this conversation as resolved.
Show resolved Hide resolved

See [Battery Monitor documentation](../../builders/components/power/batterymonitor.md)
'''

def __init__(self, cfg):
super().__init__(cfg, logger)

def init_batt_mon_hw(self, num: float, denom: float) -> None:
try:
self.adc = INA219(float(num) / 1000, busnum=1)
self.adc.configure(self.adc.RANGE_16V, self.adc.GAIN_AUTO, self.adc.ADC_32SAMP, self.adc.ADC_32SAMP)
except DeviceRangeError as e:
logger.error(f"Device range error: {e}")
raise
except Exception as e:
logger.error(f"Failed to initialize INA219: {e}")
raise

def get_batt_voltage(self) -> int:
try:
batt_voltage_mV = self.adc.supply_voltage() * 1000.0
return int(batt_voltage_mV)
except Exception as e:
logger.error(f"Failed to get supply voltage from INA219: {e}")
raise


@plugs.finalize
def finalize():
global batt_mon
cfg = jukebox.cfghandler.get_handler('jukebox')
batt_mon = battmon_ina219(cfg)
plugs.register(batt_mon, name='batt_mon')


@plugs.atexit
def atexit(**ignored_kwargs):
global batt_mon
batt_mon.status_thread.cancel()