Unlocking the data stream from the Pittsburgh Digital Dial Gauge

2014.12.20 23:05

I have an upcoming need to quickly and accurately verify that a lot of parts have dimensions within tolerance. I already have Digital Calipers I bought off Amazon but I needed something easier to use. My local Harbor Freight carried the Pittsburgh branded Digital Dial Gauge. Dial gauges are spring loaded probes designed for measuring displacement and are optimal for measuring many parts in test fixtures. (NOTE: This dial gauge may also be branded as CenTech).

Like a digital clock, it is easier to read absolute values on a digital dial gauge. Furthermore, like its Chinese calipers cousins, it also included a data port. Streaming the data from the dial gauge to a data concentrator streamlines data collection. Thus I could quickly determine the distribution of measurements of the same part. At this point, I had to capture the data streaming from the dial gauge.

The author of this handy hackaday.io project page already published some of the necessary groundwork. He has done a fantastic writeup of the data streaming protocol; I will only document my changes to his approach here.

However, I decided to depart from his approach in a few ways:

MSP430 Usage

I am most familiar with the MSP430 platform so I chose to use that. MSP430 will also run at 3.3V, which makes integration with BeagleBone Black, Raspberry PI or Teensy much easier. I chose to use the MSP430G2452, which does not include a UART but does have an onboard comparator. The comparator peripheral provides a 0.25 Vcc reference point, so I connected the Clock line from the dial gauge to P1.0 and activated the comparator for that pin. I leveraged some minimal UART code I posted on 43oh to output the measurements over the TX line. Using this code frees up the USI peripheral, so if I want an I2C interface for more sophisticated functions (min hold, max hold, etc) I can use just two pins for those. As this is a low frequency device (only about 8 measurements/sec) it would also integrate well on a shared I2C bus.

Providing external power

This step had two surprises. As I did not have the cable to hook this up, I just took 4 conductros from an old IDE ribbon cable and soldered the ends directly to the connector traces on the PCB. After I had soldered the wires to the data port, I puzzled over why I was not reading battery voltage over the fourth pin. Inspecting the PCB showed that the pin was actually not connected at all; it required an SMT jumper to reach the positive rail. Thankfully, the positive rail was very close by the fourth pin, so I just patched up my wire job. Now I seemed ready to power up the dial gauge without a battery.

The dial gauge is normally powered by a coin cell battery. I measured the output voltage to be about 1.35V in circuit. I didn't have a regulator for that voltage level, so I just used a pot and an opamp follower to provide the needed voltage. Typically you would use a regulator but the current draw is very small compared to the opamp output (which was about 25ma). So when I first hooked up the power the dial gauge went bonkers and spewed random numbers to the display. Of course I had forgotten the other important measurement besides voltage: source resistance. Button cells typically have pretty high source resistances (about 100-200 ohms), which is why they can power an LED without using a resistor. Adding a 100 ohm resistor in series quickly fixed this issue; readings stabilized thereafter. This also explains why there was a "jumper" for connecting the fourth pin to the positive rail; it was actually intended for an 0805 resistor.

Level Shifting

The hackaday project had sidestepped the issue of level shifting by just polling the data and clock lines with ADC measurements. This is sacrilege to an MSP430 user as polling creates unnecessary power usage. The onboard comparator was an obvious choice for the clock line; I would only have to set the reference and respond to the interrupt when the voltage changed. For the data line I could have also done an ADC read but I felt that was also too complicated and power hungry. I already had a 4 opamp chip on my breadboard; I just connected the data line to the + terminal on the opamp, doubled the voltage and fed the doubled signal directly to a GPIO. Since I was using the same component over again I did not need to fish out any transistors.

Parsing the data

Interrupt driven programming is not as straightforward as blocking. Although you can stage out the processing pipeline easily on paper, the same interrupt handler probably has to handle multiple non consecutive steps in the process. Most people would call this spaghetti code but I call it art. When the time is right, I will publish the code on github and provide a link here.

Blinking the LED

This was the easiest and most useful step. The LED blinks when a packet is successfully parsed and ready to be streamed over UART. Stopping the LED is handled by the timer overflow interrupt; not very neat by simple and it works.

References:

Keep updated with new posts: or follow on the Twitter feed