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.

LAUNCHXL2-570LC43: Unsure of procedure to connect with an INA219 Current Sensor through I2C.

Part Number: LAUNCHXL2-570LC43
Other Parts Discussed in Thread: INA219, , HALCOGEN

Tool/software:

Hello,

I am unable to find documentation online detailing a way to read the register values on an INA219 through I2C communication with my LAUNCHXL2-570LC43. I have the INA's VCC and GND connected to the microprocessor's 3.3V source and ground. The SCL is connected to the 3CS3 pin while the SDA is connected to the 3CS2 pin on my LAUNCHXL (booster pack 1, column J2, pins 8 and 9) as the board schematic detailed that I2C connection could be established with those pins (ref: https://www.ti.com/lit/df/sprr397/sprr397.pdf?ts=1748924725068 Booster pack site 1, page 7). For the time being I haven't set up a circuit to be analyzed just yet as I just want to understand if I can read the registers. This is the part where I get confused though: I wanted to know if there is a guide specifically for this device as I cannot seem to adapt the HALCoGen TMS570LC43x example_i2cCommunication.c example to what I need. Could someone give me an idea on how I can structure my code to perform this communication protocol between the two devices to simply read the value on a register like the Bus Voltage register as an example?

  • Hi Stefano,

    Actually, I2C from master end designed in such way that can be connected to any of the I2C slave device. So, it is difficult to find documentation for all the slave devices. However, in slave datasheet only they should mention the procedure and protocol related to that corresponding device.

    This is new I2C slave device for me, however i can help you with it by understanding the device.

    Did you connect any pull-up registers over SCL and SDA lines?

    I2C will not work without external pull-up resistors.

    Make sure to connect external pull-up resistors on SDA and SCL lines. The pullup should neither be too high and nor be too small, preferably in between 2.2K to 4.7K. 

    Even you cannot use internal pull-up resistors as well, because the internal pullups are too weak to be used for I2C. They're just strong enough to keep the pins from floating.  You have to provide external pull-up to I2C signals.

    So please connect pullup resistors in between i2c lines and 3.3v supply in the board.

    For more details you can refer below thread, here also customer initially tried without pullup's and found the communication is not working, and finally he connected external pullup resistors with 2.2K then he found that communication is working.

    For more details refer these threads:

    (18) TMS570LS3137: Temperature Sensor(tmp101na/3k) - Arm-based microcontrollers forum - Arm-based microcontrollers - TI E2E support forums

    (18) TMS570LS1224: Problem of not being able to send value with i2cSend() in I2C - Arm-based microcontrollers forum - Arm-based microcontrollers - TI E2E support forums

    (18) TMS570LS3137: I2C is not working - Arm-based microcontrollers forum - Arm-based microcontrollers - TI E2E support forums

    --
    Thanks & regards,
    Jagadish.

  • Hi Jagadish,

    My INA219 has internal pull-up resistors attached to the board of about 10KΩ. I'm guessing that is too high and would prevent any I2C communication right?

    Thank you very much for your help!

  • You are correct.

    The pullup should neither be too high and nor be too small, preferably in between 2.2K to 4.7K. 

  • Thank you for letting me know, I am currently using this code to test out if communication works with the INA219. I notice that the voltage on the SCL line drops from 3.3V to 0V when debugging, signaling that communication is happening, but I cannot seem to get past the i2cReceive(...); function since it gets stuck on the "while ((i2c->STR & (uint32)I2C_RX_INT) == 0U) {}" function. Could you provide me with some insights as to why it would be getting stuck there?

    #include "HL_sys_common.h"
    #include "HL_i2c.h"
    #include "HL_sys_core.h"
    #include <stdio.h>
    
    #define INA219_ADDR        0x40
    #define INA219_REG_BUSVOLT 0x02
    
    int main(void)
    {
        uint8 tx_data = INA219_REG_BUSVOLT;
        uint8 rx_data[2];
    
        i2cInit();
    
        /** Write register address to INA219 **/
        i2cSetSlaveAdd(i2cREG1, INA219_ADDR);
        i2cSetDirection(i2cREG1, I2C_TRANSMITTER);
        i2cSetCount(i2cREG1, 1);
        i2cSetMode(i2cREG1, I2C_MASTER);
        i2cSetStart(i2cREG1);
        i2cSend(i2cREG1, 1, &tx_data);  
        i2cSetStop(i2cREG1);
    
        /** Read 2 bytes from bus voltage register **/
        i2cSetDirection(i2cREG1, I2C_RECEIVER);
        i2cSetCount(i2cREG1, 2);
        i2cSetMode(i2cREG1, I2C_MASTER);
        i2cSetStart(i2cREG1);
        i2cReceive(i2cREG1, 2, rx_data);
        i2cSetStop(i2cREG1);
    
        uint16 raw = ((uint16)rx_data[0] << 8) | rx_data[1];
    
        // Convert to actual voltage
        float voltage = (raw >> 3) * 0.004;  // 4 mV per bit
    
        printf("%d", voltage);
    }

  • Hi Stefano,

    I verified your code and also the datasheet of the INA219.

    1. First i want to make sure this, as you are using slave address as 0x40 that means you should connect A1 and A0 address lines to the ground. I hope you did this in your hardware.

    2. Now i made some changes to your code, try with this modified code once and update the status to me:

    #include "HL_sys_common.h"
    #include "HL_i2c.h"
    #include "HL_sys_core.h"
    #include <stdio.h>
    
    #define INA219_ADDR        0x40
    #define INA219_REG_BUSVOLT 0x02
    
    int main(void)
    {
        uint8 tx_data = INA219_REG_BUSVOLT;
        uint8 rx_data[2];
    
        i2cInit();
    
        /** Write register address to INA219 **/
        i2cSetSlaveAdd(i2cREG1, INA219_ADDR);
        i2cSetDirection(i2cREG1, I2C_TRANSMITTER);
        i2cSetCount(i2cREG1, 1);
        i2cSetMode(i2cREG1, I2C_MASTER);  
        i2cSetStop(i2cREG1);
        i2cSetStart(i2cREG1);
        i2cSend(i2cREG1, 1, &tx_data);
    	
    	/* Wait until Bus Busy is cleared */
        while(i2cIsBusBusy(i2cREG1) == true);
    
        /* Wait until Stop is detected */
        while(i2cIsStopDetected(i2cREG1) == 0);
    	
    	/* Clear the Stop condition */
        i2cClearSCD(i2cREG1);
    
        /** Read 2 bytes from bus voltage register **/
        i2cSetDirection(i2cREG1, I2C_RECEIVER);
        i2cSetCount(i2cREG1, 2);
        i2cSetMode(i2cREG1, I2C_MASTER);
        i2cSetStop(i2cREG1);
        i2cSetStart(i2cREG1);
        i2cReceive(i2cREG1, 2, rx_data);
    
        uint16 raw = ((uint16)rx_data[0] << 8) | rx_data[1];
    
        // Convert to actual voltage
        float voltage = (raw >> 3) * 0.004;  // 4 mV per bit
    
        printf("%d", voltage);
    }

    --
    Thanks & regards,
    Jagadish.

  • Thank you for all your assistance. I was able to get the code to work I just realized I wasn't giving the program enough of a delay between sending the bus voltage register and the reading of the incoming data. I tried doing it with the while loops that you provided but I would constantly get stuck and not progress at all. With a __delay_cycles(n) function though I was able to make it work. I used n = 70000 so there was a delay of 7ms but anything similar should work.