INA3221 3 Channel Voltage Current Sensor Firmware Ported to Photon - Completed

@brianr Yes I did and here is the code:

.ino code:

    //
    //   SDL_Arduino_INA3221 Library Test Code
    //   SDL_Arduino_INA3221.cpp Arduino code - runs in continuous mode
    //   Version 1.1
    //   SwitchDoc Labs   January 31, 2015
    //
    //
    // This was designed for SunAirPlus - Solar Power Controller - www.switchdoc.com
    //
    
    
    #include "Particle.h"
    
    #include "SDL_Arduino_INA3221.h"
    
    SDL_Arduino_INA3221 ina3221;
    
    // the three channels of the INA3221 named for SunAirPlus Solar Power Controller channels (www.switchdoc.com)
    #define LIPO_BATTERY_CHANNEL 1
    #define SOLAR_CELL_CHANNEL 2
    #define OUTPUT_CHANNEL 3
    
    void setup(void) 
    {
        
      Serial.begin(57600);
      Serial.println("SDA_Arduino_INA3221_Test");
      
      Serial.println("Measuring voltage and current with ina3221 ...");
      ina3221.begin();
    }
    
    void loop(void) 
    {
      
      Serial.println("------------------------------");
      float shuntvoltage1 = 0;
      float busvoltage1 = 0;
      float current_mA1 = 0;
      float loadvoltage1 = 0;
    
    
      busvoltage1 = ina3221.getBusVoltage_V(LIPO_BATTERY_CHANNEL);
      shuntvoltage1 = ina3221.getShuntVoltage_mV(LIPO_BATTERY_CHANNEL);
      current_mA1 = -ina3221.getCurrent_mA(LIPO_BATTERY_CHANNEL);  // minus is to get the "sense" right.   - means the battery is charging, + that it is discharging
      loadvoltage1 = busvoltage1 + (shuntvoltage1 / 1000);
      
      Serial.print("LIPO_Battery Bus Voltage:   "); Serial.print(busvoltage1); Serial.println(" V");
      Serial.print("LIPO_Battery Shunt Voltage: "); Serial.print(shuntvoltage1); Serial.println(" mV");
      Serial.print("LIPO_Battery Load Voltage:  "); Serial.print(loadvoltage1); Serial.println(" V");
      Serial.print("LIPO_Battery Current 1:       "); Serial.print(current_mA1); Serial.println(" mA");
      Serial.println("");
    
      float shuntvoltage2 = 0;
      float busvoltage2 = 0;
      float current_mA2 = 0;
      float loadvoltage2 = 0;
    
      busvoltage2 = ina3221.getBusVoltage_V(SOLAR_CELL_CHANNEL);
      shuntvoltage2 = ina3221.getShuntVoltage_mV(SOLAR_CELL_CHANNEL);
      current_mA2 = -ina3221.getCurrent_mA(SOLAR_CELL_CHANNEL);
      loadvoltage2 = busvoltage2 + (shuntvoltage2 / 1000);
      
      Serial.print("Solar Cell Bus Voltage 2:   "); Serial.print(busvoltage2); Serial.println(" V");
      Serial.print("Solar Cell Shunt Voltage 2: "); Serial.print(shuntvoltage2); Serial.println(" mV");
      Serial.print("Solar Cell Load Voltage 2:  "); Serial.print(loadvoltage2); Serial.println(" V");
      Serial.print("Solar Cell Current 2:       "); Serial.print(current_mA2); Serial.println(" mA");
      Serial.println("");
    
      float shuntvoltage3 = 0;
      float busvoltage3 = 0;
      float current_mA3 = 0;
      float loadvoltage3 = 0;
    
      busvoltage3 = ina3221.getBusVoltage_V(OUTPUT_CHANNEL);
      shuntvoltage3 = ina3221.getShuntVoltage_mV(OUTPUT_CHANNEL);
      current_mA3 = ina3221.getCurrent_mA(OUTPUT_CHANNEL);
      loadvoltage3 = busvoltage3 + (shuntvoltage3 / 1000);
      
      Serial.print("Output Bus Voltage 3:   "); Serial.print(busvoltage3); Serial.println(" V");
      Serial.print("Output Shunt Voltage 3: "); Serial.print(shuntvoltage3); Serial.println(" mV");
      Serial.print("Output Load Voltage 3:  "); Serial.print(loadvoltage3); Serial.println(" V");
      Serial.print("Output Current 3:       "); Serial.print(current_mA3); Serial.println(" mA");
      Serial.println("");
    
      delay(1000);
    }

Here is the .CPP file:

//
//   SDL_Arduino_INA3221 Library
//   SDL_Arduino_INA3221.cpp Arduino code - runs in continuous mode
//   Version 1.1
//   SwitchDoc Labs   January 31, 2015
//
//



