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.

BQ35100: current measurement over i2c is reporting only 0mA

Part Number: BQ35100

Hello,

i have written my own little driver so a mcu can communicate with the battery manager. However i can read temperature and voltage just fine but current always reports 0mA. Why is that?

here is the code i am using:

the read two bytes code:

/*
 * reads two bytes from a register
 */
BAT_STATUS BAT_Read_Two_Bytes(BAT_StateHandle *hbat, uint8_t register_address,
		uint16_t *pBytes) {

	//we use the buffer to send the register we want to read
	//the same buffer will be used later to store the answer
	uint8_t buff[2] = { register_address, 0x00 };

	//send which register we want to read
	if (HAL_I2C_Master_Transmit(&hi2c2, hbat->address_i2c, &buff[0], 1,
	BAT_TIMEOUT_LIMIT) != HAL_OK) {
		return BAT_ERROR;
	}
	//now read it
//	if (HAL_I2C_Master_Receive(&hi2c2, hbat->address_i2c, buff, 2,
//	BAT_TIMEOUT_LIMIT) != HAL_OK) {
	HAL_Delay(BAT_DELAY); //wait  for the device to write the answer
	if (HAL_I2C_Master_Receive(&hi2c2, hbat->address_i2c, buff, 2, BAT_TIMEOUT)
			!= HAL_OK) {
		return BAT_ERROR;
	}
	HAL_Delay(BAT_DELAY);
	//fill in the result
	if (pBytes) {	//return ERROR if not there
		*pBytes = (((uint16_t) buff[1]) << 8) + buff[0];
		APP_LOG(TS_ON, VLEVEL_L, "reading two bytes buffer is [%d, %d]\n", buff[0], buff[1]);
	} else {
		return BAT_ERROR;
	}

	return BAT_OK;
}

here is the functions to read temperature, voltage and current:

/*
 * the current flow in mA
 */
BAT_STATUS BAT_Get_Current(BAT_StateHandle *hbat, uint16_t *current) {
	BAT_STATUS status;
	status =  BAT_Read_Two_Bytes(hbat, 0x0c, current);
	APP_LOG(TS_ON, VLEVEL_L, "reading current %d \r\n", *current);
	return status;
}


/*
 * returns the voltage in mV
 */
BAT_STATUS BAT_Get_Voltage(BAT_StateHandle *hbat, uint16_t *voltage) {
	return BAT_Read_Two_Bytes(hbat, BAT_REG_Voltage, voltage);
}

BAT_STATUS BAT_Get_Temperature(BAT_StateHandle *hbat, float *temperature) {
	*temperature = -273.15f; //default is 0 Kelvin
	uint16_t pBytes;
	//read the register
	BAT_STATUS status = BAT_Read_Two_Bytes(hbat, BAT_REG_Temperature, &pBytes);
	if (status == BAT_OK) {
		//interpret the value in pBytes as temperature
		*temperature = (float) pBytes;
		*temperature = (*temperature - 2731.5f) / 10.0f; //into Celcius
	}
	return status;
}

