Reading out HDQ-equipped battery fuel gauges with a serial port

Battery fuel gauges are the unsung hero of the battery world. There’s more to it than just measuring the voltage on the battery terminals,. These little chips are microcontrollers (tiny computers, essentially) that sit inside the battery pack and keep tabs on the battery’s performance for the life of that battery pack.

Texas Instruments makes battery fuel gauges that are small enough to fit in the circuitry of a cell phone, and one of the most common ones that uses this technology are iPhone batteries. These batteries use a single-wire interface called HDQ (which stands for High-Speed Data Queue). It may sound similar to Dallas Semiconductors’ 1-Wire protocol, but the two are completely different and incompatible with each other.

Protocol details

The HDQ protocol can be emulated with a serial port and a little bit of external circuitry. The protocol can be emulated with a serial port at 57600 baud with 8 data bits, no parity bit and 2 stop bits. Because this is a bi-directional bus, an open-drain configuration is needed. Most TTL serial ports are not open-drain, so some circuitry is required to do this. TI’s application note suggests using a CMOS inverter and an N-channel MOSFET along with a 1 kOhm pull-up resistor, but this can be cut down with a 74HC07 open-drain buffer and pull-up resistor.

[EDIT: June 13, 2015 – Corrected schematic]

The HDQ protocol uses a short pulse to indicate a logic 1, with a longer pulse to indicate a logic 0. The data is sent LSB (least significant byte) first, with a 7-bit address and an eighth bit to indicate if the operation is a read or write (0 is read, 1 is write). If it is a read operation, the fuel gauge will respond with one byte of data. As you might think, this is a very slow means of communication; the typical bus speed is 5-7 kilobits per second, but the actual usable throughput will be less than this.

The hack in this is that the bit timing can be made by sending a specially crafted UART byte that meets the timing specifications. Each bit takes up one byte of UART buffer memory, with 24 bytes being enough to perform an HDQ read (the first 8 bytes are echoed back to the PC and need to be ignored by the software). TI’s application note goes into this with a bit more detail.

Windows HDQ utility

HDQ utility icon, in all its pixelated glory.

HDQ utility icon, in all its pixelated glory.

I have written a small Windows program that will read out the battery’s main data, identify as a certain iPhone battery model (most iPhone batteries are supported), and save a copy of this data to a text file for safekeeping. This program requires the National Instruments LabWindows/CVI Runtime library to run, since I whipped this program up with the first available IDE on my college PC.


Screenshot of HDQ Utility version 0.96

The source code is not yet available (translation: I’m too ashamed of my programming skills to share it with others); however, a Windows executable is available for download below.

You will need to download the National Instruments LabWindows/CVI Runtime to run this program.

Current version (0.96):

Version 0.95:
Version 0.9:

Contributions are always accepted! Email me if you would like to send in a battery for me to analyze, or you can buy me a coffee through PayPal:

[EDIT – July 28, 2016] Welp, looks like the PayPal button’s broken (or was it never working to begin with…?). If you’d like to send anything to me, just give me a shout at!

[EDIT – August 2, 2016] Whoops, looks like I never had the button working in the first place. Hopefully it works this time.