/*
    Initial code from INA219 code (Basically just a core structure left)
    @author   K.Townsend (Adafruit Industries)
    @license  BSD (see BSDlicense.txt)
*/
#include "Particle.h"



#include "SDL_Arduino_INA3221.h"

/**************************************************************************/
/*! 
    @brief  Sends a single command byte over I2C
*/
/**************************************************************************/
void SDL_Arduino_INA3221::wireWriteRegister (uint8_t reg, uint16_t value)
{
  Wire.beginTransmission(INA3221_i2caddr);
  
    Wire.write(reg);                       // Register
    Wire.write((value >> 8) & 0xFF);       // Upper 8-bits
    Wire.write(value & 0xFF);              // Lower 8-bits
 
  Wire.endTransmission();
}

/**************************************************************************/
/*! 
    @brief  Reads a 16 bit values over I2C
*/
/**************************************************************************/
void SDL_Arduino_INA3221::wireReadRegister(uint8_t reg, uint16_t *value)
{

  Wire.beginTransmission(INA3221_i2caddr);
 
    Wire.write(reg);                       // Register
    Wire.endTransmission();
  
  delay(1); // Max 12-bit conversion time is 586us per sample

  Wire.requestFrom(INA3221_i2caddr, (uint8_t)2);  
  
    *value = ((Wire.read() << 8) | Wire.read());
 
}

//
void SDL_Arduino_INA3221::INA3221SetConfig(void)
{
 
 
  // Set Config register to take into account the settings above
  uint16_t config = INA3221_CONFIG_ENABLE_CHAN1 |
                    INA3221_CONFIG_ENABLE_CHAN2 |
                    INA3221_CONFIG_ENABLE_CHAN3 |
                    INA3221_CONFIG_AVG1 |
                    INA3221_CONFIG_VBUS_CT2 |
                    INA3221_CONFIG_VSH_CT2 |
                    INA3221_CONFIG_MODE_2 |
                    INA3221_CONFIG_MODE_1 |
                    INA3221_CONFIG_MODE_0;
  wireWriteRegister(INA3221_REG_CONFIG, config);
}

/**************************************************************************/
/*! 
    @brief  Instantiates a new SDL_Arduino_INA3221 class
*/
/**************************************************************************/
SDL_Arduino_INA3221::SDL_Arduino_INA3221(uint8_t addr, float shuntresistor) {
    
    INA3221_i2caddr = addr;
    INA3221_shuntresistor = shuntresistor;
 
}

/**************************************************************************/
/*! 
    @brief  Setups the HW (defaults to 32V and 2A for calibration values)
*/
/**************************************************************************/
void SDL_Arduino_INA3221::begin() {
  Wire.begin();    
  // Set chip to known config values to start
  INA3221SetConfig();
    
    Serial.print("shut resistor="); Serial.println(INA3221_shuntresistor);
        Serial.print("address="); Serial.println(INA3221_i2caddr);
    
}

/**************************************************************************/
/*! 
    @brief  Gets the raw bus voltage (16-bit signed integer, so +-32767)
*/
/**************************************************************************/
int16_t SDL_Arduino_INA3221::getBusVoltage_raw(int channel) {
  uint16_t value;
  wireReadRegister(INA3221_REG_BUSVOLTAGE_1+(channel -1) *2, &value);
//    Serial.print("BusVoltage_raw=");
//    Serial.println(value,HEX);

  // Shift to the right 3 to drop CNVR and OVF and multiply by LSB
  return (int16_t)(value );
}

/**************************************************************************/
/*! 
    @brief  Gets the raw shunt voltage (16-bit signed integer, so +-32767)
*/
/**************************************************************************/
int16_t SDL_Arduino_INA3221::getShuntVoltage_raw(int channel) {
  uint16_t value;
  wireReadRegister(INA3221_REG_SHUNTVOLTAGE_1+(channel -1) *2, &value);
   // Serial.print("ShuntVoltage_raw=");
   // Serial.println(value,HEX);
  return (int16_t)value;
}


 
/**************************************************************************/
/*! 
    @brief  Gets the shunt voltage in mV (so +-168.3mV)
*/
/**************************************************************************/
float SDL_Arduino_INA3221::getShuntVoltage_mV(int channel) {
  int16_t value;
  value = getShuntVoltage_raw(channel);
  return value * 0.005;
}

/**************************************************************************/
/*! 
    @brief  Gets the shunt voltage in volts
*/
/**************************************************************************/
float SDL_Arduino_INA3221::getBusVoltage_V(int channel) {
  int16_t value = getBusVoltage_raw(channel);
  return value * 0.001;
}

