Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 43 additions & 42 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,45 +30,46 @@ The `init_ina236` function allows to set up the INA236 either with default value
# Second parameter
# Change Vshct of the INA236.
# Choose between 8 different conversion times for the shunt voltage measurment
# 1. 140us
# 2. 204us
# 3. 332us
# 4. 588us
# 5. 1100us
# 6. 2116us
# 7. 4156us
# 8. 8244us
# 0. 140us
# 1. 204us
# 2. 332us
# 3. 588us
# 4. 1100us
# 5. 2116us
# 6. 4156us
# 7. 8244us
# Default initialization with '1100us'
# Third parameter
# Change Vbusct of the INA236.
# Choose between 8 different conversion times for the shunt voltage measurment
# 1. 140us
# 2. 204us
# 3. 332us
# 4. 588us
# 5. 1100us
# 6. 2116us
# 7. 4156us
# 8. 8244us
# 0. 140us
# 1. 204us
# 2. 332us
# 3. 588us
# 4. 1100us
# 5. 2116us
# 6. 4156us
# 7. 8244us
# Default initialization with '1100us'
# Fourth parameter
# Change Avg of the INA236.
# Choose between 8 different values to define the amount that is to be averaged
# 1. 1
# 2. 4
# 3. 16
# 4. 64
# 5. 128
# 6. 256
# 7. 512
# 8. 1024
# 0. 1
# 1. 4
# 2. 16
# 3. 64
# 4. 128
# 5. 256
# 6. 512
# 7. 1024
# Default initialization with '1'
# Fifth parameter
# Change ADCRange of the INA236.
# Choose between 2 different values that are to be used for the internal calculations
# 1. ±81.92mV
# 2. ±20.48mV
# 0. ±81.92mV
# 1. ±20.48mV
# Default initialization with '±81.92mV'

