LTC2991 Current Measurement Problem

Hello;

I am trying to read motor arm currents using the LTC2991 IC. But I have encountered some problems as follows:

I can read the battery voltages in single-ended mode. However, I always have an offset value when reading currents in differential mode and these offset values are different on each of my PCB. For example; 

V4 Current Measurement --> No Load --> 4.5 (PdbCurrent.Pack1 = (float)(VoltageValue.Pack1*LTC2991_DIFFERENTIAL_lsb*Voltage_Divider)/Rsense)

V4 Current Measurement --> 1A Load --> 5.5

V1 Current Measurement --> No Load --> 16

V1 Current Measurement --> 2A Load --> 18

The hardware designed as reference design (datasheet page 25 Large Motor Protection / Regulation). The only difference is the values of the voltage divider resistors. Since in my design the battery voltage is between 16.2V-25.2V, the resistance values have been changed in order to obtain 3.3V at maximum voltage. Reference design and my code are listed below.

The Packs are Load connection.

VIN is Battery connection.

In software, respectively, the following has been done:

1) LTC2991 Initialize settings are made. These are LTC2991 Enable All channel, LTC2991 Repeat Mode.

2) To read the currents, the corresponding channel is taken in Differential mode and Data registers are read. 

3) These readings are merged in a 16-bit variable to control the Sign bit.

4) The status of the Sign bit is being processed.

// Calibration Variables
//! Typical single-ended LSB weight in volts
const float LTC2991_SINGLE_ENDED_lsb = 3.05176E-04;
//! Typical differential LSB weight in volts
const float LTC2991_DIFFERENTIAL_lsb = 1.90735E-05;
//! Typical VCC LSB weight in volts
const float LTC2991_VCC_lsb = 3.05176E-04;
//! Typical temperature LSB weight in degrees Celsius (and Kelvin).
//! Used for internal temperature as well as remote diode temperature measurements.
const float LTC2991_TEMPERATURE_lsb = 0.0625;
//! Typical remote diode LSB weight in volts.
//! Used to readback diode voltage when in temperature measurement mode.
const float LTC2991_DIODE_VOLTAGE_lsb = 3.815E-05;
const float Voltage_Divider = 7.8;


/**
 *@brief  Installation of necessary parameters LTC2991.
 *@param  I2C_channel : Which I2C channel is chosen here. 
 *@return none
 */
void ltc2991::LTC2991_Init(uint8_t I2C_channel)
{
    uint8_t i2c_data[1]={0};
    uint8_t Write_Error = 0;
    uint8_t ControlPwm;
    uint8_t ControlReg5678;   
    uint8_t ControlReg1234;
    uint8_t ChannelEnable;
    
    i2c_data[0] =  LTC2991_ENABLE_ALL_CHANNELS;   
    Write_Error += I2c.i2cWrite(I2C_channel,LTC2991_I2C_ADDRESS,LTC2991_CHANNEL_ENABLE_REG,i2c_data,1);
      
    i2c_data[0] = 0x00;
    Write_Error += I2c.i2cWrite(I2C_channel,LTC2991_I2C_ADDRESS,LTC2991_CONTROL_V1234_REG,i2c_data,1);
        
    i2c_data[0] = 0x00;
    Write_Error += I2c.i2cWrite(I2C_channel,LTC2991_I2C_ADDRESS,LTC2991_CONTROL_V5678_REG,i2c_data,1);
          
    i2c_data[0] = LTC2991_REPEAT_MODE;
    Write_Error += I2c.i2cWrite(I2C_channel,LTC2991_I2C_ADDRESS,LTC2991_CONTROL_PWM_Tinternal_REG,i2c_data,1);    
    
    I2c.i2cRead(I2C_channel,LTC2991_I2C_ADDRESS,LTC2991_CONTROL_PWM_Tinternal_REG,i2c_data,1);   
    ControlPwm = i2c_data[0];
    
    I2c.i2cRead(I2C_channel,LTC2991_I2C_ADDRESS,LTC2991_CONTROL_V5678_REG,i2c_data,1);   
    ControlReg5678 = i2c_data[0];
    
    I2c.i2cRead(I2C_channel,LTC2991_I2C_ADDRESS,LTC2991_CONTROL_V1234_REG,i2c_data,1);   
    ControlReg1234 = i2c_data[0];
    
    I2c.i2cRead(I2C_channel,LTC2991_I2C_ADDRESS,LTC2991_CHANNEL_ENABLE_REG,i2c_data,1);   
    ChannelEnable = i2c_data[0];
    
}

