Files
ESP8266lib/ext/sens/INA219.h

101 lines
2.3 KiB
C++

#ifndef SENS_INA_219
#define SENS_INA_219
/** 1-Channel i2c volt/ampere sensor */
template <typename I2C> class INA219 {
private:
I2C& i2c;
static constexpr const uint8_t ADDR = 0b1000000;
static constexpr const char* NAME = "INA219";
static constexpr const uint8_t REG_CFG = 0x00;
static constexpr const uint8_t REG_VS = 0x01; // shunt voltage
static constexpr const uint8_t REG_VB = 0x02; // bus voltage
public:
struct Voltages {
int16_t vShunt; // in uV * 10(!!!)
int16_t vBus; // in mV
int getMilliAmps(int shunt_milliOhm) const {
return (vShunt * 10) / shunt_milliOhm;
}
};
public:
INA219(I2C& i2c) : i2c(i2c) {
}
/** get the current config */
uint16_t getConfig() {
uint8_t buf[2];
i2c.readReg(ADDR, REG_CFG, 2, (uint8_t*)&buf);
return getU16(buf);
}
/** read both voltages (shunt and bus) */
Voltages getVoltages() {
uint8_t buf[2];
Voltages res;
i2c.readReg(ADDR, REG_VS, sizeof(buf), buf);
res.vShunt = getShuntVoltage(buf);
i2c.readReg(ADDR, REG_VB, sizeof(buf), buf);
res.vBus = getBusVoltage(buf);
return res;
}
/** is an INA219 present on the bus? */
bool isPresent() {
return i2c.query(ADDR);
}
/*
void dumpConfig() {
const uint16_t cfg = getConfig();
const uint8_t mode = (cfg & 0b00000000000111) >> 0;
const uint8_t sadc = (cfg & 0b00000001111000) >> 3;
const uint8_t badc = (cfg & 0b00011110000000) >> 7;
const uint8_t pg = (cfg & 0b01100000000000) >> 11;
const uint8_t brng = (cfg & 0b10000000000000) >> 13;
printf("INA219\n");
printf("- Mode: %d\n", mode);
printf("- SADC: %d\n", sadc);
printf("- BADC: %d\n", badc);
printf("PG (shunt divider) %d\n", (1<<pg));
if (brng) {printf("- bus voltage range [0:16]\n");}
else {printf("- bus voltage range [0:32]\n");}
}
*/
private:
/** convert to bytes into a mV reading */
int16_t getBusVoltage(const uint8_t* buf) {
return (int16_t)((getU16(buf) >> 3) * 4); // lower 3 bits are status indicators -> remove, the LSB equals 4 mV -> * 4
}
/** convert to bytes into a uV reading */
int16_t getShuntVoltage(const uint8_t* buf) {
return (int16_t)getU16(buf); // NOTE: LSB = 10 uV
}
uint16_t getU16(const uint8_t* buf) {
return ((buf[0] << 8) | (buf[1] << 0));
}
};
#endif // SENS_INA_219