Reading a Dymo USB scale using Python

For an experimental project I’m working on, I wanted to read the weight from a  DYMO M10 digital postal scale with USB support. I expected the scale to show up as a virtual COM port, since older digital scales used RS232 for their computer interface,but the scale shows up as a USB HID (Human Interface Device) in Windows.

I found Micah Carrick’s site which shows how to read from a MagTek credit card reader in Linux using PyUSB 1.0. Like the DYMO M10, the MagTek reader uses the USB HID device class so the basic method for getting data from the device is the same.

The first step is to install PyUSB 1.0. Unzip the contents of the archive from the PyUSB sourceforge page and run python install.

Using PyUSB on Windows requires installing a suitable backend such as libusb-win32. After installing libusb-win32, it’s necessary to install a device filter for the scale. Connect the USB scale to the computer and press the power button. Windows should detect the scale and install the device driver automatically. The DYMO M10 shows up in Device Manager as a “USB Input Device” with vendor ID 0922 and product ID 8003.

Using the libusb-win32 Filter Wizard, install a device filter for the scale. It will show up in the list as “vid:0922 pid:8003 rev:0100 USB Input Device”.

Now it’s possible to read data from the scale using the usb module in Python:

import usb.core
import usb.util

VENDOR_ID = 0x0922
PRODUCT_ID = 0x8003