# Sixth parameter
# Change Address of the INA236.
# Choose between 4 different values which define the I2C Adress that is to be used for the communication
Expand Down Expand Up @@ -135,16 +136,16 @@ The `mask_enable` function allows to choose between 10 different options in the
```python
# Choose a option in the alert register of the INA236.
# Choose between 10 different options to define the part of the register that is to be used
# 1. SOL (Shunt Over-limit)
# 2. SUL (Shunt Under-limit)
# 3. BOL (Bus Over-limit)
# 4. BUL (Bus Under-limit)
# 5. POL (Power Over-limit)
# 6. CNVR (Conversion Ready)
# 7. MemError
# 8. AFF (Alert Function Flag)
# 9. CVRF (Conversion Ready Flag)
# 10. OVF (Math Over-flow)
# 0. SOL (Shunt Over-limit)
# 1. SUL (Shunt Under-limit)
# 2. BOL (Bus Over-limit)
# 3. BUL (Bus Under-limit)
# 4. POL (Power Over-limit)
# 5. CNVR (Conversion Ready)
# 6. MemError
# 7. AFF (Alert Function Flag)
# 8. CVRF (Conversion Ready Flag)
# 9. OVF (Math Over-flow)
# Default initialization with '1'
INA236.mask_enable(1);
```
Expand All @@ -163,24 +164,24 @@ INA236.write_alert_limit();
```

## Read from the alert register
The `read_alert_limit` function enables reading from the alert register of the INA236.
The `print_alert_limit` function enables reading from the alert register of the INA236 and printed to serial output.
```python
# Read from the alert register of the INA236.
INA236.read_alert_limit();
INA236.print_alert_limit();
```

## Read the manufacturer ID
The `manufacturer_ID` function enables the manufacturer ID of the INA236 to be read out.
The `print_manufacturer_ID` function enables the manufacturer ID of the INA236 to be read and printed to serial output.
```python
# Read from the manufacturer ID register of the INA236.
INA236.manufacturer_ID();
INA236.print_manufacturer_ID();
```

## Read the device ID
The `device_ID` function enables the device ID of the INA236 to be read.
The `print_device_ID` function enables the device ID of the INA236 to be read and printed to serial output.
```python
# Read from the device ID register of the INA236.
INA236.device_ID();
INA236.print_device_ID();
```

## Supported targets
Expand Down
80 changes: 49 additions & 31 deletions SBC_DVA.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,50 +11,56 @@

// Constructor //

SBCDVA::SBCDVA(uint8_t address) {
Address = address;
SBCDVA::SBCDVA(uint8_t _address, TwoWire* _wire) {
wire = _wire;
Address = _address;
Current_lsb = 0;
Lsb = _LSB[0];
Address = _ADDRESS_A[0];
Mode = _MODE[7];
Vshct = _VSHCT[4];
Vbusct = _VBUSCT[4];
Avg = _AVG[0];
Adcrange = _ADCRANGE[0];
byte temp[2];
}

// Private //

// Write the required 16-bit value into the register
void SBCDVA::_write_register(byte reg, int val) {
Wire.beginTransmission(Address);
Wire.write(reg);
Wire.write((val >> 8) & 0xFF);
Wire.write(val & 0xFF);
Wire.endTransmission();
wire->beginTransmission(Address);
wire->write(reg);
wire->write((val >> 8) & 0xFF);
wire->write(val & 0xFF);
wire->endTransmission();
// if (wire->endTransmission() != 0) // bus error
// return BUS_ERROR; // TODO: error handling? rely on read() error handling only?
}

// Read the 16-bit register value that will be returned
int SBCDVA::_read_register(byte reg) {
Wire.beginTransmission(Address);
Wire.write(reg);
Wire.endTransmission();
Wire.requestFrom(Address, 2);
int value = (Wire.read() << 8) | Wire.read();
wire->beginTransmission(Address);
wire->write(reg);
// wire->endTransmission();
if (wire->endTransmission() != 0) // bus error
return BUS_READ_ERROR;
// wire->requestFrom(Address, (uint8_t) 2);
if (wire->requestFrom(Address, (uint8_t) 2) == 0) // size 0
return BUS_READ_ERROR;
int value = (wire->read() << 8) | wire->read();
return value;
}

// Public //

// Initialize the INA236 with the user specified parameters
void SBCDVA::init_ina236(byte address, int mode, int vshct, int vbusct, int avg, int adcrange) {
void SBCDVA::init_ina236(int mode, int vshct, int vbusct, int avg, int adcrange, uint8_t _address) {
if (_address != 0x0) Address = _address; // use address set with constructor already, if not provided
_write_register(Config_Reg, RST); // Reset the INA236 registers
Mode = _MODE[mode];
Vshct = _VSHCT[vshct];
Vbusct = _VBUSCT[vbusct];
Avg = _AVG[avg];
Adcrange = _ADCRANGE[adcrange];
Address = _ADDRESS_A[address];
Lsb = (Adcrange == ADCRANGE_1) ? _LSB[0] : _LSB[1];
int config = 0x0000;
config |= Mode;
Expand All @@ -66,14 +72,14 @@ void SBCDVA::init_ina236(byte address, int mode, int vshct, int vbusct, int avg,
}

// Reset the INA236 registers
void SBCDVA::reset_ina236(byte address) {
Address = address;
void SBCDVA::reset_ina236(byte _address) {
Address = _address;
_write_register(Config_Reg, RST);
}

// Calibrate the INA236 for the correct Shunt measurement
void SBCDVA::calibrate_ina236() {
float current_lsb_min = 10 / pow(2, 15);
static const float current_lsb_min = 10 / pow(2, 15);
Current_lsb = current_lsb_min + 0.0018;
int SHUNT_CAL = 0.00512 / (Current_lsb * 0.008);
SHUNT_CAL = static_cast<int>(SHUNT_CAL);
Expand Down Expand Up @@ -108,33 +114,45 @@ float SBCDVA::read_bus_voltage() {
}

// Set the alert register
void SBCDVA::mask_enable(byte val = 1) {
void SBCDVA::mask_enable(byte val) {
if (val > sizeof(_MASK_ENABLE)) return;
int out = _MASK_ENABLE[val];
_write_register(Mask_Enable_Reg, out);
}

// Write a value into the alert register as reference
void SBCDVA::write_alert_limit(int val = 0x294) {
void SBCDVA::write_alert_limit(int val) {
_write_register(Alert_Limit_Reg, val);
}

// Read the value from the alert register
void SBCDVA::read_alert_limit() {
// print the value from the alert register
void SBCDVA::print_alert_limit(Stream* serial) {
if (serial == NULL) return;
int raw = _read_register(Alert_Limit_Reg);
Serial.println("Mask/Alert register value: " + String(raw));
serial->print(F("Mask/Alert register value: "));
serial->println(String(raw));
}

// Read the Manufacturer ID
void SBCDVA::manufacturer_ID() {
// print the Manufacturer ID
void SBCDVA::print_manufacturer_ID(Stream* serial) {
if (serial == NULL) return;
serial->print(F("Manufacturer ID: "));
if (_read_register(Manufacturer_ID_Reg) == 21577) {
Serial.println("Manufacturer ID: TI");
serial->println(F("TI"));
} else {
Serial.println("Manufacturer ID: nan");
serial->println(F("nan"));
}
}

// print the Device ID
void SBCDVA::print_device_ID(Stream* serial) {
if (serial == NULL) return;
serial->print(F("Device ID: "));
serial->println(String(_read_register(Device_ID_Reg)));
}

// Read the Device ID
void SBCDVA::device_ID() {
Serial.print("Device ID: ");
Serial.println(String(_read_register(Device_ID_Reg)));
int SBCDVA::read_device_ID() {
int value = _read_register(Device_ID_Reg);
return (value == BUS_READ_ERROR) ? 0 : value;
}
43 changes: 25 additions & 18 deletions SBC_DVA.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
#ifndef sbcdva
#define sbcdva

static const int READING_INVALID = -1024;

// Address variables ina236A
const byte GND_A = 0x40;
const byte VS_A = 0x41;
Expand Down Expand Up @@ -39,7 +41,7 @@ const int RST = 0x8000;
// Range of the ADC
const int ADCRANGE_1 = 0x0000;
const int ADCRANGE_2 = 0x1000;

// ADC values to be averaged
const int AVG_1 = 0x0000;
const int AVG_2 = 0x0200;
Expand Down Expand Up @@ -84,42 +86,47 @@ const int MODE_8 = 0x0007;
#include <Wire.h>
#include <math.h>


class SBCDVA {
public:
SBCDVA(uint8_t address);
void init_ina236(byte address, int mode, int vshct, int vbusct, int avg, int adcrange);
void reset_ina236(byte address);
SBCDVA(uint8_t _address, TwoWire* _wire = &Wire);
void init_ina236(int mode, int vshct, int vbusct, int avg, int adcrange, uint8_t _address = 0x0);
void reset_ina236(uint8_t _address);
void calibrate_ina236();
float read_current();
float read_power();
float read_shunt_voltage();
float read_bus_voltage();
int read_device_ID();
void mask_enable(byte val = 1);
void write_alert_limit(int val = 0x294);
void read_alert_limit();
void manufacturer_ID();
void device_ID();
void print_alert_limit(Stream* serial = &Serial);
void print_manufacturer_ID(Stream* serial = &Serial);
void print_device_ID(Stream* serial = &Serial);
float Current_lsb;
float Lsb;
byte Address;
uint8_t Address;
int Mode;
int Vshct;
int Vbusct;
int Avg;
int Adcrange;
byte temp[2];

private:
void _write_register(byte reg, int val);
int _read_register(byte reg);
int _ADDRESS_A[4] = { GND_A, VS_A, SDA_A, SCL_A };
int _ADDRESS_B[4] = { GND_B, VS_B, SDA_B, SCL_B };
int _ADCRANGE[2] = { ADCRANGE_1, ADCRANGE_2 };
float _LSB[3] = { 0.0000025, 0.000000625, 0.0016 };
int _AVG[8] = { AVG_1, AVG_2, AVG_3, AVG_4, AVG_5, AVG_6, AVG_7, AVG_8 };
int _VBUSCT[8] = { VBUSCT_1, VBUSCT_2, VBUSCT_3, VBUSCT_4, VBUSCT_5, VBUSCT_6, VBUSCT_7, VBUSCT_8 };
int _VSHCT[8] = { VSHCT_1, VSHCT_2, VSHCT_3, VSHCT_4, VSHCT_5, VSHCT_6, VSHCT_7, VSHCT_8 };
int _MODE[8] = { MODE_1, MODE_2, MODE_3, MODE_4, MODE_5, MODE_6, MODE_7, MODE_8 };
int _MASK_ENABLE[10] = { 0x8000, 0x4000, 0x2000, 0x1000, 0x0800, 0x0400, 0x0020, 0x0010, 0x0008, 0x0004 };
TwoWire* wire;
static constexpr int _ADDRESS_A[4] = { GND_A, VS_A, SDA_A, SCL_A };
static constexpr int _ADDRESS_B[4] = { GND_B, VS_B, SDA_B, SCL_B };
static constexpr int _ADCRANGE[2] = { ADCRANGE_1, ADCRANGE_2 };
static constexpr float _LSB[3] = { 0.0000025, 0.000000625, 0.0016 };
static constexpr int _AVG[8] = { AVG_1, AVG_2, AVG_3, AVG_4, AVG_5, AVG_6, AVG_7, AVG_8 };
static constexpr int _VBUSCT[8] = { VBUSCT_1, VBUSCT_2, VBUSCT_3, VBUSCT_4, VBUSCT_5, VBUSCT_6, VBUSCT_7, VBUSCT_8 };
static constexpr int _VSHCT[8] = { VSHCT_1, VSHCT_2, VSHCT_3, VSHCT_4, VSHCT_5, VSHCT_6, VSHCT_7, VSHCT_8 };
static constexpr int _MODE[8] = { MODE_1, MODE_2, MODE_3, MODE_4, MODE_5, MODE_6, MODE_7, MODE_8 };
static constexpr unsigned int _MASK_ENABLE[10] = { 0x8000, 0x4000, 0x2000, 0x1000, 0x0800, 0x0400, 0x0020, 0x0010, 0x0008, 0x0004 };

static const int BUS_READ_ERROR = 0;//0x8000;
};

#endif
6 changes: 3 additions & 3 deletions examples/SBC-DVA-Example/SBC-DVA-Example.ino
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ void setup() {
INA236.calibrate_ina236();
INA236.mask_enable(1);
INA236.write_alert_limit();
INA236.read_alert_limit();
INA236.manufacturer_ID();
INA236.device_ID();
INA236.print_alert_limit();
INA236.print_manufacturer_ID();
INA236.print_device_ID();
delay(5000); // Sleep for 5 seconds
Serial.println("start");
}
Expand Down