diff --git a/README.md b/README.md index 18fb41f..03e419a 100644 --- a/README.md +++ b/README.md @@ -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 @@ -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); ``` @@ -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 diff --git a/SBC_DVA.cpp b/SBC_DVA.cpp index cfab699..5b23460 100644 --- a/SBC_DVA.cpp +++ b/SBC_DVA.cpp @@ -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; @@ -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(SHUNT_CAL); @@ -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; } diff --git a/SBC_DVA.h b/SBC_DVA.h index 0e5dd74..055057c 100644 --- a/SBC_DVA.h +++ b/SBC_DVA.h @@ -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; @@ -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; @@ -84,42 +86,47 @@ const int MODE_8 = 0x0007; #include #include + 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 \ No newline at end of file diff --git a/examples/SBC-DVA-Example/SBC-DVA-Example.ino b/examples/SBC-DVA-Example/SBC-DVA-Example.ino index 63da2f6..927b81a 100644 --- a/examples/SBC-DVA-Example/SBC-DVA-Example.ino +++ b/examples/SBC-DVA-Example/SBC-DVA-Example.ino @@ -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"); }