# find the USB device
device = usb.core.find(idVendor=VENDOR_ID,

# use the first/default configuration
# first endpoint
endpoint = device[0][(0,0)][0]

# read a data packet
attempts = 10
data = None
while data is None and attempts > 0:
        data =,
    except usb.core.USBError as e:
        data = None
        if e.args == ('Operation timed out',):
            attempts -= 1

print data

The data packet is a 6-element array; for example:

array('B', [3, 2, 11, 255, 0, 0])

The 1st element has always had the value 3 in my tests, so I’m not sure what it does.

The 2nd element indicates whether the value is stable.

The 3rd element (value 11 in the example above) is probably a flag byte. The only values I have observed so far are 2 and 11. A value of 2 indicates that the scale is in kg mode, and a value of 11 indicates that the scale is in lbs/ounces mode. Curiously, whenever the scale reads 0, it seems to indicate lbs/oz mode.

Thanks to Daniel Rice (see his comment below), we now know what the 4th element (index 3) is for; it’s for calculating the scaling factor when reading in ounces. In the above example it has a value of 255. This is in fact the signed value -1, which indicates that the raw value is in tenths, due to a scaling factor of 10^-1 or 0.1. For a value of 254, the scaling factor is 10^-2, or 0.01. I’ll refer to this value as scaling_factor below.

The elements at indices 4 and 5 are used to calculate the weight.

In kg mode:

grams = data[4] + (256 * data[5])

In pounds/ounces mode:

ounces = scaling_factor * (data[4] + (256 * data[5]))

If you check the mode, you can just convert to whatever unit you need no matter what mode the scale is in.


raw_weight = data[4] + data[5] * 256

if data[2] == DATA_MODE_OUNCES:
    ounces = raw_weight * scaling_factor
    weight = "%s oz" % ounces
elif data[2] == DATA_MODE_GRAMS:
    grams = raw_weight
    weight = "%s g" % grams

print weight

The scale is capable of reading negative values if you zero it and then remove the weight, but I haven’t yet figured out how to get negative weight values yet. The scale itself displays the correct value, but the data packet reads as if it were zero, except the second array element has a value of 5 instead of 2.

I also haven’t figured out how to determine when the reading has stabilized. Nicholas Piasecki’s article on reading a USB scale in C# says that the 2nd element in that scale’s data packet reads 4 when the value is stable, but 4 is all I observe when reading a positive non-zero weight value, even when the values are changing rapidly.

I hope this information has been useful to you. If you have any questions or have anything to add, please post a comment!

Fiero Self-Bleeding Cooling System

The cooling system of the Pontiac Fiero is adequate for street use and stock power levels, but it is difficult to properly fill without entrapping air which reduces cooling performance.

How the stock cooling system works

The stock Fiero cooling system has more parts than a typical front-engine vehicle because the hot engine is at the rear of the car and the radiator is at the front.

Coolant is pumped through the engine and out to a thermostat which directs coolant back to the pump (when cold) or to a tube running to the front of the car (when hot). At the front of the car, the hot coolant passes through a radiator with an electric fan, which cools the coolant before returning it to the engine water pump inlet via a tube running back to the engine.

At the top of the cold side of the radiator is a vented cap which connects to a coolant overflow tank through a small hose. As coolant gets hot, the coolant and any entrapped air expands. Since the system is closed, the expansion in fluid volume causes an increase in pressure.

When pressure in the system rises above the cap’s designed pressure (~15 psi), excess volume of coolant (and some air trapped at the top of the radiator under the cap) is released to the overflow tank. Air rises to the top of the overflow tank, where it’s no longer a problem. When the vehicle is shut off and the coolant cools down, it creates a vacuum which sucks fluid back in through the overflow tank. As long as the level of coolant in the overflow tank is above the hose connection, air can’t be sucked in.

Through this process, air that collects at the top of the radiator is gradually purged out with each heat cycle. This makes it very important to fill the Fiero cooling system in such a way that it includes as few air pockets as possible, since it can take many heat cycles to purge all the air.

Any air in the system causes a decrease in cooling performance, and in extreme cases can cause the vehicle to overheat or cause damage to the engine due to air pockets preventing coolant from reaching hot parts.

How modern cooling systems work

Modern vehicles (as well as older race cars and high performance vehicles) have cooling systems that continuously separate air from coolant. This improves cooling system performance and makes the system more tolerant of coolant fill procedures that result in trapped air.

To continuously separate air from coolant, there must be a place for air to collect which doesn’t affect performance of the cooling system. This is what is known as a swirl pot or expansion tank. In some vehicles (such as race cars), the swirl pot is separate from the expansion tank. In most street cars they are one and the same.

The expansion tank is part of the pressurized cooling system and is designed to have a volume of air at the top which acts as a cushion for expansion of coolant it heats up. Any excess expansion beyond the designed pressure of the cooling system is safely vented out of the expansion tank cap by bleeding off some of the air. No coolant escapes the system.

In addition to its function of allowing expansion of the coolant, the expansion tank acts as an air separator. Small coolant lines are plumbed into the expansion tank from all of the high spots in the system where air might collect. These include the engine heads, coolant outlet pipe, thermostat housing, and the top of the radiator. These connections are sometimes known as bleed ports or bleed lines.

A small amount of coolant travels through the bleed lines back to the expansion tank, along with any air that would have gotten trapped at those locations. This is a continuous flow that is facilitated by a larger hose connecting the bottom of the expansion tank to the inlet of the water pump.

The bleed ports on the expansion tank are usually configured in such a way that the coolant and air are separated by swirling the coolant along the sides of the expansion tank. The air bubbles separate out and join the large air pocket at the top of the tank, and the liquid coolant flows to the bottom to return to the water pump.

Whenever the water pump is turning, any trapped air is continuously being removed from circulation and returned to the expansion tank. This improves cooling system performance because air does not do a good job of transferring heat from the hot engine!

Self-Bleeding Fiero Cooling System

Now that we know how a self-bleeding cooling system works, how do we convert a Fiero to use one?

Let’s go through the steps I took to make this work in my 1988 Pontiac Fiero which is equipped with the Chevrolet 3.4 DOHC V6 “LQ1” engine.

  1. Install an expansion tank
  2. Add bleed ports where needed (at minimum add to top of radiator)
  3. Remove the original overflow tank
  4. Plumb the expansion tank into the system
  5. Fill the cooling system

Expansion Tank

Since I relocated my battery to the front of my car to improve weight distribution, I had a lot of room in front of the rear right strut tower on my car. Without relocating the battery, it should be possible to fit an overflow tank near the left strut tower.

I took a trip to the junkyard to look for candidate expansion tanks that would fit in the available space.

I found that a 2001 Ford Taurus expansion tank (Ford 1F1Z8A080AA) was a close fit. It is sculpted out at the bottom to clear the wheel well, has mounting tabs on the rear and side, two bleed ports, and a large outlet port on the bottom.

I mounted the expansion tank to the wheel well sheet metal using M6 rivnuts, M6 screws, and a small steel angle bracket.

It’s extremely important that the expansion tank is the highest point in the cooling system. Ideally, the “low” or “cold” mark on the expansion tank should be above the highest coolant hose, tube, or engine coolant passage.

Ford 1F1Z8A080AA mounted in a 1988 Pontiac Fiero

Bleed Ports

I added two bleed ports to the system:

  1. Top of radiator under the stock radiator cap location
  2. Engine outlet pipe where the factory installed a manual air bleed valve

For the bleed port on the radiator, I added an AN-4 adapter to my Griffin radiator fill neck. I also replaced the vented cap with a simple blank cap (Stant 10203) . This allows fluid to continuously flow out the bleed port. If you still have the stock Fiero radiator, you can use the same cap that I did, and attach your bleed line to the existing overflow fitting on the radiator.

I attached a 1/4″ tube which I ran back to the expansion tank at the rear of the vehicle, with short sections of flexible rubber hose on each end.

Bleed line on radiator

For the coolant outlet pipe bleed port, I replaced the factory-installed manual air bleed valve with a right-angle AN-4 adapter and installed a tube running to the expansion tank side of my engine.

Remove the Overflow Tank

No pictures needed — the stock tank is gone!

Plumb the Expansion Tank

Plumbing in the expansion tank took a number of different connections which I’ve called out below.

NoteNamePart NumberQty
1TankFord 1F1Z8A080AA1
2Bleed hose*Gates 181272
3Spring clamp for bleed hoseBelmetric CTC16BAND122
4Oetiker clamp for bleed hosesOetiker 13.3mm 167000102
5Water pump hoseGates 197921
6Water pump hose clamp (tank end)Belmetric CTC32BAND121
7Water pump hose clamp (pump end)Belmetric CTC28BAND121
8Engine hose barb¾” hose fitting**1
9Bleed tube*¼” tube with bead*2

* The lower right bleed hose must be connected to a ¼” line coming from the top right of the radiator. Do not use larger tubing. The upper bleed hose must be connected to a ¼” tube coming from the top of the engine water outlet pipe. Again, do not use a larger tube size. Make sure to bead all tubes before attaching hoses to them. DO NOT SKIP THE BEAD.

** You will need to select a fitting for your engine. On my car, the heater hose return tees into the radiator return tube under the car. This allowed me to use the original heater hose return fitting on the water pump of my engine.

Filling the System

The absolute best way to fill the system is to use a vacuum-facilitated coolant fill tool such as the UView Airlift or OEMTools Coolant System Refiller. These tools allow you to pull a vacuum on the cooling system to suck out all the air, then switch over to a bucket of coolant to suck in liquid while introducing very little air.

However, our system is now self-bleeding, so if we don’t have that type of fill tool we can still get a good result.

Start by removing the radiator cap and the expansion tank cap. Add coolant through the expansion tank until coolant starts to spill out of the radiator. Now reinstall radiator cap. Continue filling from the expansion tank until coolant reaches the “cold” mark on the side of the tank.

Now reinstall the cap and start the engine. Watch the coolant level in the expansion tank while the engine is at idle. The level may drop as coolant displaces air pockets in the system. Stop the engine and top it off to the “cold” mark as needed. If the engine gets too hot you may need to let the system cool off a bit before you can open the expansion tank cap.

How well does it work?

I haven’t yet had an opportunity to test the cooling system at the track, but performance around town and in spirited mountain driving has been great. During my first fill the air was purged out in about 10 minutes of driving! At this point the coolant level no longer went down as I continued to drive.

I’ll update this article when I get a chance to test the system at a race track.

Fiero Radiator Upgrade

I could not keep coolant temps down below 250*F with the stock radiator at the track. A hood vent might have made it workable, but I wasn’t ready to cut the hood.

I ended up installing a Griffin 1-25201-X radiator; it’s a universal radiator so I had to build a fan mount (Spal fan) and radiator mounts. However, it fits without any cutting or grinding of the chassis.

The 1-25201-X is close in dimensions to the stock Fiero radiator. The main differences are that it’s a little thicker, has two rows instead of one, is of entirely aluminum welded construction (no plastic end tanks), and has the cap in a slightly different spot. The inlet and outlet tubes are different dimensions, so the stock hoses won’t fit.

Since the Griffin radiator is an inch shorter than the Fiero radiator, the hood clears the radiator cap despite it pointing straight up.

Griffin 1-25201-X (left) vs Fiero radiator (right)
1-row stock Fiero radiator
2-row Griffin radiator
Griffin 1-25201-X weighs 9.14 lbs empty and 18.06 lbs full (1.07 gallons capacity)
Stock 1988 Fiero radiator weighs 7.80 lbs empty and 12.78 lbs full (0.6 gallons capacity)

Upgrading to the Griffin radiator adds 5.28 lbs to the front of the car due to the extra mass from the radiator and water. This doesn’t account for any change in the mounts and hoses however.


From left to right: Stock ’88 Fiero upper (inlet) radiator hose. Goodyear 52016 flex hose 15.5″ length with 1.5″ ID on one end and 1.25″ ID on the other end. Dayco B71159. Original ’88 Fiero lower (outlet) radiator hose (Not used).

For the upper hose, cut the stock Fiero hose in half, and couple it to the flex hose using a W0133-1788945 OES Genuine cooling hose coupler as shown. If you don’t have the stock Fiero hose, or want to replace it with new rubber, you can use a Goodyear 52011 flex hose.

Stock ’88 Fiero radiator hose (or Goodyear 52011) coupled to Goodyear 52016 flex hose using W0133-1788945 OES Genuine cooling hose coupler
Radiator inlet hose installed on Griffin 1-25201-X radiator in a 1988 Pontiac Fiero

For the lower (outlet) hose, use Dayco B71159 with an inch or two trimmed off the small end. I had to carefully twist the hose to get it to line up with the ’88 Fiero coolant pipe, not kink, and clear the overflow container. There is probably another hose out there that’s a better fit.

Dayco B71159 with one inch trimmed from the end
Radiator outlet hose installed

Now we need a mount to hold the Griffin radiator in place. The new radiator dropped into the existing lower radiator mount with some minor tweaking of the lower support lip with some pliers to clear the endtank welds. You can see the interference in the image below, right under the weld bead.

Griffin 1-25201-X radiator interference with 1988 Fiero lower radiator mount

I removed the stock upper radiator mount, this 2.58 lbs piece of steel.

1988 Fiero upper radiator support weighs 2.58 lbs including the rubber air guide

There is no way it would fit over the right side of the Griffin because of the location of the cap, and even if it did, the Griffin radiator is shorter than the stock radiator so there would be a gap where baffles need to be added to prevent air from bypassing the radiator.

Instead, I made new mounts that utilize the holes for the stock mount.

Holes in 1988 Fiero chassis for mounting upper radiator support

The stock Fiero cap can be used with this radiator. Alternatively, use an aftermarket replacement such as the Stant 10330 16 psi cap. If you buy an aftermarket cap, make sure it’s vented. Some of the parts catalogs list an incorrect unvented cap.

Expansion tank / overflow connection: a 3/8″ barb x 1/8″ NPT fitting is needed to connect the expansion tank hose. I don’t think my Griffin radiator came with one, so I’m not sure if they’re supposed to. You can source a brass or aluminum fitting from McMaster or a local supplier, and a couple feet of 3/8″ ID rubber hose, rated for coolant.

Now on to the mounts. As we saw before, the stock mount wasn’t going to fit. It looked close in the pic but doesn’t really fit at all. It’s also heavy, so I got rid of it. For the new mounts, I made some CAD templates — that’s cardboard-aided-design — to locate some rubber radiator cushions on the end tanks, transferred the cardboard to metal, bent them up in a vice, drilled mounting holes (two for the mount bolts, one for the rubber cushion), and voila! Here are the mount brackets I came up with:

Sheet metal radiator mounts for Griffin 1-25201-X in a 1988 Pontiac Fiero
Radiator mount cushions from the stock 1988 Fiero upper radiator mount
Cushion added to new radiator mount
Radiator mount installed (driver side)
Radiator mount installed (passenger side)

Finally, I had to mount my Spal 30102082 radiator fan to the new radiator. I chose to mount it flat against the radiator because this large fan has sufficient area to keep the car cool at idle without a shroud, and when the car is at speed, there will be airflow through the portion of the radiator that the fan doesn’t cover.

This fan has T slots which conveniently accept M6 hex head bolts with 10mm heads. For the bottom, I bent some aluminum brackets from 1″ wide aluminum strips to grab the bottom radiator lip:

Fan mount strap for Spal 30102082 fan on Griffin 1-25201-X radiator

For the top, a simple aluminum angle with a speed nut is sufficient to hold the radiator fan in place. The bottom straps keep the fan from moving up or back, and the top straps keep it from moving down or back.

Fan mount bracket for Spal 30102082 fan on Griffin 1-25201-X radiator

The final detail is to shroud radiator so that air can’t flow under, around, or above it. All airflow in the inlet duct from the front bumper must go THROUGH the radiator. Any gaps around the radiator will cause air to bypass the cooling system! I already upgraded the stock radiator ducting by adding more panels and taping off seams.

When I removed the stock upper mount, the stock upper shroud went with it. Pontiac had used a sheet of recycled rubber to prevent air from flowing over the radiator. I added back something similar — I used a sheet of EPDM rubber clamped to the upper flange of the radiator. The rubber sheet is draped over the radiator and AC condensor, and then folded back around to the upper flange. It effectively forms a big bulb seal, and it actually works quite well. Feel free to laugh at the binder clips, but they work great, they’re easy to remove and replace, and they cost nothing.


The finished result!

This radiator upgrade brought coolant temps down by roughly 20 degrees at the track. I had already been using this fan with my stock radiator, so the improvement is attributable directly to the radiator itself. Awesome!

Parts List

Part NumberQtyDescription
Griffin 1-25201-X124″ x 15.5″ x 3″ radiator with 1.5″ driver inlet (top) and 1.75″ passenger outlet (botom)
Dayco B711591Outlet hose 1.75″ to 1.25″
Goodyear 520111Universal hose 1.25″ to 1.25″ x 11″
Goodyear 520161Universal hose 1.25″ x 1.5″ x 15.5″
OES Genuine W0133-178894511.25″ radiator hose connector
Belmetric CTC46BAND12146mm constant tension clamp
Belmetric CTC42BAND12442mm constant tension clamp
Belmetric CTC55BAND12155mm constant tension clamp

Fiero RallyCross

Rallycross a road course track car? Are you crazy?! Oh YES!

I borrowed some gravel tires mounted on 15×6 GTI wheels from my friend and took my DOHC V6-powered Fiero track car out to a RallyCross practice event. I have been very successful competing in the all-wheel drive Apocalypse Wagon but this was my first time on the dirt with a rear wheel drive car.

With the low-hanging aero bits, lowered suspension, and almost-slick tires, this configuration won't cut it in the gravel.
With the low-hanging aero bits, lowered suspension, and almost-slick tires, this configuration won’t cut it in the gravel.

Conversion from my track setup to rallycross involved the following:

  • Swap wheels over to the gravel setup, removing the front wheel spacers
  • Remove fieroguru lateral link relocation brackets (15″ wheels will not fit over them)
  • Raise front and rear suspension by 2 inches using the adjustable coilover sleeves
  • Remove front splitter
  • Remove rear wing
  • After these adjustments, toe remained at zero front and rear. I didn’t measure the camber but it is not critical for rallycross.

The car looks a lot more mundane without all the tarmac-oriented aero upgrades!
The car looks much more mundane after removing all aero upgrades and wide wheels!

The car behaved VERY well. Surface irregularities were easily soaked up by my springs and dampers (800 lb/in front with custom valved Bilsteins, 475 lb/in rear with Koni reds at full stiff) and even the largest dips did not upset the chassis or result in tires losing contact with the ground. The fast steering made for very easy corrections. The 3.4 DOHC makes enough torque that 2nd gear can be used for almost the entire course. First was only needed if I messed up and lost a lot of momentum. Even in second gear at 2500 RPM I could spin the tires at full throttle. Even on a freshly-wetted surface, handling was predictable. The torque delivery is so linear that it’s easy to control the rotation of the car by feathering the throttle and making minor steering adjustments.

It could certainly use some more grip.. the tires I used were heavily worn, hard compound, and hardened more with age. Some fresh gravel tires should help quite a bit.

I would definitely like to make it back out on the dirt, perhaps with some fresher tires. I also had a minor issue in the form of right strut tower separation.. but as scary as it sounds it was because of some work I had done in removing some brackets and adding clearance for the power steering pump, and I forgot to re-weld some spot welds that broke while I was hammering it out. Doesn’t look too hard to fix though.

Here’s a video of one of the runs. Sorry about the sound, I didn’t have my external mic:

And some photos:

Extended wheel studs for the 1988 Fiero

With aftermarket wheels and/or thicker brake rotors, the Fiero’s stock wheel studs don’t provide much thread engagement with the lug nuts. I found that on the front of my ’88 Fiero I was only getting 8 turns with the C4 12″ rotors and my Motegi wheels. That’s 12 mm of thread engagement on a 12mm stud. Marginal at best. With the 3mm spacers I wanted to add behind my rotors to get some control arm clearance, I would be down to a dangerous 6 turns or 9mm.

I scoured the ARP and Dorman catalogs to find a good candidate. The 1988 front hub holes are about 0.490″ with the stock studs removed. Dorman recommends a hole size between 0.017″ and 0.027″ under the knurl OD, while ARP recommends 0.005″ for iron and steel hugs and 0.007″ for aluminum. It’s not clear why there’s such a big range or difference between the recommended interference.

The closest longer studs that would fit are ARP 100-7708 and Dorman 610-323. The ARP 100-7708 studs have an 0.509″ knurl,  making a 1/2″ reamer the closest common size to the correct hole size (0.504″ by ARP’s recommendation). When installed, these studs increase the thread length by 0.84″ (21.4mm) over the stock studs.

The Dorman 610-323 studs have a 12.80 mm (0.504″) knurl, which fit in the original hub holes based on Dorman’s specifications. They are 54 mm long, thus increasing the thread length by 12mm over the stock studs.

I pressed the lug studs out of a brand new Rodney Dickman 88 front hub and measured the hole size as about 0.490″ at the smallest and around 0.50″ at the largest. I went ahead and pressed the ARP studs in without reaming the hole to 0.503″,  and they pressed in without too much trouble. The hub didn’t split, but a few metal shavings were produced by the knurl pushing through the hole. This fit exceeds the ARP recommendation for the interference fit, but is within spec if Dorman’s recommendation is followed.

1988 Fiero hub with ARP 100-7708 studs installed
1988 Fiero hub with ARP 100-7708 studs installed

Since these studs are so much longer than stock, open-ended lug nuts must be used. For GM wheels the stock ones should work. In the aftermarket, I found some inexpensive Gorilla lug nuts on The part number is 20033SD for a set of 20 lug nuts and the spline drive socket. These nuts are narrow enough to fit in aftermarket wheels. I tried some White Knight lug nuts but they were too large in diameter to fit in the lug but counterbores in my wheels.

I purchased these inexpensive Gorilla brand  open-end lug nuts on
I purchased these inexpensive Gorilla brand open-end lug nuts on p/n 20033SD

The Gorilla lug nuts fit perfectly in my aftermarket Motegi MR116 wheels. The only disadvantage of these nuts is that the require the use of Gorilla’s spline drive key. Some hex drive lug nuts are available from Vorshlag that look like they might fit, since they are small enough to use a 17mm hex instead of the 19mm hex on the White Knight lug nuts that were too large for my wheels.

After installing the extended studs and open-ended lug nuts, I had plenty of thread engagement while running a 3mm rotor spacer
After installing the extended studs and open-ended lug nuts, I had plenty of thread engagement while running a 3mm rotor spacer

The same studs will work just as well on the rear bearings as on the front.