/**
 *@brief  Reads the current ESC through LTC2991.
 *@param  I2C_channel  : Which I2C channel is chosen here.
 *@param  EscSelected  : Which arm current?
 *@return f_Vx_Current : Returns the value of the selected LifeData.
 */
void ltc2991::readCurrent(uint8_t I2C_channel)
{
    uint8_t i2c_data[1]={0};   
    uint8_t sign = 0;
   
/******************************************************************************/          
            i2c_data[0] = LTC2991_V7_V8_DIFFERENTIAL_ENABLE | LTC2991_V5_V6_DIFFERENTIAL_ENABLE; //LTC2991_V5_V6_DIFFERENTIAL_ENABLE
            I2c.i2cWrite(I2C_channel,LTC2991_I2C_ADDRESS,LTC2991_CONTROL_V5678_REG,i2c_data,1);    
            
            I2c.i2cRead(I2C_channel,LTC2991_I2C_ADDRESS,LTC2991_V8_MSB_REG,i2c_data,1);
            VoltageValue.Pack1_VoltageMSB = i2c_data[0];
            I2c.i2cRead(I2C_channel,LTC2991_I2C_ADDRESS,LTC2991_V8_LSB_REG,i2c_data,1);
            VoltageValue.Pack1_VoltageLSB = i2c_data[0];
       
            VoltageValue.Pack1 = ((uint16_t)VoltageValue.Pack1_VoltageMSB)<<8  | VoltageValue.Pack1_VoltageLSB;
            SignController.PackSign1 = (VoltageValue.Pack1 >>14) & 0x01;
            
            if (SignController.PackSign1 == 1)
            {
                VoltageValue.Pack1 = ~(VoltageValue.Pack1);
                sign = -1;
            } 
            else
            {
                VoltageValue.Pack1 = (VoltageValue.Pack1);
                sign = 1;
            }
            VoltageValue.Pack1 = (VoltageValue.Pack1 & 0x3FFF);    
            
            PdbCurrent.Pack1 = (float)(VoltageValue.Pack1*LTC2991_DIFFERENTIAL_lsb*Voltage_Divider)/Rsense;    //VoltageDivider;
            Timer.timerDelayMicros(10);
/******************************************************************************/          

/******************************************************************************/      
            I2c.i2cRead(I2C_channel,LTC2991_I2C_ADDRESS,LTC2991_V6_MSB_REG,i2c_data,1);
            VoltageValue.Pack2_VoltageMSB = i2c_data[0];
            I2c.i2cRead(I2C_channel,LTC2991_I2C_ADDRESS,LTC2991_V6_LSB_REG,i2c_data,1);
            VoltageValue.Pack2_VoltageLSB = i2c_data[0];
       
            VoltageValue.Pack2 = ((uint16_t)VoltageValue.Pack2_VoltageMSB)<<8  | VoltageValue.Pack2_VoltageLSB;
            SignController.PackSign2 = (VoltageValue.Pack2 >>14) & 0x01;
           
            if (SignController.PackSign2 == 1)
            {
                VoltageValue.Pack2 = ~(VoltageValue.Pack2);
                sign = -1;
            }   
            else
            { 
                VoltageValue.Pack2 = (VoltageValue.Pack2);   
                sign = 1;
            }
            VoltageValue.Pack2 = (VoltageValue.Pack2 & 0x3FFF);    
            PdbCurrent.Pack2 = (float)(VoltageValue.Pack2*LTC2991_DIFFERENTIAL_lsb*Voltage_Divider)/Rsense;     //(4.413608)
            Timer.timerDelayMicros(10);
/******************************************************************************/  
            
/******************************************************************************/   
            i2c_data[0] = LTC2991_V3_V4_DIFFERENTIAL_ENABLE | LTC2991_V1_V2_DIFFERENTIAL_ENABLE;
            I2c.i2cWrite(I2C_channel,LTC2991_I2C_ADDRESS,LTC2991_CONTROL_V1234_REG,i2c_data,1);    
            
            I2c.i2cRead(I2C_channel,LTC2991_I2C_ADDRESS,LTC2991_V4_MSB_REG,i2c_data,1);
            VoltageValue.Pack3_VoltageMSB = i2c_data[0];
            I2c.i2cRead(I2C_channel,LTC2991_I2C_ADDRESS,LTC2991_V4_LSB_REG,i2c_data,1);
            VoltageValue.Pack3_VoltageLSB = i2c_data[0];
       
            VoltageValue.Pack3 = ((uint16_t)VoltageValue.Pack3_VoltageMSB)<<8  | VoltageValue.Pack3_VoltageLSB;
            SignController.PackSign3 = (VoltageValue.Pack3 >>14) & 0x01;
            
            if (SignController.PackSign3 == 1)
            {
                VoltageValue.Pack3 = ~(VoltageValue.Pack3);
                sign = -1;
            }   
            else
            {
                 VoltageValue.Pack3 = VoltageValue.Pack3;
                 sign = 1;
            }
            VoltageValue.Pack3 = (VoltageValue.Pack3 & 0x3FFF);    
            PdbCurrent.Pack3 = (float)(VoltageValue.Pack3*LTC2991_DIFFERENTIAL_lsb*Voltage_Divider)/Rsense;    //Voltage_Divider,-(14.092575)
            Timer.timerDelayMicros(10);
/******************************************************************************/  
            
/******************************************************************************/     
                     
            I2c.i2cRead(I2C_channel,LTC2991_I2C_ADDRESS,LTC2991_V2_MSB_REG,i2c_data,1);
            VoltageValue.Pack4_VoltageMSB = i2c_data[0];
            I2c.i2cRead(I2C_channel,LTC2991_I2C_ADDRESS,LTC2991_V2_LSB_REG,i2c_data,1);
            VoltageValue.Pack4_VoltageLSB = i2c_data[0];
       
            VoltageValue.Pack4 = ((uint16_t)VoltageValue.Pack4_VoltageMSB)<<8  | VoltageValue.Pack4_VoltageLSB;
            SignController.PackSign4 = (VoltageValue.Pack4 >>14) & 0x01;
                    
            if (SignController.PackSign4 == 1)
            {
                VoltageValue.Pack4 = ~(VoltageValue.Pack4);
                sign = -1;
            }   
            else
            {
                VoltageValue.Pack4 = (VoltageValue.Pack4);
                sign = 1;
            }
            VoltageValue.Pack4 = (VoltageValue.Pack4 & 0x3FFF);    
            PdbCurrent.Pack4 = (float)(VoltageValue.Pack4*LTC2991_DIFFERENTIAL_lsb*Voltage_Divider)/Rsense;   //Voltage_Divider -(10.810861)
             Timer.timerDelayMicros(10);
/******************************************************************************/  
}

