Files
ESP8266lib/ext/sens/INA3221.h
kazu ccd7f119d3 worked on SPI, fixed some bugs
adjusted LCD code
added code for INA3221
worked on UI
2020-06-24 21:28:44 +02:00

90 lines
1.9 KiB
C++

#ifndef SENS_INA_3221
#define SENS_INA_3221
/** 3-Channel i2c volt/ampere sensor */
template <typename I2C> class INA3221 {
private:
I2C& i2c;
static constexpr const uint8_t ADDR = 0b1000000;
static constexpr const char* NAME = "INA3221";
static constexpr const uint8_t REG_CFG = 0x00;
static constexpr const uint8_t REG_CH1_VS = 0x01; // shunt voltage
static constexpr const uint8_t REG_CH1_VB = 0x02; // bus voltage
static constexpr const uint8_t REG_CH2_VS = 0x03;
static constexpr const uint8_t REG_CH2_VB = 0x04;
static constexpr const uint8_t REG_CH3_VS = 0x05;
static constexpr const uint8_t REG_CH3_VB = 0x06;
public:
struct Channel {
int16_t vShunt;
int16_t vBus;
};
struct Voltages {
Channel ch1;
Channel ch2;
Channel ch3;
};
public:
INA3221(I2C& i2c) : i2c(i2c) {
}
/** get the current config */
uint16_t getConfig() {
uint16_t res = 0;
i2c.readReg(ADDR, REG_CFG, 2, (uint8_t*)&res);
return res;
}
/** read all 6 voltages (3 channels, each shunt and bus) */
Voltages getVoltages() {
uint8_t buf[2];
Voltages res;
i2c.readReg(ADDR, REG_CH1_VS, sizeof(buf), buf);
res.ch1.vShunt = getVoltage(buf);
i2c.readReg(ADDR, REG_CH1_VB, sizeof(buf), buf);
res.ch1.vBus = getVoltage(buf);
i2c.readReg(ADDR, REG_CH2_VS, sizeof(buf), buf);
res.ch2.vShunt = getVoltage(buf);
i2c.readReg(ADDR, REG_CH2_VB, sizeof(buf), buf);
res.ch2.vBus = getVoltage(buf);
i2c.readReg(ADDR, REG_CH3_VS, sizeof(buf), buf);
res.ch3.vShunt = getVoltage(buf);
i2c.readReg(ADDR, REG_CH3_VB, sizeof(buf), buf);
res.ch3.vBus = getVoltage(buf);
return res;
}
/** is an INA3221 present on the bus? */
bool isPresent() {
return i2c.query(ADDR);
}
private:
/** convert to bytes into a mV reading */
int16_t getVoltage(const uint8_t* buf) {
return ((buf[0] << 8) | (buf[1] << 0)); // the lowest 3 bits are always zero. no shift required!
}
};
#endif // SENS_INA_3221