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.

BQ40Z50-R1: Reading unexpected Temperature value

Part Number: BQ40Z50-R1
Other Parts Discussed in Thread: BQSTUDIO

Hi Team,

I am using Smart battery in my product. While I am reading the battery temperature(0x08U) value using stm32 via smbus communication. Some time  its get unexpected value.

(ex) I am getting 32 degree continuously suddenly i got one spike in 260 degree within 30 to 60 min.

I don't know why i  am getting like this..

Please advise how to solve this issue.

thanks,

  • Hi

        What is the interval for temperature reading? once a second maybe appropriate, but an extreme dense reading operation may cause trouble

  • Hi steven Yao,

    Thanks for quick replay.

    What is the interval for temperature reading?

    The reading is read one second intervals and also reading the BV,CC,RSOC,ASOC parameters.

    thanks,

  • Hi,

        The temperature is read once every 250ms, but gauge has other tasks to handle, reading once every second should be fine.

        Have you tried with bqStudio to read the temperature? Do you see same issue with bqStudio? Can you provide a log file from bqStudio

        If you still see such issue with bqStudio, then can you please check the waveform on the TS pin see if the waveform change when the temperature reading is 260 degree?

  • Hi,

    Thanks for your response.

    Have you tried with bqStudio to read the temperature? Do you see same issue with bqStudio?

    Yes, we read the data and didn't find any unexpected value.

    Herewith attached the Communication function file for your reference.
    Hopefully it will be helpful..
    bool smbusCommunication::SmbusDataLose(SMBUS_HandleTypeDef *smbus) {
    
    	bool isCommunicate{true};
    	const uint8_t delay10ms{10U};
    
    	while ((HAL_SMBUS_GetState(smbus) != HAL_SMBUS_STATE_READY) &&
    			isCommunicate) {
    		if ((HAL_SMBUS_GetError(smbus)) != HAL_SMBUS_ERROR_NONE) {
    			isCommunicate = false;
    		} else {
    		}
    		HAL_Delay(delay10ms);
    	};
    
    	if (HAL_SMBUS_GetState(smbus) == HAL_SMBUS_STATE_MASTER_BUSY_TX) {
    		__HAL_SMBUS_CLEAR_FLAG(smbus, SMBUS_FLAG_STOPF);
    		SMBUS_RESET_CR2(smbus);
    		smbus->PreviousState = HAL_SMBUS_STATE_READY;
    		smbus->State = HAL_SMBUS_STATE_READY;
    	}
    
    	if (HAL_SMBUS_GetState(smbus) == HAL_SMBUS_STATE_MASTER_BUSY_RX) {
    		__HAL_SMBUS_CLEAR_FLAG(smbus, SMBUS_FLAG_STOPF);
    		SMBUS_RESET_CR2(smbus);
    		smbus->PreviousState = HAL_SMBUS_STATE_READY;
    		smbus->State = HAL_SMBUS_STATE_READY;
    	}
    
    	return isCommunicate;
    }
    
    
    bool smbusCommunication::TranmitData(const uint8_t memLocation,
    		const uint8_t devAddress, uint32_t value,
    		bool isWrite) {
    
    
    	bool isCommunicate{true};
    	std::array<uint8_t, 10> buffertx{0U};
    
    	std::array<uint8_t, 10> tmpvalue{0U};
    	tmpvalue.at(CHG_BUFF_INDEX_THREE) = static_cast<uint8_t>(value);
    	tmpvalue.at(CHG_BUFF_INDEX_TWO) = static_cast<uint8_t>(value >>= 8);
    
    	buffertx.at(CHG_BUFF_INDEX_ZERO) = memLocation;
    	buffertx.at(CHG_BUFF_INDEX_ONE) = tmpvalue.at(CHG_BUFF_INDEX_THREE);
    	buffertx.at(CHG_BUFF_INDEX_TWO) = tmpvalue.at(CHG_BUFF_INDEX_TWO);
    
    	if (!isWrite) {
    		ret = HAL_SMBUS_Master_Transmit_IT(
    				(&hsmbus2), static_cast<uint16_t>(devAddress), &buffertx[0], CHG_BUFF_INDEX_ONE,
    				SMBUS_FIRST_AND_LAST_FRAME_NO_PEC);
    	} else {
    		ret = HAL_SMBUS_Master_Transmit_IT(
    				(&hsmbus2), static_cast<uint16_t>(devAddress), &buffertx[0], CHG_BUFF_INDEX_THREE,
    				SMBUS_FIRST_AND_LAST_FRAME_NO_PEC);
    	}
    
    	isCommunicate = SmbusDataLose(&hsmbus2);
    
    	std::fill(buffertx.begin(), buffertx.end(), RESET_VALUE);
    	return !isCommunicate;
    }
    
    bool smbusCommunication::ReceiveData(const uint8_t devAddress,
    		std::array<uint8_t, 10> &rxData) {
    
    	bool isCommunicate{true};
    	std::fill(rxData.begin(), rxData.end(), RESET_VALUE);
    	ret = HAL_SMBUS_Master_Receive_IT(&hsmbus2, static_cast<uint16_t>(devAddress),
    			&rxData[0], CHG_BUFF_INDEX_TEN,
    			SMBUS_FIRST_AND_LAST_FRAME_WITH_PEC);
    
    	isCommunicate = SmbusDataLose(&hsmbus2);
    	return !isCommunicate;
    }
    
    bool smbusCommunication::DataLoseRetry(const uint8_t memLocation,
    		const uint8_t devAddress,
    		std::array<uint8_t, 10> &rxData) {
    	std::fill(rxData.begin(), rxData.end(), RESET_VALUE);
    
    	bool dataTxRX{false};
    	dataTxRX = TranmitData(memLocation, devAddress);
    	if (!dataTxRX) {
    		dataTxRX = ReceiveData(devAddress, rxData);
    	}
    	return dataTxRX;
    }
    
    bool smbusCommunication::SmbusRead(const uint8_t memLocation,
    		const uint8_t devAddress, uint32_t &data,
    		bool &isCRCmatch) {
    
    	CRCCAL<uint8_t> crc8(static_cast<uint8_t>(0x07), false, false);
    	bool isCommunicate{true};
    	uint8_t calpec{0U};
    	std::array<uint8_t, 10> bufferrx{0U};
    	uint8_t count{0U};
    	data = RESET_VALUE;
    	isCRCmatch = false;
    
    	bool dataTxRX{false};
    	dataTxRX = TranmitData(memLocation, devAddress);
    
    	while ((count <= SMBUS_FAULT_VERIFY_COUNT) && dataTxRX){
    		count++;
    		dataTxRX = TranmitData(memLocation, devAddress);
    	}
    
    	if (count >= SMBUS_FAULT_VERIFY_COUNT) {
    		isCommunicate = false;
    		return isCommunicate;
    	}
    	count = RESET_VALUE;
    
    	dataTxRX = ReceiveData(devAddress, bufferrx);
    
    	while ((count <= SMBUS_FAULT_VERIFY_COUNT) && dataTxRX){
    		count++;
    		dataTxRX = DataLoseRetry(memLocation, devAddress, bufferrx);
    	}
    
    	if (count >= SMBUS_FAULT_VERIFY_COUNT) {
    		isCommunicate = false;
    		return isCommunicate;
    	}
    
    	if ((memLocation == AT_RATE_ADDR) || (memLocation == CURRENT_ADDR) || (memLocation == AVERAGE_CURRENT_ADDR)) {
    		int16_t tmp = ((int16_t)bufferrx[CHG_BUFF_INDEX_ONE] << 8U) | bufferrx[CHG_BUFF_INDEX_ZERO];
    		data = abs(tmp);
    	} else {
    		data = ((uint16_t)bufferrx[CHG_BUFF_INDEX_ONE] << 8U) | bufferrx[CHG_BUFF_INDEX_ZERO];
    	}
    
    	uint8_t crcData[CHG_BUFF_INDEX_FOUR]{0U};
    	crcData[CHG_BUFF_INDEX_TWO] = bufferrx[CHG_BUFF_INDEX_ONE];
    	crcData[CHG_BUFF_INDEX_ONE] = bufferrx[CHG_BUFF_INDEX_ZERO];
    	crcData[CHG_BUFF_INDEX_ZERO] = devAddress;
    
    	calpec = crc8.CalcCrc(&crcData[CHG_BUFF_INDEX_ZERO], &crcData[CHG_BUFF_INDEX_THREE], 0x00);
    	if (calpec == bufferrx[CHG_BUFF_INDEX_TWO]) {
    		isCRCmatch = true;
    	} else {
    		isCRCmatch = false;
    	}
    	return isCommunicate;
    }
    
    
  • Hi, Vel

        Are the erroneous temperature reading occurs at a regular time interval? like 30min or 60min?

        Please also check if there would be any other device on the same SMBUS in your system which could possibly cause bus conflict.

        Also if you have [BCAST] bit set in SBS configuration register, please get this bit cleared to disable the broadcast function disabled

  • Hi, Vel

        Some questions about your code below:

    bool smbusCommunication::TranmitData(const uint8_t memLocation,
      const uint8_t devAddress, uint32_t value,
      bool isWrite) {


     bool isCommunicate{true};
     std::array<uint8_t, 10> buffertx{0U};

     std::array<uint8_t, 10> tmpvalue{0U};
     tmpvalue.at(CHG_BUFF_INDEX_THREE) = static_cast<uint8_t>(value);
     tmpvalue.at(CHG_BUFF_INDEX_TWO) = static_cast<uint8_t>(value >>= 8);

     buffertx.at(CHG_BUFF_INDEX_ZERO) = memLocation;
     buffertx.at(CHG_BUFF_INDEX_ONE) = tmpvalue.at(CHG_BUFF_INDEX_THREE);
     buffertx.at(CHG_BUFF_INDEX_TWO) = tmpvalue.at(CHG_BUFF_INDEX_TWO);

     if (!isWrite) {
      ret = HAL_SMBUS_Master_Transmit_IT(
        (&hsmbus2), static_cast<uint16_t>(devAddress), &buffertx[0], CHG_BUFF_INDEX_ONE,
        SMBUS_FIRST_AND_LAST_FRAME_NO_PEC);
     } else {
      ret = HAL_SMBUS_Master_Transmit_IT(
        (&hsmbus2), static_cast<uint16_t>(devAddress), &buffertx[0], CHG_BUFF_INDEX_THREE,
        SMBUS_FIRST_AND_LAST_FRAME_NO_PEC);
     }

     isCommunicate = SmbusDataLose(&hsmbus2);

     std::fill(buffertx.begin(), buffertx.end(), RESET_VALUE);
     return !isCommunicate;
    }

    1: the input parameter value is a 32 bit integer, however, per the code below, looks like only 16bit are used, why not define it as a 16bit integer?

    2: What is the purpose of the array of tmpvalue? why do not pass the value in directly to the array buffertx?

    3: What is the purpose of below code at the end of this function?

     std::fill(buffertx.begin(), buffertx.end(), RESET_VALUE);?

  • Hi Steven Yao,

        Are the erroneous temperature reading occurs at a regular time interval? like 30min or 60min?

        Yes, I'm getting the erroneous temperature reading continuously in 30 to 60 min. But some time its getting after 60 min.

       Also if you have [BCAST] bit set in SBS configuration register, please get this bit cleared to disable the broadcast function disabled.

       BCAST Bit was enabled in the SBS configuration. but i am disabling the BCAST bit using software in BatteryMode(0x03) register.

        Please also check if there would be any other device on the same SMBUS in your system which could possibly cause bus conflict.

       Host, Master and slave connected in same smbus communication otherthan no device is connected.

    Thanks,

  • Hi Steven Yao,

    The input parameter value is a 32 bit integer, however, per the code below, looks like only 16bit are used, why not define it as a 16bit integer?

    will be change.

    What is the purpose of the array of tmpvalue? why do not pass the value in directly to the array buffertx?

    Will be update the pass value directly in the array.

    What is the purpose of below code at the end of this function?

    That buffer is reset the updated value.


    Thanks for point that. I will  change and check it soon.

  • Hi, Pieter

        The questions above are just for better understanding to the code.

        I still suspect the issue is caused by bus conflicting, seems that there are master, host devices on the bus, please can you try to remove these devices and make sure the IC is working in slave mode and check if the erroneous reading would still occur?