Remote access to a Tekpower TP9605BT DMM


I was measuring amps and volts in a circuit with a Rigol DM3066 DMM and Siglent SDP3303S power supply when I fat-fingered the Rigol and blew it’s 10 amp high current shunt fuse. Strange but true, this fuse is inside the Rigol under a factory warranty seal. I fretted about this and was convinced I had a choice of giving away the remaining two years of warranty by replacing the fuse myself or sending it to Rigol. In the middle of this I really wanted to continue logging measurements and so I thought I’d get a cheap meter that was accurate enough as a stop gap. I spent about 1/20th as long as I should have researching a meter and settled on the Tekpower TP9605BT because it offered logging via bluetooth in addition to USB.

But the truth is the actual utility of bluetooth logging was a fuzzy, pie in the sky nice feature for the future. It had no relevance at all to what I was doing. In retrospect I was an idiot to become non-selective by virtue of the lure of a cool feature.

The meter came from Amazon very quickly and I couldn’t get the cool bluetooth feature to work at all. An email to Tekpower support brought an nearly instant response from two different people there and Tekpower followed up with two additional emails to make sure I had a fix and ask for more details etc. I give the US support at Tekpower high marks for wanting to satisfy customers. The updated Android App I was pointed to worked immediately and the logging by bluetooth, automatic creation of .csv files and ability to share these via email, etc. The app does crash part of the time, but when it works it is in fact very cool.

But that’s not what I’m writing about. I’m writing about being able to log measurements from this device using USB. The good news is that the optically coupled USB dongle that came with this meter works perfectly for me. It creates a /dev/ttyUSBn device that can be cat’d and within minutes one can get measurements that are usable in a sense. I say “in a sense” because what the meter puts out is a mish-mash of binary and ASCII with a funky expression of values as a four digit magnitude and single digit sale factor. But I was OK with that and could hack something that would capture current measurements so my show could go on.

I just imagined the meter would spit out a plain ASCII string of a number followed by a letter or five indicating the measurement unit or some exception state like overrange, battery low, etc.

But the real format is like this for the typical case:

+/- MMMM SM <four bytes> <carriage return><line feed>

Where MMMM is four ASCII digits, S is a scale factor define as “one plus the number of places to move the decimal to the right”) , M is a mystery ASCII digit that I still haven’t figured out, and the four bytes are binary containing a bit set here and there to indicate what mode the meter is in as well as conditions such as low battery.

Speaking of batteries. This meter eats batteries. I mean with sharp teeth. It draws 48-50 milliamperes ordinarily but drops to 25 when a bluetooth connection is established. When the continuity beeper beeps it draws an additional 30 milliamperes, but of course this is infrequent. But the amazing thing is that the ten minute default auto-shutoff blanks the display and stops data logging *but does not disconnect from the power source*.  You read this right. I’m not kidding. So it continues to draw 48 milliamperes. I went through two batteries before realizing what was happening and switching to running the meter off a power supply. (Note that this is unsafe: connecting the battery terminals to an external supply compromises safety when measuring high voltages. Don’t do this if you’re going to deal with high voltages!)

Also, the auto-shutoff was not disabled with the documented method of holding the “select” button down while turning the meter on. After many experiments I determined that holding the button on the other side of the meter (“range”) did disable auto-shutoff. Until I determined this I couldn’t use the meter for logging for more than 10 minutes unless I pushed a button on the meter to keep it active. Blech.

After finding no trace of anybody else having done anything with this meter I decided to make some Python code for it. (No, it is not at all like a TP4000, having a radically different message format that happens to also be 14 bytes long. I actually started to modify some TP4000 code before realizing it was different in every way and not agreeing with the message interpretation strategy, etc).

My approach was to write a simple standalone utility to output the logging data like the ‘cat’ Unix/Linux command simply outputs what’s fed to it. So I called it tp9605cat. I studied Python style guides, command line argument processing, and otherwise boosted my experience with this language quite a bit as a side effect.  But the key thing I did was solve the basic problem of how to tell the difference between one complete message from the meter vs a random string of bytes that was the end of one message and the beginning of the other.

I used a ring buffer and “next read stores here” index and interpreted the message relative to that index, performing more and more tests on the 14 bytes of the buffer to answer the question, “is this a complete, valid message”. It obviously needed to end in carriage return and line feed, but that left 11 versions of not quite complete messages and whatever you get with “noise”. (I’ve seen no evidence of random corruption of the datastream coming from the meter, so this is theoretical) By presetting the buffer to impossible byte values (I chose ‘?’) I could not be fooled by a glitch of some sort resulting in stale data being mistaken for new data, and after a few iterations I ended up with eight tests of message bytes that had to be true to convince the code that the current ring buffer contents were synchronized with the data stream and held a valid measurement message.

This left determining what the binary bytes meant and I’ve done a partial job by capturing the raw stream while switching meter modes and then deciding which bit indicates volts, which one millivolts, which one temperature in degrees C, etc. Again, this is currently incomplete which is why my software is in what I would call a “pre-alpha” state. It might be interesting to play with, but it would be frustrating to mistake it for feature complete code.

But after getting the ‘cat’ utility the way I wanted it I then wrote a simple API to allow an arbitrary program to get meter readings and then retrofitted use of the API back into tp9605cat. The API is called

This code is in pre-alpha state. It’s not feature complete and not fully tested. But it’s a start and can be found on GitHub here.