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.

BQ34Z100-G1: Reliable Arduino HDQ Code

Part Number: BQ34Z100-G1

I am building a test fixture that uses an Arduino Nano to communicate with a bz34Z100-g1.  I have had varying success with sample HDQ libraries I have found on the web.  I seem to have had the most success with the HDQ.cpp by Matthieu Lalonde (website no longer works), however, I get some strange behavior, such as I never get an even StateOfCharge() (ok, maybe not "never", but only once every 500 seconds).

Does anybody have any Arduino HDQ code they have been successful at using?  I've compared the timings in the routine to the datasheet and everything seems to jive.  I've tried adjusting the timings in case there was some margin issue, but I cannot seem to tune it such that it always gives me the data I am expecting.  Most values I get seem to be reasonable, but a few nagging ones don't seem to work (like the StateOfCharge(); voltage is always even; when I read the serial number out with block commands, it is always off by 1, but if I read with the 0x28/0x29 command, it is usually right (sometimes it is off by 1).  Sometimes I read the PackConfiguration() and get 0x970, sometimes 0x971.  Clearly there is something off about the timing.

Here is essentially the code that I am using.  I don't seem to have any issue with the writes or the breaks, so I am omitting that code (although it is freely available at https://github.com/mozzwald/HDQLib

#define HDQ_DELAY_THW1 45 // 32 - 66uS
#define HDQ_DELAY_THW0 120 // 70 - 145uS

#define HDQ_DELAY_TDW1 48 // 0.5 - 50us
#define HDQ_DELAY_TDW0 110 // 86 - 145uS
#define HDQ_DELAY_TCYCD 205 // 190 min

#define HDQ_DELAY_TB 250 /* Min: 190uS */
#define HDQ_DELAY_TBR 70 /* Min: 40uS */
#define HDQ_DELAY_TCYCH 250 /* Min: 190uS Max: 250uS*/

#define HDQ_DELAY_TRSPS_MAX 320 /* Max: 320uS */
#define HDQ_DELAY_BIT_TOTAL 200

#define HDQ_STATE_OF_CHARGE     0x02

#define _HDQ_readPin() (*inputReg & bitmask)>>pin // Change me to inline!*/

uint8_t HDQ::read(uint8_t reg)
{
  uint8_t result = 0; 
  uint8_t maxTries = HDQ_DELAY_FAIL_TRIES; // ~128uS at 8Mhz with 8 instructions per loop 
  // Singal a break
  HDQ::doBreak();
  
  // Write the register to read
  HDQ::writeByte((reg |= HDQ_ADDR_MASK_READ));
  
  for (uint8_t ii = 0; ii < 8; ii++)
  {
    // Wait for the slave to toggle a low, or fail
    maxTries = HDQ_DELAY_FAIL_TRIES;
  while (_HDQ_readPin() != 0 && maxTries-- > 0)
    {
      if (maxTries == 1) return 0xFF;
    }
  
    // Wait until Tdsub and half or one bit has passed
  delayMicroseconds(((HDQ_DELAY_TDW0 - HDQ_DELAY_TDW1) / 2) + HDQ_DELAY_TDW1);
    // Read the bit
    result |= _HDQ_readPin()<<ii;
  
    // Wait until Tssub has passed
  delayMicroseconds(HDQ_DELAY_TCYCD - HDQ_DELAY_TDW0);
  }
  
  delayMicroseconds(HDQ_DELAY_TB);
  
  return result;
}
and the call to get the StateOfCharge() is:

currentPercent = HDQ.read(HDQ_STATE_OF_CHARGE);