temperature and voltage work fine. current only returns 0. why is that? they seem to be doing pretty much the same.

  • i made a typo in the current function. this is the one i am using:

    /*
     * the current flow in mA
     */
    BAT_STATUS BAT_Get_Current(BAT_StateHandle *hbat, uint16_t *current) {
    	BAT_STATUS status;
    	status =  BAT_Read_Two_Bytes(hbat, BAT_REG_Current, current);
    	APP_LOG(TS_ON, VLEVEL_L, "reading current %d \r\n", *current);
    	return status;
    }

    However i checked with a logic analyzer and the gauge is returning two bytes with 0x00 and 0x00. meaning that it is actually reporting the current to be 0mA. My test setup is drawing 10mA which i have verified with a multimeter. Here is part of the logic analyzer output:

    write to 0x55 ack data: 0x00 
    read to 0x55 ack data: 0x80 0x40
    
    write to 0x55 ack data: 0x08 
    read to 0x55 ack data: 0x9D 0x0D
    
    write to 0x55 ack data: 0x0C 
    read to 0x55 ack data: 0x00 0x00
    
    write to 0x55 ack data: 0x28 
    read to 0x55 ack data: 0xAF 0x0B

    I am running in ACC UNSEALED mode. GAUGE start stop did not change anything i tried both.

  • Hello,

    That does seem strange. Can you confirm that the sense resistor is in the current path and maybe try a larger test current? The only other thing I can think to check right now is the 0x0C with your logic analyzer to see if that is getting sent properly. 

    We cannot debug the code itself but we can help with the behavior. If you can confirm the voltage is across the sense resistor, and that the command was correctly sent, we can rule out a lot of possibilities.

    Thanks,

    Alex M.

  • I retried using a 100ohm resistor. I did measure the same battery voltage at the ends of the resistor. The measured mA with a multimeter is 34mA the bq35100 is reporting 0mA. The resistor is connected as shown in [www.ti.com/.../sluubh7.pdf page 5. There are 3 pins, Bat+ Bat- and Pack-. The resistor is connected between Bat+ and Pack-.

    15:12:26.764 -> 421s479:reading two bytes buffer is [0x80, 0x40]
    15:12:26.764 -> 421s479:sec mode UNSEALED


    15:12:26.998 -> 421s698:reading two bytes buffer is [0x29, 0xD]
    15:12:26.998 -> 421s698:voltage: 3369 mV


    15:12:27.139 -> 421s817:reading two bytes buffer is [0x0, 0x0]
    15:12:27.139 -> 421s817:reading current 0
    15:12:27.139 -> 421s817:current: 0


    15:12:27.233 -> 421s936:reading two bytes buffer is [0xA6, 0xB]
    15:12:27.233 -> 421s936:temperature: 25 C

    The output of the logic analyzer was already attached to the first post. it is sending 0x0c but reports back 0x00.

    EDIT:

    after moving the code around for a bit i noticed something weird:

    i can only measure current AFTER i start and stopped the gauge. is this intended?

  • Hello,

    Sorry I didn't notice that those were from a logic analyzer. Anyways, I think the data appearing after gauge_stop may explain the problem. I think you may be polling the device too quickly. When Gauge stop is issued, the gauge finishes whatever tasks it was doing. I would suggest adding a 1s or more delay between sending gauge start and sending the commands to read the values. Try that and let me know if it helps.

    Thanks,

    Alex M.

  • The 1s didn't change anything since i had a 1sec delay after the gauge_start already:

    	/////////////////// GAUGE START ///////////////////
    		status = BAT_Gauge_Start(&hbat1);
    		if (status != BAT_OK) {
    			APP_LOG(TS_ON, VLEVEL_L, "[BAT] error start gauge\r\n");
    		}
    		HAL_Delay(1000); //let it measure for 1 sec

    However i can measure current flow after a gauge_stop. Maybe this is intended?

  • Hello,

    I tested on an EVM to verify the behavior; here is what is expected in ACC mode:

    • Measurements are enabled when Gauge_start is sent
    • There are no current/temperature/voltage measurements while the gauge is in Gauge_stop/Gdone. However, it will continue to report the last value in the register. Since voltage/temp don't change fast, it can appear that it is still measuring those even if it is not.

    So you should be able to read the current in gauge_start. Please make sure your gauge is in ACC mode and try polling current even more/adding more delay, because you should be able to see it. When you hit gauge_stop, it will keep reporting the last current value it saw, which is why I think some delay may be the issue. 

    To confirm if this is the situation, you could try removing the load after gauge_stop is sent and see if the gauge updates its reading to reflect that or if it keeps reporting the load current.

    But I was able to read the current on my board after sending gauge_start, so please double-check everything with the setup. If it still doesn't work, can you share the value you used for the sense resistor?

    Thanks,

    Alex M.