diff --git a/demo.py b/demo.py new file mode 100644 index 0000000..535027f --- /dev/null +++ b/demo.py @@ -0,0 +1,24 @@ +#!/usr/bin/env python3 +import powermon as pm +from time import sleep + +sensors = [ + [0x40, 0x08B6], # pink/blue: Pi + [0x44, 0x0B60] # pink/pink: Solar panel +] + +solarmon = pm.PowerMon(sensors) +powerData = None + +while True: + data = solarmon.getData() + print("Raspberry Pi Power Consumption:") + print(f"Vbus:\t\t{powerData[0].voltage} V") + print(f"Current:\t{powerData[0].current} A") + print(f"Power:\t\t{powerData[0].power} W") + + print("\nSolar Panel Power Production:") + print(f"Vbus:\t\t{powerData[1].voltage} V") + print(f"Current:\t{powerData[1].current} A") + print(f"Power:\t\t{powerData[1].power} W") + sleep(1) \ No newline at end of file diff --git a/inachip.py b/inachip.py new file mode 100644 index 0000000..d8a37ff --- /dev/null +++ b/inachip.py @@ -0,0 +1,48 @@ +#!/usr/bin/env python3 +import smbus2 + +VOLTAGE_REG_ADDR = 0x02 +POWER_REG_ADDR = 0x03 +CURRENT_REG_ADDR = 0x04 +CAL_REG_ADDR = 0x05 + +CURRENT_LSB = 0.00032 +VOLTAGE_LSB = 0.00125 +SHUNT_LSB = 0.0000025 + +class PowerData: + voltage = 0.0 + power = 0.0 + current = 0.0 + +class INA226: + def __init__(self, bus: smbus2.SMBus, addr: int, cal: int = 0): + self.addr = addr + self.cal = cal + self.bus = bus + self.data = PowerData() + + # Initial calibration + self.calibrate(cal) + + def __readRegWord(self, reg: int) -> int: + regWord = self.bus.read_word_data(self.addr, reg) & 0xFFFF + regValue = ((regWord << 8) & 0xFF00) + (regWord >> 8) + return regValue + + def __writeRegWord(self, reg: int, val: int) -> None: + regBytes = [(val >> 8) & 0xFF,val & 0xFF] + self.bus.write_i2c_block_data(self.addr, reg, regBytes) + + # Calibrate current sensor + def calibrate(self, cal: int) -> None: + self.__writeRegWord(CAL_REG_ADDR, cal) + + # Retrieve power data from sensor + def getData(self) -> PowerData: + self.data.voltage = float(self.__readRegWord(VOLTAGE_REG_ADDR)) * VOLTAGE_LSB + self.data.power = float(self.__readRegWord(POWER_REG_ADDR)) * CURRENT_LSB * 25.0 + self.data.current = float(self.__readRegWord(CURRENT_REG_ADDR)) * CURRENT_LSB + return self.data + + \ No newline at end of file diff --git a/powermon.py b/powermon.py new file mode 100644 index 0000000..1bcacec --- /dev/null +++ b/powermon.py @@ -0,0 +1,26 @@ +#!/usr/bin/env python3 +import smbus2 +from inachip import * + + +class PowerMon: + def __init__(self, sensors: list): + self.bus = smbus2.SMBus(1) + self.sensors = sensors + self.chipObjs = [] + try: + ina = None + for i in range(len(sensors)): + if type(list[i]) is int: + ina = INA226(self.bus, sensors[i]) + else: + ina = INA226(self.bus, sensors[i][0], sensors[i][1]) + self.chipObjs.append(ina) + except Exception as e: + raise Exception("Initiating sensors failed: " + e) + + def getData(self) -> list[PowerData]: + results = [] + for chip in self.chipObjs: + results.append(chip.getData()) + return results