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.

INA233: INA233 I2C COMMUNICATION

Part Number: INA233
Other Parts Discussed in Thread: ISO1541, , INA226

I m developing an application where i need to read ina233 bus voltage , current etc with an isolator  ISO1541 in between   MCU and INA233. So i2c communication happens between mcu----1SO1541----INA233.

For testing purpose i  am trying to read the MFID (Manufacturer id from reg address 0x88) . But I am not able to read the complete 2 byte data, I just receive the (2,255) from the IC.i.e second byte read is always high.

Sharing the code with functions :

data = read_ina(0x88);               // for reading the data from the reg address 0x88.

unsigned char read_ina(unsigned char address)
{

unsigned int temp=0,temp2=0;
unsigned char add_lo = 0,add_hi = 0;

unsigned char reg_address = 0;
reg_address = address;

start1(); delay_us(300);
  write_byte_ina233(0x88);                                     //delay_us(300);          //slave address + write bit
  write_byte_address_ina233(reg_address);          //delay_us(300);          // register address
stop1(); delay_us(300);

start1(); delay_us(300);
write_byte_ina233(0x89); trisb.f3 = 1;delay_us(300);                                //slave address + read bit
ina_data_lsb = read_byte_ina233_ack();                     //delay_us(300);
ina_data_msb = read_byte_ina233_nack();                 //delay_us(300);

stop1(); delay_us(300);

return(ina_data_msb);
}

Other functions are as follows :

void start1(void)
{
trisb.f3 = 0;delay_us(300);

sda_iso1541 = 1 ; delay_us(300);
scl_iso1541 = 1; delay_us(300);

sda_iso1541 = 0 ; delay_us(300);
scl_iso1541 = 0; delay_us(300);
}


void stop1(void)
{
trisb.f3 = 0;delay_us(300);

sda_iso1541 = 0 ; delay_us(300);
scl_iso1541 = 1; delay_us(300);

sda_iso1541 = 1 ; delay_us(300);

}


void write_byte_ina233(unsigned char val)
{
unsigned char x=0;
trisb.f3 = 0;delay_us(500);

for(x=0;x<=7;x++)
{
if(val & 0x80)
{sda_iso1541 =1;}
else
{sda_iso1541 =0;}

delay_us(500);

scl_iso1541 =1;
delay_us(500);
scl_iso1541 =0;
delay_us(500);
val = val << 1;
}

trisb.f3 = 1;delay_us(500);

scl_iso1541 =1;
delay_us(500);
scl_iso1541 =0;
delay_us(500);

//trisb.f3 = 1;delay_us(300);
}


void write_byte_address_ina233(unsigned char val)
{
unsigned char x=0;
trisb.f3 = 0;delay_us(500);


for(x=0;x<=7;x++)
{
if(val & 0x80)
{sda_iso1541 =1;}
else
{sda_iso1541 =0;}

delay_us(500);

scl_iso1541 =1;
delay_us(500);
scl_iso1541 =0;
delay_us(500);
val = val << 1;
}

trisb.f3 = 1;delay_us(500);

scl_iso1541 =1;
delay_us(500);
scl_iso1541 =0;
delay_us(500);

//trisb.f3 = 1;delay_us(300);

}

unsigned char read_byte_ina233_ack(void)
{
unsigned char x=0,val=0;
//trisb.f3 = 1;
delay_us(300);

for(x=0;x<=7;x++)
{
val = val << 1 ;
delay_us(500);
val = val | sda_iso1541;
delay_us(500);

scl_iso1541 =1;
delay_us(500);
scl_iso1541 =0;
delay_us(500);
}

delay_us(500);

scl_iso1541 =1;
delay_us(500);
scl_iso1541 =0;
delay_us(500);

return(val);
}

unsigned char read_byte_ina233_nack(void)
{
unsigned char x=0,val=0;
//trisb.f3 = 1;
//delay_us(300);

for(x=0;x<=7;x++)
{
val = val << 1 ;
delay_us(500);
val = val | sda_iso1541;
delay_us(500);

scl_iso1541 = 1;
delay_us(500);
scl_iso1541 = 0;
delay_us(500);
}

//trisb.f3 =0;delay_us(100);
return(val);
}

Kindly let me know for some issue with the code .

Or please send me sample code for reading some register value.

  • Hi friends , Solved the matter , it was with i2c communication , Was not pulling down sda line from the master .Now i am able to word read, word write , block read .....
    So my next question is :
    I am able to read 2 registers of the address (0x88) i.e READ_VIN .But how do i use these 2 data bytes to calculate real world voltage .?
    PLease help......
  • Hi,

    Glad you got it working.

    To calculate BUS voltage, please use equation (3) in the data sheet and set m=8; b=0; R=2; Y=the decimal value of the register value from Vin.

    Detailed instructions can be found in section 7.5.4

    Regards, Guang

  • Hi Im using an application note as follows to read telecom -48v and current. But i am using INA233 instead of INA226.

    Following is the diagram for the same :

    Well I am able to read bus voltage at V bus with accuracy of 0.1V .However there is some linearity issue. I am applying following formula to read real world voltage .

    volts_ina = ina_data_msb;
    volts_ina <<= 8;
    volts_ina = volts_ina | ina_data_lsb;
    voltage_var = volts_ina * 0.00125;      //Vbus

    The Vbus voltage after the voltage divider resistor(R2,R1) is matching with the read result.(voltage_var).   only 0.1 V variation in it.

    But when i try to get the reading of the VIN-(GND_INA) There comes a difference of 3V in reading  on applying -59 V supply.( Applying -59 Volts gives approx 20V at the Vbus which is safe region 0 - 36 V ).

    How do i scale Vbus to read Vin-(GNd_ina).

    Is there something to do with the part number i am using.....The reference part was INA226 , i used INA233 . 

    I am reading 0x88 register which reads V bus voltage which is coming fine.BUt How do i convert to real world Vin- voltage , It is not coming linear(-59.23 V  Vin- is reading as 56.122 on applying multiplication factor of 2.78625 on Vbus voltage which is 20.144V)i.e  Vbus * mult factor = Vin- as read from mcu.

     

  • Hi Jitender,

    The INA233 should be just as fine in your application.

    How did you obtain the scaling factor? Did you measure or simply calculate it based on nominal resistor values?. What you can do is to fit a straight line between smallest and largest Vin’s, calculate the gain, or scaling factor. This is essentially a calibration, which should provide much accurate readings.

    Regards, Guang