/**************************************************************************/
/*! 
    @brief  Gets the current value in mA, taking into account the
            config settings and current LSB
*/
/**************************************************************************/
float SDL_Arduino_INA3221::getCurrent_mA(int channel) {
    float valueDec = getShuntVoltage_mV(channel)/INA3221_shuntresistor;
  
  return valueDec;
}

Here is the .H file:

//
//   SDL_Arduino_INA3221 Library
//   SDL_Arduino_INA3221.cpp Arduino code - runs in continuous mode
//   Version 1.1
//   SwitchDoc Labs   January 31, 2015
//
//

/**************************************************************************/
/*! 
    Initial code from INA219 code (Basically just a core structure left)
    @author   K. Townsend (Adafruit Industries)
    @license  BSD (see BSDlicense.txt)
    
    */
/**************************************************************************/


#include "Particle.h"


/*=========================================================================
    I2C ADDRESS/BITS
    -----------------------------------------------------------------------*/
    #define INA3221_ADDRESS                         (0x40)    // 1000000 (A0+A1=GND)
    #define INA3221_READ                            (0x01)
/*=========================================================================*/

/*=========================================================================
    CONFIG REGISTER (R/W)
    -----------------------------------------------------------------------*/
    #define INA3221_REG_CONFIG                      (0x00)
    /*---------------------------------------------------------------------*/
    #define INA3221_CONFIG_RESET                    (0x8000)  // Reset Bit
    
    #define INA3221_CONFIG_ENABLE_CHAN1             (0x4000)  // Enable Channel 1
    #define INA3221_CONFIG_ENABLE_CHAN2             (0x2000)  // Enable Channel 2
    #define INA3221_CONFIG_ENABLE_CHAN3             (0x1000)  // Enable Channel 3
    
    #define INA3221_CONFIG_AVG2                     (0x0800)  // AVG Samples Bit 2 - See table 3 spec
    #define INA3221_CONFIG_AVG1                     (0x0400)  // AVG Samples Bit 1 - See table 3 spec
    #define INA3221_CONFIG_AVG0                     (0x0200)  // AVG Samples Bit 0 - See table 3 spec

    #define INA3221_CONFIG_VBUS_CT2                 (0x0100)  // VBUS bit 2 Conversion time - See table 4 spec
    #define INA3221_CONFIG_VBUS_CT1                 (0x0080)  // VBUS bit 1 Conversion time - See table 4 spec
    #define INA3221_CONFIG_VBUS_CT0                 (0x0040)  // VBUS bit 0 Conversion time - See table 4 spec

    #define INA3221_CONFIG_VSH_CT2                  (0x0020)  // Vshunt bit 2 Conversion time - See table 5 spec
    #define INA3221_CONFIG_VSH_CT1                  (0x0010)  // Vshunt bit 1 Conversion time - See table 5 spec
    #define INA3221_CONFIG_VSH_CT0                  (0x0008)  // Vshunt bit 0 Conversion time - See table 5 spec

    #define INA3221_CONFIG_MODE_2                   (0x0004)  // Operating Mode bit 2 - See table 6 spec
    #define INA3221_CONFIG_MODE_1                   (0x0002)  // Operating Mode bit 1 - See table 6 spec
    #define INA3221_CONFIG_MODE_0                   (0x0001)  // Operating Mode bit 0 - See table 6 spec

/*=========================================================================*/

/*=========================================================================
    SHUNT VOLTAGE REGISTER (R)
    -----------------------------------------------------------------------*/
    #define INA3221_REG_SHUNTVOLTAGE_1                (0x01)
/*=========================================================================*/

/*=========================================================================
    BUS VOLTAGE REGISTER (R)
    -----------------------------------------------------------------------*/
    #define INA3221_REG_BUSVOLTAGE_1                  (0x02)
/*=========================================================================*/

#define SHUNT_RESISTOR_VALUE  (0.1)   // default shunt resistor value of 0.1 Ohm

class SDL_Arduino_INA3221{
 public:
  SDL_Arduino_INA3221(uint8_t addr = INA3221_ADDRESS, float shuntresistor = SHUNT_RESISTOR_VALUE);
  void begin(void);
  float getBusVoltage_V(int channel);
  float getShuntVoltage_mV(int channel);
  float getCurrent_mA(int channel);

 private:
  uint8_t INA3221_i2caddr;
  float INA3221_shuntresistor;

  
  void wireWriteRegister(uint8_t reg, uint16_t value);
  void wireReadRegister(uint8_t reg, uint16_t *value);
  void INA3221SetConfig(void);
  int16_t getBusVoltage_raw(int channel);
  int16_t getShuntVoltage_raw(int channel);

};