This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

INA228-Q1: Current reading error

Part Number: INA228-Q1
Other Parts Discussed in Thread: INA228, , INA226

Using a maximum current of 10 A, with a Shunt of 0.005 Ω we cannot achieve the correct current measurement. Even though the shunt voltage reading is right on spot.

If we calculate CURRLSBCALC as 13107.2 x 10^7 x CURRENT_LSB x RSHUNT and then multiply the content of register 7h (shifted right by 4 bits) by the CURRENT_LSB and then by 10 we get the right current value.

Are you sure the datasheet values are correct? Or is the error on our software side?

  • Hello,

    There are currently errors in some of the equations for the Q1 preview datasheets that will be updated soon.  For now, please use the equations from the released commercial datasheet (INA228), and see if that fixes the problem.

  • Hello,

    I can't find that much of a difference although I noticed some inconsistency in the following:

    On (2) you say 10^6 then below it says 10e6 which one is the correct one? This error is on both data sheets.

  • I marked it as resolved by accident...

  • Oh, I see what you are saying now. Sorry, I didn't catch that before. 13107.2 x 10^6 is the correct value to use. I'll let the systems team know to clarify this in the next update.

  • But this doesn’t still get the current value right.

    The only way to get it right is by doing what I said in the first post:

    If we calculate CURRLSBCALC / SHUNT_CAL as 13107.2 x 10^7 x CURRENT_LSB x RSHUNT and then multiply the content of register 7h (shifted right by 4 bits) by the CURRENT_LSB and then by 10 we get the right current value.

    This  is using ADC range 0.

  • Hello,

    Can you give me exact register readouts for the incorrect situation?  Use 10^6 in your in your SSHUNT_CAL equation. Specifically, I'd like to see the readouts from SHUNT_CAL, VSHUNT, and the CURRENT registers.  I will also need to know what you chose for your CURRENT_LSB, in case you rounded it.

  • Hi Mitch,

    Please find below the requested info.

    SHUNT_CAL RAW Value: 1250
    VSHUNT RAW Value: 13680
    Shunt voltage: 0.00027
    CURRENT RAW Value: -21472
    Shunt Current: -0.02560

    I'm using a VBUS voltage of 24V and a Load resistor of 470Ω so the shunt voltage reading is fine. The current reading is negative, I have no ideia why...

    The schematic is below, keep in mind that we are using the INA-48V part of the schematic, the shunt is 5mΩ and the INA we are using is a INA228-Q1 and not the INA226 as written on the schematic.

    The code I'm using to read the registers is the following:

    #define INA228_REG_CONFIG			(0x00)
    #define INA228_REG_ADCCONFIG		(0x01)
    #define INA228_REG_SHUNTCAL         (0x02)
    #define INA228_REG_TEMPCOCONFIG     (0x03)
    #define INA228_REG_VSHUT	        (0X04)
    #define INA228_REG_VBUS             (0x05)
    #define INA228_REG_DIETEMP          (0x06)
    #define INA228_REG_CURRENT			(0x07)
    #define INA228_REG_POWER            (0x08)
    #define INA228_REG_ENERGY           (0x09)
    #define INA228_REG_CHARGE           (0x0A)
    #define INA228_REG_DIAGALRT         (0x0B)
    #define INA228_REG_SOVL             (0x0C)
    #define INA228_REG_SUVL             (0x0D)
    #define INA228_REG_BOVL             (0x0E)
    #define INA228_REG_BUVL             (0x0F)
    #define INA228_REG_TEMPLIMIT        (0x10)
    #define INA228_REG_PWRLIMIT         (0x11)
    #define INA228_REG_MANUFACTURERID   (0x3E)
    #define INA228_REG_DEVICEID         (0x3F)
    
    int32_t INA228::readRegister24(uint8_t reg)
    {
        int32_t value = 0;
    
        Wire.beginTransmission(inaAddress);
        Wire.write(reg);
        Wire.endTransmission();
    
        Wire.requestFrom(inaAddress, 3);
        uint8_t vha = Wire.read();
        uint8_t vma = Wire.read();
        uint8_t vla = Wire.read();
        value = (uint32_t)vha << 16 | (vma << 8) | vla;
    
        return value;
    }
    
    int16_t INA228::readRegister16(uint8_t reg)
    {
        int16_t value;
    
        Wire.beginTransmission(inaAddress);
        Wire.write(reg);
        Wire.endTransmission();
    
        Wire.requestFrom(inaAddress, 2);
        uint8_t vha = Wire.read();
        uint8_t vla = Wire.read();
        value = vha << 8 | vla;
    
        return value;
    }
    
    void INA228::writeRegister16(uint8_t reg, uint16_t val)
    {
        uint8_t vla;
        vla = (uint8_t)val;
        val >>= 8;
    
        Wire.beginTransmission(inaAddress);
        Wire.write(reg);
        Wire.write((uint8_t)val);
        Wire.write(vla);
        Wire.endTransmission();
    }
    
    bool INA228::calibrate(float rShuntValue, float iMaxCurrentExpected)
    {
        uint16_t calibrationValue;
        rShunt = rShuntValue;
    
        float iMaxPossible;
    
        iMaxPossible = vShuntMax / rShunt;
    
        currentLSB = iMaxCurrentExpected / pow(2,19);
    
        powerLSB = currentLSB * 3.2;
        energyLSB = currentLSB * 51.2;
        chargeLSB = currentLSB;
    
        calibrationValue = (uint16_t)(13107.2 * pow(10,6) * currentLSB * rShunt);
    
        writeRegister16(INA228_REG_SHUNTCAL, calibrationValue);
    
        return true;
    }
    
    float INA228::readShuntCurrent(void)
    {
        int32_t current_raw;
        // current_raw = readRegister24(INA228_REG_CURRENT) >> 4;
    
        current_raw = readRegister24(INA228_REG_CURRENT);
        Serial.println((String)"CURRENT RAW Value: " + current_raw);
        current_raw = current_raw >> 4;
        Serial.print("Shunt Current: ");
        Serial.println( current_raw * currentLSB, 5 );    
    
        return ( current_raw * currentLSB);
    }
    
    float INA228::readShuntVoltage(void)
    {
        int32_t voltage_raw;
    
        // voltage_raw = readRegister24(INA228_REG_VSHUT) >> 4;
        
        voltage_raw = readRegister24(INA228_REG_VSHUT);
        
        Serial.println((String)"SHUNT_CAL RAW Value: " + readRegister16(INA228_REG_SHUNTCAL));
        Serial.println((String)"VSHUNT RAW Value: " + voltage_raw);
        voltage_raw = voltage_raw >> 4;
        Serial.print("Shunt voltage: ");
        Serial.println( voltage_raw * 0.0000003125, 5 );
        
        return ((float)voltage_raw  * 0.0000003125); //If ADCRANGE = 0
    }
    

  • Hello,

    The value you got back for the raw current register is not a valid current code, as that will always end in 0b0000.  So maybe there is an issue with the I2C transmission or code?  Could you get a logic analyzer/scope shot of the I2C transmission for a read command to the current register so that we can confirm the value on the I2C bus itself?

  • Hello,

    The number is correct. The raw number that comes from the INA is in two complement if you convert -21472 to two complement you will get: 11111010110000100000b which is 0xFAC20.

    The number printed that way because of the way the Arduino handles the prints.

  • Oh, sorry, I mistyped it on my end. I'll rerun the numbers again.

  • Hello,

    To make sure that the current and vshunt register readouts are from the same conversion, could you please take the data again, but this time in single-sot mode. It may also be good to use a longer conversion time, and possibly some averages (just to make sure the read out is more accurate).

  • I'm not with the board again until next week but I'm sure they are, this is the same I was getting before. And in this scenario the load is a fixed resistor only so it is no changing. Given that being from the same conversion or not doesn't really changes anything.

  • Ok, I see what you are saying.  I just tried to repeat the issue on an EVM, but I do get the expected current value.  Do you have an EVM that could be used to run the same test?  This way we can see if the issue still happens under your same conditions, but with a different device/firmware.

  • Unfortunately I do not have an EVM. I would be happy to test it if you guys send us one.

    Nonetheless I posted my code, there is not much more to it than what I posted...

  • Yes, I looked over your code and did not notice any problems.  This is why I think it would be good to try different hardware/device as well.  I have sent you a friend request so that we can send private messages to discuss EVM options. 

  • Ok, I have already sent you a message.

  • Ok, thank you, I will reply to this thread once there is more info that relates to the original question.  

  • Also, can you share what the device ID register says, ie, is it 0x2280 or 0x2281? Is the device you are using the preview device (ie, PINA228-Q1), or from the full commercial release (INA228).  

  • I don't have physical access to the device at the moment but I bough the parts from TI Store and they are the Preview Device as per the invoice and the label on the chip package. I think that at the time (20th of January) there was not yet the full comercial version available.

  •  ok, Just let me know the device ID once you get back to the physical setup.  Also, I think your value came out negative because it looks like it's being treated as a 16 bit value by the print statement, so it would be good to look as a scope shot just to confirm the value on the bus.

  • Hi Mitch,

    Just had the opportunity to check the Device ID register. It is reporting back as 0x2281. By the way, I think the datasheet for the comercial version has a typo on 7.6.1.20 since according to the table in that point the id is 0x2281 and in the point title it says [reset = 0x2080]

    Best regards,

    Sebastião

  • Sebastião,

    Thanks for catching that. I'll point out to the datasheet team that the number is not consistent. Not sure if they want it to be 1 or 0, since it is a revision ID, and both numbers can exist. (Though at the moment, most will say 1).

    As for the current reading problem, since I was able to get the expected current value with a simulated setup on the EVM, this would not be a consistent device problem. So, I think there are 2 paths to test:

    1. If the problem is with your hardware/software, then it would be best to try using the EVM with your same current sensing setup to see if you get correct values from it.

    2. If the device was somehow damaged and is causing the problem, then it would be good to swap out the INA228 with another device and see if you get the same problem.

    In general, it also wouldn't hurt to put a scope on the I2C communication lines and make sure that the Arduino is reporting the same value that shows on the I2C bus.

    Please perform the above tests and let me know how it goes. (I'll mark this post at "TI thinks resolved" in case this fixes your problem, but I would still be curious to find out the results once you know them).

  • uint8_t vha = Wire.read(); uint8_t vma = Wire.read(); uint8_t vla = Wire.read(); value = (uint32_t)vha << 16 | (vma << 8) | vla;

    So after playing around with the EVM I discover that the problem was on the Arduino side. This cast of aha was the problem. Defining vha, vma and vla as uint32_t solved the problem.