void ltc2991::readPdbVoltage(uint8_t I2C_channel)
{
    uint8_t i2c_data[1]={0};
    float Voltage1;
/******************************************************************************/                         
    I2c.i2cRead(I2C_channel,LTC2991_I2C_ADDRESS,LTC2991_Vcc_MSB_REG,i2c_data,1);
    VoltageValue.VoltageMSB[4] = i2c_data[0];
    I2c.i2cRead(I2C_channel,LTC2991_I2C_ADDRESS,LTC2991_Vcc_LSB_REG,i2c_data,1);
    VoltageValue.VoltageLSB[4] = i2c_data[0];
         
    VoltageValue.SourceVoltage = ((uint16_t)VoltageValue.VoltageMSB[8])<<8  | VoltageValue.VoltageLSB[8];
    VoltageValue.SourceVoltage = (VoltageValue.SourceVoltage & 0x3FFF);
    Voltage1  = (float)(VoltageValue.SourceVoltage * LTC2991_VCC_lsb)+2.5;
    Timer.timerDelayMicros(1);
 /******************************************************************************/
    
/******************************************************************************/    
    I2c.i2cRead(I2C_channel,LTC2991_I2C_ADDRESS,LTC2991_V7_MSB_REG,i2c_data,1);
    VoltageValue.VoltageMSB[3] = i2c_data[0];
    I2c.i2cRead(I2C_channel,LTC2991_I2C_ADDRESS,LTC2991_V7_LSB_REG,i2c_data,1);
    VoltageValue.VoltageLSB[3] = i2c_data[0];
       
    VoltageValue.V1_Voltage = ((uint16_t)VoltageValue.VoltageMSB[3])<<8  | VoltageValue.VoltageLSB[3];
    VoltageValue.V1_Voltage = (VoltageValue.V1_Voltage & 0x3FFF);
    PdbCellVoltage.Pack4_CellVoltage  = (float)(VoltageValue.V1_Voltage * Voltage_Divider*LTC2991_SINGLE_ENDED_lsb);
    Timer.timerDelayMicros(1);
/******************************************************************************/
 
/******************************************************************************/    
    I2c.i2cRead(I2C_channel,LTC2991_I2C_ADDRESS,LTC2991_V5_MSB_REG,i2c_data,1);
    VoltageValue.VoltageMSB[2] = i2c_data[0];
    I2c.i2cRead(I2C_channel,LTC2991_I2C_ADDRESS,LTC2991_V5_LSB_REG,i2c_data,1);
    VoltageValue.VoltageLSB[2] = i2c_data[0];
       
    VoltageValue.V2_Voltage = ((uint16_t)VoltageValue.VoltageMSB[2])<<8  | VoltageValue.VoltageLSB[2];
    VoltageValue.V2_Voltage = (VoltageValue.V2_Voltage & 0x3FFF);
    PdbCellVoltage.Pack3_CellVoltage  = (float)(VoltageValue.V2_Voltage * Voltage_Divider*LTC2991_SINGLE_ENDED_lsb);
    Timer.timerDelayMicros(1);
/******************************************************************************/  
    
/******************************************************************************/
    I2c.i2cRead(I2C_channel,LTC2991_I2C_ADDRESS,LTC2991_V3_MSB_REG,i2c_data,1);
    VoltageValue.VoltageMSB[1] = i2c_data[0];
    I2c.i2cRead(I2C_channel,LTC2991_I2C_ADDRESS,LTC2991_V3_LSB_REG,i2c_data,1);
    VoltageValue.VoltageLSB[1] = i2c_data[0];
       
    VoltageValue.V3_Voltage = ((uint16_t)VoltageValue.VoltageMSB[1])<<8  | VoltageValue.VoltageLSB[1];
    VoltageValue.V3_Voltage = (VoltageValue.V3_Voltage & 0x3FFF);
    PdbCellVoltage.Pack2_CellVoltage  = (float)(VoltageValue.V3_Voltage * Voltage_Divider*LTC2991_SINGLE_ENDED_lsb);
    Timer.timerDelayMicros(1);
/******************************************************************************/
    
 /******************************************************************************/
    I2c.i2cRead(I2C_channel,LTC2991_I2C_ADDRESS,LTC2991_V1_MSB_REG,i2c_data,1);
    VoltageValue.VoltageMSB[0] = i2c_data[0];
    I2c.i2cRead(I2C_channel,LTC2991_I2C_ADDRESS,LTC2991_V1_LSB_REG,i2c_data,1);
    VoltageValue.VoltageLSB[0] = i2c_data[0];
       
    VoltageValue.V4_Voltage = ((uint16_t)VoltageValue.VoltageMSB[0])<<8  | VoltageValue.VoltageLSB[0];
    VoltageValue.V4_Voltage = (VoltageValue.V4_Voltage & 0x3FFF);
    PdbCellVoltage.Pack1_CellVoltage  = (float)(VoltageValue.V4_Voltage * Voltage_Divider*LTC2991_SINGLE_ENDED_lsb);
    Timer.timerDelayMicros(1);
 /******************************************************************************/      
}

There is no problem reading the voltages. There are problems reading the currents. 

Any help would be greatly appreciated.

Sincelery,