# MAX17048.py SMBUS = True if SMBUS: import smbus else: from smbus2 import SMBus import time class My_MAX17048: def __init__(self): # MAX17048 registers # NAME ADDRESS PURPOSE/CONTENTS self.VCell = 0x02 # Cell voltage for a single cell self.SOC = 0x04 # Reported state of charge in mAhrs self.MODE = 0x06 # Initiates quick-start, reports hibernation mode, enables sleep mode self.Version = 0x08 # IC production version self.HIBRT = 0x0A # Controls trhesholds for entering and leaving hiberation self.Config = 0x0C # Compensation to optimize performance self.VALRT = 0x14 # VCELL range for alerts self.CRATE = 0x16 # charge/discharge rate of battery self.Vreset_ID = 0x18 # VCELL threshold for reset self.ChipID = 0x19 # Chip ID self.Status = 0x1A # shows alerts self.Table_start = 0x40 # Battery config self.Table_end = 0x7F # Battery config self.CMD = 0xFE # Send POR command if SMBUS: self.i2cbus = smbus.SMBus(1) else: self.i2cbus = SMBus(1) # Create a new I2C bus on port 1: pins 3 (SDA) and 5 (SCL) self.i2caddress = 0x36 # address of MAX17048 # Status register masks # These bits are set only when they cause an alert (e.g., if CONFIG.ALSC = 0, then SC is never set). # Reset Indicator: # RI (reset indicator) is set when the device powers up. Any time this bit is set, the IC is not configured, so the # model should be loaded and the bit should be cleared. self.RI = 0x01FF # VH (voltage high) is set when VCELL has been above ALRT.VALRTMAX. self.VH = 0x02FF # VL (voltage low) is set when VCELL has been below ALRT.VALRTMIN. self.VL = 0x4FF # VR (voltage reset) is set after the device has been reset if EnVr is set. self.VR = 0x08FF # HD (SOC low) is set when SOC crosses the value in CONFIG.ATHD. self.HD = 0x10FF # SC (1% SOC change) is set when SOC changes by at least 1% if CONFIG.ALSC is set. self.SC = 0x20FF # Enable or Disable VRESET Alert: # EnVr (enable voltage reset alert) when set to 1 asserts the ALRT pin when a voltage-reset event occurs under # the conditions described by the VRESET/ ID register. self.ENVR = 0x40FF def read_Status(self): s = self._read_register(self.Status) status = self._decode_status_register(s) return status def read_VCell(self): value = self._read_register(self.VCell) return value, (value * 78.125) / 1000000 def read_SOC(self): value = self._read_register(self.SOC) return value, int(value) / 256 def read_Chip_ID(self): value = self._read_register(self.ChipID) return value def read_Version(self): return self._read_register(self.Version) def read_Config(self): return self._read_register(self.Config) def read_VALRT(self): return self._read_register(self.VALRT) def read_CRATE(self): value = self._read_register(self.CRATE) return value * 0.208 def read_Vreset_ID(self): return self._read_register(self.Vreset_ID) def read_Status(self): return self._read_register(self.Status) def read_CMD(self): return self._read_register(self.CMD) def _read_register(self, register): if SMBUS: d = self.i2cbus.read_i2c_block_data(self.i2caddress, register, 2) data = d[0] * 256 + d[1] else: data = self.i2cbus.read_word_data(self.i2caddress, register) return data def _write_register(self, register, data): self.i2cbus.write_word_data(self.i2caddress, register, data) def _decode_status_register(self, data): status = { "RI": bool(data & self.RI), "VH": bool(data & self.VH), "VL": bool(data & self.VL), "VR": bool(data & self.VR), "HD": bool(data & self.HD), "SC": bool(data & self.SC), "ENVR": bool(data & self.ENVR), } return status