Created
March 18, 2022 16:41
-
-
Save bauergeorg/0a6363bc3b4215a1aa6095a8ce4f53c6 to your computer and use it in GitHub Desktop.
Python Script to communicate with LTC1760 via I2C on Raspberry Pi
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python | |
import smbus | |
# i2cdetect -y 1 | |
# Address | |
charger_address = 0x0A | |
battery_address = 0x0B | |
# Charger Functions | |
CHARGER_SPEC_INFO = 0x11 | |
CHARGER_MODE = 0x12 | |
CHARGER_STATUS = 0x13 | |
CHARGING_CURRENT = 0x14 | |
CHARGING_VOLTAGE = 0x15 | |
ALARM_WARNING = 0x16 | |
CHARGER_LTC0 = 0x3C | |
# Standard and common non-standard Smart Battery commands | |
BATTERY_MODE = 0x03 | |
TEMPERATURE = 0x08 | |
VOLTAGE = 0x09 | |
CURRENT = 0x0A | |
RELATIVE_SOC = 0x0D | |
ABSOLUTE_SOC = 0x0E | |
REMAINING_CAPACITY = 0x0F | |
FULL_CHARGE_CAPACITY = 0x10 | |
TIME_TO_FULL = 0x13 | |
CHARGING_CURRENT = 0x14 | |
CHARGING_VOLTAGE = 0x15 | |
BATTERY_STATUS = 0x16 | |
CYCLE_COUNT = 0x17 | |
DESIGN_CAPACITY = 0x18 | |
DESIGN_VOLTAGE = 0x19 | |
SPEC_INFO = 0x1A | |
MFG_DATE = 0x1B | |
SERIAL_NUM = 0x1C | |
MFG_NAME = 0x20 # String | |
DEV_NAME = 0x21 # String | |
CELL_CHEM = 0x22 # String | |
MFG_DATA = 0x23 # String | |
MFG_DATA3B = 0x4F # String | |
#define MFG_DATA3C 0x3C // String | |
#define MFG_DATA3D 0x3D // String | |
#define MFG_DATA3E 0x3E // String | |
#define MFG_DATA30 0x48 // String | |
#define MFG_DATA31 0x49 // String | |
#define MFG_DATA32 0x4A // String | |
#define MFG_DATA33 0x4B // String | |
CELL8_VOLTAGE = 0x43 | |
CELL7_VOLTAGE = 0x42 | |
CELL6_VOLTAGE = 0x41 | |
CELL5_VOLTAGE = 0x40 | |
CELL4_VOLTAGE = 0x3C # Individual cell voltages don't work on Lenovo and Dell Packs | |
CELL3_VOLTAGE = 0x3D | |
CELL2_VOLTAGE = 0x3E | |
CELL1_VOLTAGE = 0x3F | |
STATE_OF_HEALTH = 0x54 | |
def printFlag(txt, b, mask): | |
if( b & mask ): | |
print("{} ON".format(txt)) | |
else: | |
print("{} OFF".format(txt)) | |
def setSMBMux(battery: int): | |
''' battery 1 or 2''' | |
state = bus.read_word_data(charger_address, 0x01) | |
#print(state) | |
# set SMB_BAT[1], unset SMB_BAT[2] | |
if battery == 1: | |
newState = (state & (~0x2000)) | 0x1000 | |
# set SMB_BAT[2], unset SMB_BAT[1] | |
elif battery == 2: | |
newState = (state & (~0x1000)) | 0x2000 | |
else: | |
raise Exception("Unknown value") | |
bus.write_word_data(charger_address, 0x01, newState) | |
bus = smbus.SMBus(1) | |
print("\n************** CHARGER: 0x{:02x} ********************".format(charger_address)) | |
print("BatterySystemState: {}".format(bus.read_word_data(charger_address, 0x01))) | |
BatterySystemState = bus.read_word_data(charger_address, 0x01) | |
printFlag(" PRESENT BAT1", BatterySystemState, 0x0001) | |
printFlag(" PRESENT BAT2", BatterySystemState, 0x0002) | |
printFlag(" PRESENT BAT3", BatterySystemState, 0x0004) | |
printFlag(" PRESENT BAT4", BatterySystemState, 0x0008) | |
printFlag(" CHARGE BAT1", BatterySystemState, 0x0010) | |
printFlag(" CHARGE BAT2", BatterySystemState, 0x0020) | |
printFlag(" CHARGE BAT3", BatterySystemState, 0x0040) | |
printFlag(" CHARGE BAT4", BatterySystemState, 0x0080) | |
printFlag(" POWER BY BAT1", BatterySystemState, 0x0100) | |
printFlag(" POWER BY BAT2", BatterySystemState, 0x0200) | |
printFlag(" POWER BY BAT3", BatterySystemState, 0x0400) | |
printFlag(" POWER BY BAT4", BatterySystemState, 0x0800) | |
printFlag(" SMB BY BAT1", BatterySystemState, 0x1000) | |
printFlag(" SMB BY BAT2", BatterySystemState, 0x2000) | |
printFlag(" SMB BY BAT3", BatterySystemState, 0x4000) | |
printFlag(" SMB BY BAT4", BatterySystemState, 0x8000) | |
print("BatterySystemStateCont: {}".format(bus.read_word_data(charger_address, 0x02))) | |
BatterySystemStateCont = bus.read_word_data(charger_address, 0x02) | |
printFlag(" AC PRESENT", BatterySystemStateCont, 0x0001) | |
printFlag(" PWR NOT GOOD", BatterySystemStateCont, 0x0002) | |
printFlag(" CAL REQ SUPPORT", BatterySystemStateCont, 0x0004) | |
printFlag(" CAL REQ", BatterySystemStateCont, 0x0008) | |
printFlag(" CHARG INH", BatterySystemStateCont, 0x0010) | |
printFlag(" CHARG POR", BatterySystemStateCont, 0x0020) | |
printFlag(" CALIBRATE", BatterySystemStateCont, 0x0040) | |
printFlag(" CALIBRATE BAT1", BatterySystemStateCont, 0x0100) | |
printFlag(" CALIBRATE BAT2", BatterySystemStateCont, 0x0200) | |
printFlag(" CALIBRATE BAT3", BatterySystemStateCont, 0x0400) | |
printFlag(" CALIBRATE BAT4", BatterySystemStateCont, 0x0800) | |
print("BatterySystemInfo: {}".format(bus.read_word_data(charger_address, 0x04))) | |
BatterySystemInfo = bus.read_word_data(charger_address, 0x04) | |
print(" BATTERY SUPPORTED: {}". format(BatterySystemInfo & 0x000F)) | |
print(" BATTERY SYSTEM REVISION: {}". format((BatterySystemInfo & 0x00F0) >> 4)) | |
print("LTC: {}".format(bus.read_word_data(charger_address, CHARGER_LTC0))) | |
Ltc = bus.read_word_data(charger_address, CHARGER_LTC0) | |
print(" LTC VERSION: {}". format((Ltc & 0x000F))) | |
printFlag(" TURBO", Ltc, 0x0080) | |
printFlag(" POWER-OFF", Ltc, 0x8000) | |
print("\nSet Mux to BAT 1") | |
setSMBMux(1) | |
print("\n************** BATTERY: 0x{:02x} ********************".format(battery_address)) | |
print("Design Capacity: {} mAh".format(bus.read_byte_data(battery_address, DESIGN_CAPACITY))) | |
print("Full Charge Capacity: {} mAh".format(bus.read_byte_data(battery_address, FULL_CHARGE_CAPACITY))) | |
print("Design Voltage: {} mV".format(bus.read_byte_data(battery_address, DESIGN_VOLTAGE))) | |
print("Serial Number: {} ".format(bus.read_byte_data(battery_address, SERIAL_NUM))) | |
print("Specification Info: {} ".format(bus.read_byte_data(battery_address, SPEC_INFO))) | |
#print("State of Health: {} ".format(bus.read_byte_data(battery_address, STATE_OF_HEALTH))) | |
print("Max. Charging Current:{} mAh".format(bus.read_byte_data(battery_address, CHARGING_CURRENT))) | |
print("Max. Charging Voltage:{} mV".format(bus.read_byte_data(battery_address, CHARGING_VOLTAGE))) | |
print("Cycle Count: {} ".format(bus.read_byte_data(battery_address, CYCLE_COUNT))) | |
print("Actual Voltage: {} mV".format(bus.read_byte_data(battery_address, VOLTAGE))) | |
print("Remaining Capacity: {} mAh".format(bus.read_byte_data(battery_address, REMAINING_CAPACITY))) | |
print("Relative Charge: {} %".format(bus.read_byte_data(battery_address, RELATIVE_SOC))) | |
print("Absolute Charge: {} %".format(bus.read_byte_data(battery_address, ABSOLUTE_SOC))) | |
print("Time to full: {} min".format(bus.read_byte_data(battery_address, TIME_TO_FULL))) | |
print("Cell 1 Voltage: {} mV".format(bus.read_byte_data(battery_address, CELL1_VOLTAGE))) | |
print("Cell 2 Voltage: {} mV".format(bus.read_byte_data(battery_address, CELL2_VOLTAGE))) | |
print("Cell 3 Voltage: {} mV".format(bus.read_byte_data(battery_address, CELL3_VOLTAGE))) | |
print("Temperature: {} ?".format(bus.read_byte_data(battery_address, TEMPERATURE))) | |
print("Actual Current: {} mA".format(bus.read_byte_data(battery_address, CURRENT))) | |
print("\nSet Mux to BAT 2") | |
setSMBMux(2) | |
print("\n************** BATTERY: 0x{:02x} ********************".format(battery_address)) | |
print("Design Capacity: {} mAh".format(bus.read_byte_data(battery_address, DESIGN_CAPACITY))) | |
print("Full Charge Capacity: {} mAh".format(bus.read_byte_data(battery_address, FULL_CHARGE_CAPACITY))) | |
print("Design Voltage: {} mV".format(bus.read_byte_data(battery_address, DESIGN_VOLTAGE))) | |
print("Serial Number: {} ".format(bus.read_byte_data(battery_address, SERIAL_NUM))) | |
print("Specification Info: {} ".format(bus.read_byte_data(battery_address, SPEC_INFO))) | |
#print("State of Health: {} ".format(bus.read_byte_data(battery_address, STATE_OF_HEALTH))) | |
print("Max. Charging Current:{} mAh".format(bus.read_byte_data(battery_address, CHARGING_CURRENT))) | |
print("Max. Charging Voltage:{} mV".format(bus.read_byte_data(battery_address, CHARGING_VOLTAGE))) | |
print("Cycle Count: {} ".format(bus.read_byte_data(battery_address, CYCLE_COUNT))) | |
print("Actual Voltage: {} mV".format(bus.read_byte_data(battery_address, VOLTAGE))) | |
print("Remaining Capacity: {} mAh".format(bus.read_byte_data(battery_address, REMAINING_CAPACITY))) | |
print("Relative Charge: {} %".format(bus.read_byte_data(battery_address, RELATIVE_SOC))) | |
print("Absolute Charge: {} %".format(bus.read_byte_data(battery_address, ABSOLUTE_SOC))) | |
print("Time to full: {} min".format(bus.read_byte_data(battery_address, TIME_TO_FULL))) | |
print("Cell 1 Voltage: {} mV".format(bus.read_byte_data(battery_address, CELL1_VOLTAGE))) | |
print("Cell 2 Voltage: {} mV".format(bus.read_byte_data(battery_address, CELL2_VOLTAGE))) | |
print("Cell 3 Voltage: {} mV".format(bus.read_byte_data(battery_address, CELL3_VOLTAGE))) | |
print("Temperature: {} ?".format(bus.read_byte_data(battery_address, TEMPERATURE))) | |
print("Actual Current: {} mA".format(bus.read_byte_data(battery_address, CURRENT))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Lots thanks goes to Bud Bennett