78 thoughts on “Reading out HDQ-equipped battery fuel gauges with a serial port

  1. Pingback: Looking inside a (fake) iPhone 5S battery | Rip It Apart – Jason's electronics blog-thingy

  2. This worked great! I had some batteries that were not holding charge as they should, turns out some of them had less than 900 mAh charge capacity left… The only thing is closing and opening the program for each battery, It would be good to have just a button to test each battery and get the calculated state of health to determine good and bad.
    If you don’t mind sharing the source code as is (read ‘I will not judge you’ 😉 ) it will be great, otherwise, kudos for sharing such good info!

    Liked by 1 person

    • Hi Nick,

      I’m delighted to hear the software has worked out for you! I will probably be releasing the source code of this program soon, as I no longer have access to the computer that compiled the program initially. I plan to re-write this program to have a GUI and a press-to-test feature, with an auto-export with individual files for each battery, and so on.

      By the way, is it alright if I contact you further via email, using the address that you’ve submitted when you added your comment on my blog? We can discuss sharing the source code earlier than me releasing it publicly.


      • Hello, my name is Matthias. My wife Gabi and I have a little company in Germany where we develop software on all platforms. Thank you for your very good support in explaining how the HDQ-equipped battery fuel gauges with a serial port work. I could not find anything like this in my language. Is it possible to stay in contact with you for sharing more information? Besides maintaning smartphones, tablets and all kind of computers, we concentrate on the raspberry pi project. We are lucky to have four programmers who all dig in deep stuff like you do, especially in programming on hardware level with C, Assembler and others to create special solutions. You find our little funny portal on and in the inprint you find some english written stuff of what we have done within the last 40 years. – Where are you living at? Since we travel a lot we like to get to know people like you who have special expertise in the IT-World.
        Kind regards from Obernburg am Main, not far from Frankfurt
        Matthias & Gabi
        mrc-online Team


  3. Would be very exciting with code to read HDQ live for Arduino or Raspberry Pi… I’m just afraid it’s way beyond my abilities. If you or anyone else don’t feel up to writing it I wouldn’t mind taking a look at your source code for the HDQ utility though… Just maybe I can wrap my head around the general idea and whip something up. But I do doubt my abilities.

    This also inspired me to hook up an iPhone 5 battery to the IC from an old USB-power bank with defective (0v) cells – works perfectly it seems.
    There is no reason iPhone batteries can’t be charged in parallel as long as they are balanced to nearly the same voltage level first, right? (+- 0.01v) Or would the cells eventually get out of balance and kill each other?
    I think I have around a hundred 4-4s-5-5s batteries now waiting to be repurposed – should I be worried they weren’t good enough for stable iPhone use? (The usual power-off at 20-30% only to turn on claiming 40% five minutes later)


    • The physical HDQ interface can be done with a dedicated UART or even simply by bit-banging the protocol. Shall I send an email to the address you provided when you posted your comment?

      Li-ion batteries should perform fine in parallel as long as the battery voltage is close enough as to prevent once cell from forcefully charging another one; it’s series packs that really need to worry about becoming unbalanced.

      If you’re trying to make a power bank with these cells you should be fine, as the boost converter for a USB power bank is a lot less sensitive than the circuitry that runs the iPhone itself.


      • Completely missed your reply! Thank you! 🙂
        I’d love to take a look at the source – you can just email it to the address given here – I think I might be able to whip something up in C+ that’ll work on an Arduino 🙂 I’m thinking about making a charging/discharging/HDQ->UART circuit 🙂


  4. Hi there, this is great work! I have used a slightly different circuit as detailed in ti’s notes, so the tx and rx are not tied together. Before I did that I could not get it to work.

    I’ve got some additional battery logs from your program for batteries not in your list. It would be great to have them added 🙂 I also have a few minor suggestions if you are interested..

    Feel free to contact me. Thanks!


      • Good catch, and thanks for the feedback! I made the schematic off the top of the head and never realized that I had gotten the Tx pin connected wrong. I’ll update the schematic accordingly.

        Is it alright if I email you with the address that you submitted when you posted your comment?


      • Certainly, that email is fine.

        I have now used your software on an Apple Watch, iPad Mini 1+2 (iphone 5 connector with reversed pinout), iPhone 6, and a few other things, and your software tells me almost everything i could possibly need to know 🙂

        I would love to see some extra device support added, like the ability to determine genuine iPad batteries. I have a heap of output files for you if it helps at all (With batteries in different states, charging, discharging, critically low, ect) 🙂

        Once again great work! And don’t be ashamed of the source code.. No matter how messy it might be, the program works well. that’s all that matters 🙂



        • Thanks! I’ll be sending an email to you in the near future. The output files will be very useful (critical, really) for adding new entries to the list.

          As for determining if a battery is genuine, I’m not sure if it can be done, but if it is possible it would involve reading out the data memory (something I have not written code for yet).


      • Ahh yes i should have worded that better 😛 I meant to match known hardware and firmware versions, as it seems to do at the moment, but for other batteries. Like if a battery is refurbished with the wrong IC, or some unknown firmware.

        Also one more thing I should have mentioned when i made that slight change to the schematic. The tx actually goes to pin 1 (1A) on the 74HC04, and the output is on pin 2 (1Y). So the 2 and 3 should be a 1 and 2 (Technically it could also be 3+4 / 5+6 / 13+12 / 11+10 / 9+8). Maybe it is different depending on the specific package you use? Not sure.

        Its also worth mentioning, Pin 14 connects to VCC, and Pin 7 to GND.

        These are just little details though. No biggy.

        It would be great to see a few extra features too, but I’m unsure how you would implement them.. For example (sorry for the bombardment here):

        +An auto refresh setting/mode for monitoring batteries that are charging/discharging without closing and opening the program. A value could be set for refresh time, i guess you could just have a file called “refresh.txt” with the number or seconds between intervals

        +The ability to save the hdq_data files with different names, OR probably easier, the files build up rather than overwriting (ie hdq_data.txt, hdq_data1.txt, hdq_data2.txt ect, or even timestamped filenames.) I have been using a batch file that prompts for input, then moves/renames the files after the program closes, into a folder called logs.

        +iPad/iPhone wording. For example when you connect an iPad battery, you get told it is not an iPhone battery (same with apple watch, and iphone 6 for some reason) You could reword this to “Battery configuration matches that of a non-iDevice battery (configuration data doesn’t match any known iDevice battery profile).”

        +Not sure if it is possible, but when charging, the “Not discharging” flag appears the same as it would when the battery is not being charged/discharged. You can of course see the current going into the battery, but if there happens to be a flag for charging, that would be cool… Even cooler would be some colored/bold text when the battery reaches 95% or so, telling you to disconnect the charger, and/or the opposite, telling you the battery is low when below 15% or so (it already states when the battery is critically low, but even that would be nice in bold, if its possible..)

        +The same as above but for temperature, again if possible. (ie, BATTERY IS TOO HOT, BATTERY IS TOO COLD)


        No battery was detected, or the battery connected does not contain a recognisable gas gauge ic. Alternatively your computer might not have responded fast enough. Try running this program again, check battery connecton, and/or check circuit. An example circuit can be found here: http://shorturl” (The slower the computer i use is, the more i seem to get this prompt. Running the program again once or twice seems to rectify it, except in the case of my XP Virtualbox, where i had to set a higher CPU execution cap [ubuntu host os])

        Your UART port was detected, but the HDQ interface was not found. Check you are using the correct drivers for your UART/TTL interface, and check the circuit is correct. An example circuit can be found here: http://shorturl

        Have you set the config.txt file to the correct port? Eg, if using COM5, the text file should contain “5” with no quotation marks, spaces, or letters. Otherwise, check you are using the correct drivers for your UART/TTL interface.” (The config file could also be renamed to port.txt, just to make it more obvious)

        Once again, sorry for the bombardment there but i think if you could implement things like this, i think everyone would greatly benefit..

        And lastly, on the output files, on the GUI, and/or on this article, you should have a paypal donate link! I can only imagine the time that went into this work (I’ve invested many hours into similar things, and this saved me from starting from scratch). Even if you don’t consider it a big deal, others surely do, and there is next to no information online about iDevice specific HDQ.

        This could be used by technicians worldwide. Imagine when a customer comes into a repair store with a battery issue. The first thing they can do is test the battery with your HDQ utility, and print a report of its estimated health.

        Then they could replace the battery, printing a new report, knowing that the issue was infact the battery, and not something else entirely like a rogue app using high CPU, ect.

        If the battery is not found to be the issue, they could then go on to use other diagnostic utilities, like ios8+ battery usage menu, or this 3rd party server i made specifically for this purpose I based that off Christopher Lyon Anderson’s article, and modified the python/mitm scripts to be suitable for those who have no idea how python works. That means anyone, anywhere can use it, without installing anything, or having an apple computer running specific versions of software. It took me days to write, and longer to bypass the new ios8 SSL security that broke the script.. So there is a donation button there. Despite that I have never received donations, but hey, i can see myself (and others) using your tool 10x more than i use my own, so maybe you will be luckier 😛

        Anyway I hope the feedback is well received, and I wish you the best of luck. If there’s anything I can do to help, be sure to let me know. Also thanks for the fast responses!



        • Many thanks for the feedback! This software tool was originally a test of using a UART for HDQ but eventually turned into the tool in its current state, hence why many of the features are unpolished (fatal error messages, single HDQ log file, etc…). Don’t worry about the long post – the feedback is definitely important in allowing me to make this utility even more useful, and to allow this to become a “true” tool for technicians. I’ll answer your points as they appear in your comment:

          – The schematic pins weren’t really meant to match up with the pins of the actual IC, but it’s definitely something that could trip up some people; I’ll re-update the schematic accordingly.
          – Auto-refresh was something I had a while back, but was really quite buggy and eventually was removed entirely (it was never available in the version that I made publicly available). One thing that I might add alongside an auto-refresh polling feature is CSV file logging.
          – The utility overwriting a previous hdq_data.txt file is one of the issues that’s bothered me before – I ended up just copy-pasting the files in-place if I wanted to keep a certain log! It’ll certainly be amended so that previous logs will be retained.
          – The device identification section was created when I had no iPad/Apple Watch data at the time, hence why it only mentioned iPhone batteries.
          – The “discharging” and “not discharging” flags are a direct report from the gas gauge’s Flags register, and it has a delay of about 40-60 seconds after the discharge has stopped. As for formatted text, LabWindows/CVI doesn’t support coloured/formatted text in its console (if it did, I’d have used it long ago! 🙂 ), but could have a way of emphasizing battery warnings.
          – The tool does have a warning for over-temperature, but as stated before, my tool is only mirroring the status bits in the fuel gauge and doesn’t interpret the temperature thresholds itself. None of the mainstream HDQ gas gauges have an under-temperature status bit, but they set an XCHG (charge-inhibit) bit if the temperature goes below 0 degrees C, or above 45 degrees C.
          – The error messages were essentially a debugging feature and never really had any troubleshooting information alongside it (once again, this was a “test” program). Of course, this will be amended with some troubleshooting steps.

          Great idea for the donation button. I’m sure many people out there would find a huge amount of value in this tool, especially once I get more user-friendly features in it.


    • I was going to mention CSV logging but I thought that would be much harder lol 😛 a CSV output would be great for those wanting to format/plot the data whichever way they like. I wouldn’t pull hair out over it though 😛 (previous experience pulling hair out with CSV files :P)

      Thanks for providing such a detailed response 🙂 There is definitely a large demand for a tool like this, and considering this was just you testing, you’ve done a fantastic job getting it where it is.

      And you did just remind me of the delay on those flags. Would it be possible to add an autorefresh feature in minutes?, or 5 minute intervals, or similar? Even if the program were to close and reopen that wouldn’t be a big deal.

      Otherwise a timeout at the end could work. Instead of pressing a key, if the program prompted to press a key or wait 30 seconds, for example. Then those wishing to do so could use a batch script to wait for your program to close, count a specified amount of time, then launch it again on a loop.

      As far as LabWindows/CVI and the formatted text (No experience here with LabWindows/CVI), would it be possible to do this with ASCII characters? I do this in batch files often to draw attention to things. I’m not sure how this will look once posted, but something like this


      ## BATTERY IS TOO HOT!!! ##

      Anyway I just got your email, so i’ll put these output files together for you and email them off. I’m just going to populate it to include as much info/batteries as possible first.

      Cheers again!


      • Thanks for the kind words!

        The delay on the flags is only for the discharging/not discharging bit, and all other data from the fuel gauge (not my tool) are updated once a second; the auto-refresh will most likely be done at once with the rest of the fuel gauge data (probably easier to implement as well). I’ll probably use a method of highlighting alerts that is similar to the end-of-program message that my tool currently uses.


    • Yup I noticed the current and everything was by the second, or thereabouts. The only delay i noticed was when discharging (it would say discharging after i had removed the load, but only for a short amount of time)

      Anyway that sounds great! I’ve sent the email off now. Be sure to keep me updated 🙂



  5. Hi Jason

    I have to thank you for a thoroughly enjoyable couple days exploring the an old iPhone 5c battery that I removed from my daughters phone ~ your site was the inspiration I needed to look into things further.

    Unfortunately I’ve had mixed success using your utility.

    I initially managed to get the 0.9 version of the utility to work and it reported the detail from the BQ27545-G1, but only once, all subsequent attempts to run the utility failed with “Error: Could not detect a gas gauge.”

    Unfortunately thinking that I could simply replicate running the utility I did not keep the successful output.

    I inspected the subsequent conversations with a Saleae Logic analyser and noted that all that seemed to be happening was a read of the CONTROL_STATUS register – the result was:
    – high byte: 0110 0000
    – low byte: 0000 1011

    I then downloaded version 0.95 and was pleased to see that the conversation changed and on the first run there was a write of, 1000 0001, to the 0x01 Control() command. Presumably in order to get the DEVICE_TYPE. Unfortunately subsequent reads of the 0x00/0x01 addresses returned the same result as above.

    Following this initial conversation the subsequent conversations have been exactly the same as the 0.9 version.

    I’m not sure what may be causing the unusual output but thought I would let you know how I got on.

    Independently I have been using RealTerm to converse with the BQ27545 and have successfully returned the NomAvailableCapacity(), FullAvailableCapacity() and CycleCount(). I have so far been unable to write to the Control() command to get the various other details returned to the 0x00/0x01 Control Addresses, but will persevere at another time.

    Incidentally I have tried to converse with a brand new cheap battery and it has completely failed to respond – do you know if they need initialising in the phone first?

    Anyway – thank you again, I have thoroughly enjoyed poking around in this battery and learning about the ti Fuel Gauges – I would not have done so if it had not been for your insight.



    • Hi Grant, glad to hear that my blog inspired you to look into battery fuel gauges!

      I’ve been working on yet another version of my HDQ Utility that saves each log to a new file, as well as displaying more diagnostic information if communication errors are detected (it should be ready within a couple days). I’m not sure why your setup is having inconsistent results when running the utility, but it may be good to check that you have solid continuity from the iPhone’s battery connector and your UART adapter.

      Some cheap batteries may omit a fuel gauge altogether; these can be found if no voltage is detected from the HDQ pin to ground (it should be 2-2.5 volts). That said, the battery’s protection circuitry may simply need to be ‘woken up’ by applying 3.5-4.3 volts to the Pack+/Pack- terminals for less than a second, or by attaching the battery to a phone and plugging it in.



  6. Pingback: HDQ Utility version 0.96 now available! | Rip It Apart – Jason's electronics blog-thingy

  7. Jason, this is VERY cool. I’m the developer of an iOS app that reads some of this information from your iPhone/iPad’s installed battery, and so I find this very interesting. One thing I’m curious about is, have you found a way to get the battery’s serial number? It must be in one of those Manufacturer Info blocks.

    Would love to chat with you about a couple of ideas and to let you try out my app, please reach out to me!


  8. hi Jason,
    Great project! I been working on a personal project with ti fuel gauge as battery management control for its battery backup and I would like to incorporate a pc based application so I can monitor the battery in my computer. Would it be ok if you can share the code to use it as my refefence. by the way, I’m planning to use VB or c# for the application and i think CVI is a c based language right? so I must have to translate it . Thank you very much.


  9. Thanks for such a great program! Works without problems. I could finally see the difference between Iphone 4s-batteri and fake-batteri.
    Program running on my win7 Pc. Changed the hardwareinterface. 74HC04 (no-have) replaced with BC549. Use “FTDI FT232RL USB to TTL Serial Cable 5V Converter Adapter f Arduino / CTS RTS” (ebay). Working out of the box.
    Thank you very much.
    Best regards


  10. Hi Jason, I built your interface and I tried to readout 2 iPhone 4 akku packs. I used a USB serial interface (like used for Arduino programming). Unfortunatly I don’t get any data from the akkus. Your software is reporting always somthing like Communication error and cannot read byte from address xxx. The COM port is succesfully opened and the HDQ loopback interface is recognised by the software. Do you have any clue what the issue could be here? Is the USB2Serial Board possibly part of the problem? I tried two different Serial inferfaces both with FTDI chips on. Both have the same problem. No Communication possible.


    • Hi Bernhard,

      Are you connecting the HDQ circuit to the HDQ and Pack- pins on the battery? You should see about 2 volts across the HDQ and Pack- pins. If there is voltage present, try shorting the HDQ and Pack- pins together for about 10 seconds. This will activate the reset circuitry that Apple includes with their iPhone/iPad battery packs.



  11. Hi Jason,

    I built your UART-HDQ interface and tried to read two different iPhone 4 Akkus. I used an USB-RS232 Interface converter with FTDI chip. Unfortunately it doesn’t work. The com port and the HDQ Loopback interface was found, but the read commands fails with reading multiple 0x22 or 0x2222 values. None of the listed values makes any sense.

    Battery Identification
    DEVICE_TYPE = 0x2222, FW_VERSION = 0x2222, DESIGN_CAPACITY = 8738 mAh
    Battery configuration match: none (could not match device type and firmware version due to a communication error).
    Restarting this program should be enough to collect the information required to identify this battery.

    Basic Battery Information
    Device = bq272222 v.22.22, hardware rev. 0x2222, data-flash rev. 0x2222

    Do you have any clue what’s the issue here? Is the timing from the FTDI RS232 converter a potential issue? Both batteries are showing the same garbage …



    • Hi Bernhard,

      The 0x22 values result from how I’ve implemented the HDQ routines in the program. It’s used internally to signal that no response was received on the HDQ bus. The HDQ protocol lacks error checking, and my program has omitted more thorough checks in order to speed up the communication process.

      That said, you shouldn’t be seeing those values. Some sort of communication (or just a glitch) seems to have caused the program to continue operation, as if a valid battery was connected.

      I don’t have any FTDI-based USB-to-serial adapters to test my program on (I am currently using some Prolific PL2032HX-based adapters at the moment). I doubt the chip itself is the issue, as others were successful in getting their adapters to communicate properly. Are you using a generic USB-to-serial board?



        • My program works with batteries before the iPhone SE. The SE doesn’t seem to accept the timings of the HDQ adapter without the break signals occurring before every HDQ transaction, and so far I haven’t been able to get that timing to work properly.

          I damaged my PL2303HX based adaptors and had to try some FTDI UARTs, but they were incredibly glitchy. I have since ordered more Prolific based UART dongles as they have worked almost perfectly for me, but still can’t talk to the iPhone SE battery.



          • Hi Jason, stumbled across your site while investigating the charger on an iphone SE battery… did you ever get your HDQ program to read SE batteries? Mine’s got an bq27546-g1 on it (it’s the original battery from phone). Thanks!


            • I stopped spending money on buying batteries since I found that I kept getting knockoffs that don’t read correctly. If the genuine ones use the bq27546, they should read out and I’d just have to add its IDs to the list.


              • Ok cool! It is the original battery from the phone, so I’ll see what I can read from it. I realize you may be swimming in these things, but if you can use a genuine SE gas gauge I’m happy to send it to you once I’m done.


                • If you can get it to communicate, please send me the data from the program! That said, the gauge can still help me figure out more about the iPhone SE battery, especially since it’s known to be genuine. I live in Canada so shipping might be a bit more, but sending only the PCB/connector assembly without the actual Li-ion cell would make it safer and cheaper.


  12. Pingback: So Phone Me Maybe: A list of iPhone/iPad batteries with gas gauge functionality | Rip It Apart – Jason's electronics blog-thingy

  13. Hi Jason,
    Im trying to work with your program but having trouble.
    With 3GS batteries that are charged and showing 2.5 V on HDQ,
    when I run the program the fuel gauge is not found and the HDQ line
    seems to turn off (0V).
    Got any ideas? Happened to 2 batteries.


    • Hi Kevin,

      Is your adapter pulling the HDQ line low? iPhone batteries have a circuit external to the gas gauge that will remove power from the gauge if the HDQ line is pulled low for more than a few seconds.



      • That was likely part of the problem. I am trying to interface directly to the RX/TX lines of a PC USB-RS232 adapter. These are +-6V nominal idle at -6V, so I removed the ’04 inverter and drive the FET with TX. Drain w/1K to HDQ and RX. VCC is direct from 3.7V battery under test.

        (I cant figure how to insert a snippet schematic copy here).
        Anyway, with logic analyzer I see (from idle at 1), a break of 1.125ms followed be 4 bytes separated by ~3ms, 11ms delay, 2 bytes back-2-back (host/gauge?), 300ms delay, 2 bytes back-2-back.
        Am I on the right track? Unfortunately, the Saleae logic tool has no HDQ analyzer.

        Also, the TI-HDQ appnote you reference is for the bq2019, a real old gauge with (I think) a different command protocol that the 3GS bq27541. (But I am a newby here.)
        What are the actual command/response seq you are sending to initiate a connection to the battery?



        • It sounds like you’re driving the HDQ interface through an RS-232 driver rather than direct CMOS/TTL. The appnote is only referenced for the bit timing of the interface but the protocol used is quite different.

          The detection simply sees whether it sees any response from the gauge (but given your next comment it doesn’t seem to be working the way it should). What USB-RS232 adapter chip are you using (FTDI, Prolific, etc.)?



  14. Jason,
    Sometimes, based on the logic analyzer, after the break, I see a READ 0x01/response 0x05, READ 0x00/response 0x41. That is the device code for the dq27541. But there is no more communication.


    • Hi Jason,
      Let’s see if I can post some drawings on my WEB as I cant figure
      how to insert them here.
      Directory contains png images of schematic, your pgm output,
      3 byte exchanges, Saleae Logic file. (You can read the Logic file
      version 1.2.5. Chan-0 is HDQ line, Chan-1 is RS232 TX from GearHead USB-RS232 adapter diode clamped to ground.



      • Thanks for the screenshots and the Saleae logic trace. It looks like your UART chip or the driver is truncating the data in the buffer. The HDQ Utility code won’t consider a data byte valid unless it sees 16 bytes in the buffer (8 looped back from the host sending the address, and 8 coming from the gauge).

        Do you have a USB-to-serial adapter that does not have an RS-232 +/-5V driver on its output?


        • Thanks for getting back. No, currently just bipolar rs232 stuff. I need to get a translator chip.
          I airline think something fishy cause many host bytes that look good get no response from battery.


          • Getting a USB to CMOS-level UART adapter should be pretty easy. Look for one that uses a Prolific brand chip – it’s the only one that’s worked flawlessly for me. FTDI chips have given me a lot of grief testing my software for compatibility.


  15. Hi Jason,
    I ended up taking a different approach. My original intent was to use an iPhone 3gs battery in an embedded application. I started out planning to use a TP4056 charger module and use the embedded processor for battery management. But then I found your blog on accessing the TI chip.
    The embedded application uses the Microchip UNIO 1-wire protocol. That is way more complicated that the TI HDQ protocol. So I am prototyping the HDQ battery channel on a PICDemo board with a PIC16F887. That board also has a MAX3232 PC UART interface to the PIC.
    I wrote a C app on the PIC that runs HDQ 1-wire protocol to the battery and echos the HDQ protocol on a spare pin in Manchester protocol. With that, I can trace the HDQ pin with a logic analyzer (with no available protocol analyzer). I can then trace the Manchester code for which there is a good Protocol analyzer! Makes debugging a walk in the park. It is a simple matter to echo the HDQ register address and data info out the RS232 port to a terminal for now.

    I can now read and write all the standard registers on the 3GS battery. I have not tried to unseal a battery yet. Im not sure it is possible.

    I have not looked at other batteries yet due to the tinyier[sic] contacts.

    Once I have something more complete, I think I will dump it on my web.


    R/W HDQ protocol on a PIC is way more simple than kludging the HDQ directly with RS232!
    THe trade off is having the PIC PCB in between!


    • Hi Kevin,

      Glad to hear you’re able to get a solution working – very cool idea mirroring the data back as Machester for debugging!

      For most uses, you won’t need to unseal the battery. It only becomes necessary if you need to access the gauge’s Data Flash memory, and that’s another matter in itself.



  16. any chance you can post the source code, here or in a github repo, etc.
    I would like to take a stab at making a python version of this which can run on windows, mac, linux, etc, and doesn’t have the dependency on the beastly NI runtime..


    • Hi Jens,

      I don’t normally put my source code for public download, but I can email you a development test version of my program that has all the fundamentals for interfacing over HDQ.



      • Ok no worries. I would rather it be open source.
        FYI, I started a pure python implementation proof of concept.

        It’s functional, but I’d love it if it did more intuitive output like your program.
        I’d also like to make it a python module for others to use. (I looked around but couldn’t find anything like that on github or anywhere else.)

        Pull requests and enhancements are welcome!


  17. also, I found, at least for me, with a common, simple usb-uart adapter like CP2102, you can just use a diode (like 1N4148) from txd to rxd line (so that txd can pull down hdq/rxd when it goes active low), and connect rxd to hdq line. I guess if you wanted, you can put some 1k resistors on both rxd/txd for added safety. The speed of the protocol is slow enough that I don’t think you need any faster components (fets/cmos buffers, etc).


  18. Pingback: All about iPhone Batteries, and why you don't want 0 cycle | A One Mobiles and Repairs

      • Hi I was merely checking if you were receiving messages. I’m looking for a bit of help reading and resetting the registers on an old sony aibo robot battery. I’ve recelled the battery but the intregral pcb is holding off it powering the robot. There are afew people out there with the knowledge but its pretty costly to have them work on the batteries, i’m thinking if you can help i may be able to develop a solution. Just reading the battery and then what the charging unit is asking of the battery initially would be a step forward. Do you think you’d be able to help me please, even if its just some baby steps?


  19. Really appreciate that, lets start by asking what harware tools one would need to read the battery state parameters, I have various bits of kit like a UART CP2102 USB dongle for instance. I’ve used this for flashing firmware to sony psp console before. I’m assuming then if i can get a schematic of how to connect this to the battery, which simply has a positive and negative terminal an one for the HDQ using your program I could extract information?


    • It would depend on whether the battery is actually using HDQ as its communication interface or not. Looking at a tool on GitHub ( suggests that the battery communicates over SMBus/I2C. HDQ Utility only works with single-cell gauges over HDQ and not multi-cell SMBus gauges as both the interface and command set are completely different.

      What model of Aibo and battery are you trying to repair?


      • Many thanks, thats actually a chance find for aibo 210 and upwards and will be useful in the future.
        For now, i’m doing an Aibo ERS111 battery model – ERA110B. I did read that the protocol changed from HDQ for the ERS110/111 to SMBus for the latter batteries you found and linked to from Github i.e. ERS 210 etc. What was also interesting is the use of Arduino, I have one of those too if thats a better option?


        • I would recommend the Arduino route if you’re dealing with an SMBus battery. I found a piece of Arduino code for reading an Aibo battery over HDQ ( but my software provides much more information than that code on GitHub (although my code doesn’t know what the specifics of each Aibo battery model are). The GitHub code is simple enough to follow if you really want to match values for the device type and firmware version from my software; it looks like they’re doing comparisons in decimal rather than hex which does make some of the values a bit counterintuitive to parse at first.

          If you get some good data captures from my software of the batteries you’re testing, I’d love to check those out if you’re willing to share.


  20. Hi Jason i finally got round to getting myself a little usb uart interface and have run your program with it. The good news is my PC sees it and intialises it ok. It then errors with “HDQ loopback adapter not detected” i suspect because i do not have a battery connected. I’m a little nervous connecting it to a rare aibo battery but can you give me some further instructions on how please? My uart adpater has usual rx tx 5v 3.3v Gnd but also has dcd, dsr, rts rst etc etc. So my question then is the battery of course has +ve -ve and hdq pin, but from your schematic does it need the 74ch*, mosfet and resistor or are they all build in the 74ch IC and i merely need to connect the pins correctly please?


    • The external circuitry is required for the HDQ interface to work correctly; the external circuitry essentially loops the UART Tx and Rx lines together while preventing the Tx pin from causing bus contention while the computer isn’t sending data. HDQ Utility expects to see 8 bytes (8 HDQ bits) in its receive buffer even if it doesn’t receive a response from a fuel gauge. If it doesn’t, the “HDQ loopback adapter not detected” error occurs. You could use other methods to make the Tx pin open-drain/open-collector, like using a 74HC07 with a pull-up resistor to 3.3V,or with a Schottky diode with the cathode on Tx and the anode on Rx and connecting the HDQ line to Rx. The error message would normally be “no response from device” if the battery is fully discharged or otherwise disconnected.


      • Many thanks for responding I did just this i think for another purpose for Sony PSP flashing using a 1N4148 diode RX to TX and a 10k resistor 3.3v to RX. I just tried that one and behold we go a stage further in that I now get error “no response from device” – Cannot read byte from 0x01 or 0x00. So it looks like i’m making tiny steps forward here. Regarding the battery then I would be connecting just two wires the UART ground pin to Batt -ve and the RX to the HDQ. I’m not going to backfeed the battery chip from the 3.3v uart adapter and damage it am I? I read somewhere that HDQ is sub 2 volts? Sorry if these are very basic and frustrating questions but i am learning here?


        • Yes, the ground goes to the battery’s negative pin and HDQ to Rx. This shouldn’t damage the fuel gauge if the battery is dead, but you will need to charge the battery at least slightly for the gauge to be able to communicate.


          • Thanks I connected it and it would not read, I wonder if i can past the software text so you can see it, i’ll just send part of the logfile thus rror: Could not detect a gas gauge (no response from device). Ensure that the battery fuel gauge and loopback adapter are securely connected.
            (Developer test information: gg_command(DEVICE_TYPE) returned 0x2222.)
            Its returning something. The uart is flashing that its got comms and is running software btw no voltage on meter HDQ to GND. Any ideas?


            • The UART lights will blink regardless of whether a gauge is accessible or not; 0x2222 is an internal code that returns if a communication error occurs and doesn’t indicate that the gauge is present. If the HDQ pin on the battery is 0V when the adapter is not connected, it is likely that the battery needs to be charged first.


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.