198 lines
5.9 KiB
C++
198 lines
5.9 KiB
C++
#include "INA233.h"
|
|
|
|
|
|
uint16_t get_word(uint8_t address, uint8_t reg) {
|
|
uint8_t data[2];
|
|
int16_t rawVoltage;
|
|
|
|
// Request data from the PMBus device
|
|
Wire.beginTransmission(address);
|
|
Wire.write(reg);
|
|
Wire.endTransmission();
|
|
Wire.requestFrom(address, 2);
|
|
|
|
if (Wire.available() == 2) {
|
|
data[0] = Wire.read();
|
|
data[1] = Wire.read();
|
|
} else {
|
|
// return 0 on error
|
|
return 0.0;
|
|
}
|
|
|
|
// Combine the two bytes into a single 16-bit value
|
|
return (data[1] << 8) | data[0];
|
|
}
|
|
|
|
String INA233::get_device_model() {
|
|
char data[7]; // Array size includes space for the null terminator
|
|
|
|
// Request data from the PMBus device
|
|
Wire.beginTransmission(INA233::_address);
|
|
Wire.write(0x9A); // Command to read the manufacturer ID
|
|
Wire.endTransmission();
|
|
Wire.requestFrom(INA233::_address, 7);
|
|
|
|
if (Wire.available() == 7) {
|
|
uint8_t i = Wire.read();
|
|
data[0] = Wire.read();
|
|
data[1] = Wire.read();
|
|
data[2] = Wire.read();
|
|
data[3] = Wire.read();
|
|
data[4] = Wire.read();
|
|
data[5] = Wire.read();
|
|
data[6] = '\0'; // Null-terminate the string
|
|
} else {
|
|
return String("");
|
|
}
|
|
|
|
return String(data);
|
|
}
|
|
|
|
|
|
void sendWord(uint8_t deviceAddress, uint8_t registerAddress, uint16_t value) {
|
|
Wire.beginTransmission(deviceAddress);
|
|
Wire.write(registerAddress); // Send the register address
|
|
Wire.write((uint8_t)value); // Send the low byte first
|
|
Wire.write((uint8_t)(value >> 8)); // Send the high byte next
|
|
Wire.endTransmission();
|
|
}
|
|
|
|
void sendByte(uint8_t deviceAddress, uint8_t registerAddress, uint8_t value) {
|
|
Wire.beginTransmission(deviceAddress);
|
|
Wire.write(registerAddress); // Send the register address
|
|
Wire.write((uint8_t)value); // Send the low byte first
|
|
Wire.endTransmission();
|
|
}
|
|
|
|
INA233::INA233(const uint8_t address, TwoWire *wire)
|
|
{
|
|
_address = address;
|
|
_wire = wire;
|
|
// not calibrated values by default.
|
|
_current_LSB = 0;
|
|
_maxCurrent = 0;
|
|
_shunt = 0;
|
|
}
|
|
|
|
bool INA233::begin(const uint8_t sda, const uint8_t scl)
|
|
{
|
|
_wire->begin(sda, scl);
|
|
if (! isConnected()) return false;
|
|
return true;
|
|
}
|
|
|
|
bool INA233::isConnected()
|
|
{
|
|
_wire->beginTransmission(_address);
|
|
return ( _wire->endTransmission() == 0);
|
|
}
|
|
|
|
float INA233::getBusVoltage() {
|
|
uint8_t data[2];
|
|
int16_t rawVoltage;
|
|
|
|
// Request data from the PMBus device
|
|
Wire.beginTransmission(INA233::_address);
|
|
Wire.write(REGISTER_READ_VIN);
|
|
Wire.endTransmission();
|
|
Wire.requestFrom(INA233::_address, 2);
|
|
|
|
if (Wire.available() == 2) {
|
|
data[0] = Wire.read();
|
|
data[1] = Wire.read();
|
|
} else {
|
|
// Handle error (e.g., return 0.0 or a special error value)
|
|
return 0.0;
|
|
}
|
|
|
|
// Combine the two bytes into a single 16-bit value
|
|
rawVoltage = (data[1] << 8) | data[0];
|
|
|
|
// Convert raw value to actual voltage using the appropriate scaling
|
|
// For example, assuming a linear scaling with a coefficient of 1.25 mV per LSB:
|
|
float voltage = rawVoltage * 1.25 / 1000.0;
|
|
|
|
return voltage;
|
|
}
|
|
|
|
float INA233::getShuntVoltage() {
|
|
int16_t rawVoltage = get_word(INA233::_address, REGISTER_READ_VSHUNT); // Read raw voltage (16-bit register)
|
|
|
|
// Convert from two's complement to an integer value
|
|
// If the MSB (most significant bit) is set, the number is negative
|
|
if (rawVoltage & 0x8000) { // Check if MSB (bit 15) is set
|
|
rawVoltage = rawVoltage - 0x10000; // Convert two's complement negative number
|
|
}
|
|
|
|
// Convert value according to the datasheet
|
|
// LSB: 2.5 μV per bit -> Multiply by 2.5e-6 to convert to volts
|
|
float voltage = rawVoltage * 2.5e-6;
|
|
|
|
return voltage;
|
|
}
|
|
|
|
float INA233::getShuntVoltage_mV() {
|
|
return getShuntVoltage() * 1000;
|
|
}
|
|
|
|
void INA233::setAveragingMode(AveragingMode avg_mode) {
|
|
uint8_t avg_bits = avg_mode;
|
|
|
|
uint16_t old_conf = get_word(INA233::_address, REGISTER_CONFIGURATION);
|
|
|
|
// Mask to clear bits 9, 10, and 11 (positions 9 to 11) in the original register
|
|
uint16_t clear_mask = ~(0x7 << 9);
|
|
old_conf &= clear_mask;
|
|
|
|
// Prepare new bits: extract 3 bits from new_bits and shift them to position 9
|
|
// 0x7 ensures only the last 3 bits are considered
|
|
uint16_t set_bits = (avg_bits & 0x7) << 9;
|
|
|
|
// Set the new bits in the register
|
|
old_conf |= set_bits;
|
|
sendWord(INA233::_address, REGISTER_CONFIGURATION, old_conf);
|
|
};
|
|
|
|
void INA233::setBusVoltageConversionTime(ConversionTime conversion_time) {
|
|
uint8_t conv_bits = conversion_time;
|
|
|
|
uint16_t old_conf = get_word(INA233::_address, REGISTER_CONFIGURATION);
|
|
|
|
// Mask to clear bits 9, 10, and 11 (positions 6 to 8) in the original register
|
|
uint16_t clear_mask = ~(0x7 << 6);
|
|
old_conf &= clear_mask;
|
|
|
|
// Prepare new bits: extract 3 bits from new_bits and shift them to position 6
|
|
// 0x7 ensures only the last 3 bits are considered
|
|
uint16_t set_bits = (conv_bits & 0x7) << 6;
|
|
|
|
// Set the new bits in the register
|
|
old_conf |= set_bits;
|
|
sendWord(INA233::_address, REGISTER_CONFIGURATION, old_conf);
|
|
};
|
|
|
|
void INA233::setShuntVoltageConversionTime(ConversionTime conversion_time) {
|
|
uint8_t conv_bits = conversion_time;
|
|
|
|
uint16_t old_conf = get_word(INA233::_address, REGISTER_CONFIGURATION);
|
|
|
|
// Mask to clear bits 9, 10, and 11 (positions 3 to 5) in the original register
|
|
uint16_t clear_mask = ~(0x7 << 3);
|
|
old_conf &= clear_mask;
|
|
|
|
// Prepare new bits: extract 3 bits from new_bits and shift them to position 3
|
|
// 0x7 ensures only the last 3 bits are considered
|
|
uint16_t set_bits = (conv_bits & 0x7) << 3;
|
|
|
|
// Set the new bits in the register
|
|
old_conf |= set_bits;
|
|
sendWord(INA233::_address, REGISTER_CONFIGURATION, old_conf);
|
|
};
|
|
|
|
uint16_t INA233::getConfigRegister() {
|
|
return get_word(INA233::_address, REGISTER_CONFIGURATION);
|
|
}
|
|
|
|
void INA233::reset() {
|
|
sendByte(INA233::_address, 0x12, 0x00);
|
|
} |