bq4050 reading fail on smbus

Hello,

I tried to read the value from bq4050 on smbus.

I had good results but I got wrong value randomly as following.

The last marked value is temperature from DAStatus2Reg(0x72). it works well but randomly it works malfunction.  

How can I solve this problem? please help me.

<info> app: bms(3:58:9) : 11164 12400 2678
<info> app: bms(3:58:10) : 11165 12400 2678
<info> app: bms(3:58:11) : 11165 12400 -275
<info> app: bms(3:58:12) : 11164 12400 -275
<info> app: bms(3:58:13) : 11165 12400 -275
<info> app: bms(3:58:14) : 11165 12400 -275
<info> app: bms(3:58:15) : 11164 12400 -275
<info> app: bms(3:58:16) : 11164 12400 2678
<info> app: bms(3:58:17) : 11164 12400 2678
<info> app: bms(3:58:18) : 11165 12400 -275
<info> app: bms(3:58:19) : 11165 12400 -275
<info> app: bms(3:58:20) : 11165 12400 -275
<info> app: bms(3:58:21) : 11165 12400 2678
<info> app: bms(3:58:22) : 11164 12400 2678
<info> app: bms(3:58:23) : 11164 12400 2678
<info> app: bms(3:58:24) : 11165 12400 2678
<info> app: bms(3:58:25) : 11165 12400 2678
<info> app: bms(3:58:26) : 11165 12400 2678

Here is read function as following.

void read_BQ4050_data(uint8_t regAddress, uint8_t size)
{
  ret_code_t err_code;
  uint8_t reg[1] = {regAddress};
  uint8_t buf[2] = {0};

  err_code = nrf_drv_twi_tx(&m_twi, BQ4050_WHO_AM_I, reg, sizeof(reg), false);
  APP_ERROR_CHECK(err_code);
  
  twi_done();


  switch(size)
  {
    case 1:
      err_code = nrf_drv_twi_rx(&m_twi, BQ4050_WHO_AM_I, m_buf8, size);
      break;
    
    case 2:
      err_code = nrf_drv_twi_rx(&m_twi, BQ4050_WHO_AM_I, (uint8_t *)m_buf16, size);
      break;

    case 4:
      err_code = nrf_drv_twi_rx(&m_twi, BQ4050_WHO_AM_I, m_buf, size);
      break;

    default:
      err_code = nrf_drv_twi_rx(&m_twi, BQ4050_WHO_AM_I, m_buf, size);
      break;

  }
  
  APP_ERROR_CHECK(err_code);

  twi_done();

  switch(regAddress)
  {
    case StateOfChargeReg:
      m_bms_measurement1->realSOC = (uint8_t)m_buf8[0];
      break;

    case CellVoltageOne:
      m_bms_measurement1->cellV[0] = m_buf16[0]; 
      //err_check_read(&m_bms_measurement1->cellV[0], &pre_cV1, 1);
      break;

    case CellVoltageTwo:
      m_bms_measurement1->cellV[1] = m_buf16[0]; 
      //err_check_read(&m_bms_measurement1->cellV[1], &pre_cV2, 1);
      break;

    case CellVoltageThree:
      m_bms_measurement1->cellV[2] = m_buf16[0]; 
      //err_check_read(&m_bms_measurement1->cellV[2], &pre_cV3, 1);
      break;

    case CellVoltageFour:
      m_bms_measurement1->cellV[3] = m_buf16[0]; 
      //err_check_read(&m_bms_measurement1->cellV[3], &pre_cV4, 1);
      NRF_LOG_INFO("cell V : %d  %d  %d  %d ", m_bms_measurement1->cellV[0], m_bms_measurement1->cellV[1], m_bms_measurement1->cellV[2], m_bms_measurement1->cellV[3]);
      break;

    case CurrentReg:
      m_bms_measurement1->packCurrent = m_buf16[0]; 
      //m_bms_measurement1->packCurrent = 21000;
      //err_check_read(&m_bms_measurement1->cellV[2], &pre_cV3, 1);
      //NRF_LOG_INFO("Pack C : %d", m_bms_measurement1->packCurrent);
      break;

    case VoltageReg:
      m_bms_measurement1->packVoltage = m_buf16[0]; 
      err_check_read(&m_bms_measurement1->packVoltage, &pre_pV, 1);
      //NRF_LOG_INFO("Pack V : %d", m_bms_measurement1->packVoltage);
      break;

    case OperationStatusReg:
      m_status_bq4050->OperationStatus = byte2short(m_buf[1], m_buf[2]); 
      break;

    case ManufacturingStatusReg:
      m_status_bq4050->ManufacturingStatus = byte2short(m_buf[1], m_buf[2]);; 
      break;

    case DAStatus2Reg:
      m_bms_measurement2->temperature[0] = byte2short(m_buf[3], m_buf[4])-KTEMP_PARAM;
      m_bms_measurement2->temperature[1] = byte2short(m_buf[5], m_buf[6])-KTEMP_PARAM;
      m_bms_measurement2->temperature[2] = byte2short(m_buf[7], m_buf[8])-KTEMP_PARAM; 
      m_bms_measurement2->temperature[3] = byte2short(m_buf[9], m_buf[10])-KTEMP_PARAM;
      NRF_LOG_INFO("Pack Temp : %d", m_bms_measurement2->temperature[0]);
      break;
  }
}

Parents
  • Can you try to initialize the various variables (e.g. addresses and arrays) with the 'static' keyword? 

    If the problem still exists I suggest that you add a logic analyzer to measure the twi interface, and set a breakpoint when you experience the wrong value so you may stop the trace and see if you can find anything wrong with the serial data or internal variables (e.g. is the sensor writing the wrong data or not).

Reply
  • Can you try to initialize the various variables (e.g. addresses and arrays) with the 'static' keyword? 

    If the problem still exists I suggest that you add a logic analyzer to measure the twi interface, and set a breakpoint when you experience the wrong value so you may stop the trace and see if you can find anything wrong with the serial data or internal variables (e.g. is the sensor writing the wrong data or not).

Children
No Data
Related