Last week I started putting together the new firmware that will allow the MSP430 Launchpad version of the digital readout to read a mix of different scales and calipers. My last post discussed the needed hardware changes and touched on the high-level requirements. With the adapter board build and tested I was able to start investigating the data formats used by the small collection of calipers I was able to put together. Using my trusty Open Logic Sniffer I was able to identify two different protocols. BG Micro Digital Indicator used the 48 bit protocol described in the excellent article "Chinese Scales" by Shumatech. Surprising none of the other calipers used this protocol.
Instead of two 24-bit streams separated by a short interval, the calipers sent a single 24-bit stream split into six niblets of 4 bits each. Additionally the transfer rate was almost 20 times slower, compared to the 48-bit scale. Whereas the latter transferred the data at close to 80 KHz, the former used a leisurely rate of less than 4 KHz.
|Harbor Freight calipers sent the data using six 4-bit niblets|
After some research I came across an article at robotroom.com where David describes a similar protocol called BCD 7, that uses seven 4-bit niblets. Each of the first six niblets is used to represent a decimal digit from 0-9 and the last unit contains the metadata about the position. After some experimenting I was disappointed to discover that the protocol used by the calipers was different. Searching the internet didn’t turn up much useful information so I was left with no other options but to reverse engineer the protocol.
Side note: BCD stands for "Binary Coded Decimal". Using this scheme each decimal digit is represented using a 4-bit niblet. For example, decimal number 256 (or 2^8) in binary is 10000000. In BCD format it would be 0010, 0101, 0110 (2,5,6). Negative numbers are represented using as 2’s complement. This format is less compact than the straight binary representation but is easier to understand for humans (I guess as easy as a stream of ones and zeros can be to understand).
At that point the large portion of the firmware was functional so the controller could read the raw stream into a 32-bit integer and send it to the UART. All I had to do was place a breakpoint at the appropriate place and start moving the caliper around. Right away I noticed that everytime the screen is zeroed out the data stream reads all "0"s. This had to mean that unlike the rest of the scales the calipers transmit only the relative position. To investigate further I started writing down the position indicated on screen and the raw stream coming from the caliper into a table similar to the one shown below.
A careful look at the results show a some clear patterns:
- The last bit of the stream indicates the "inch" mode when it's set and "mm" when it's not.
- The 21-st bit indicates the negative number. In contrast the rest of the scales that use the "complement of two" representation.
- The calipers appear to be sending the least significant bit first, since small readout values change the first bits of the stream.
Table 2: "Normalized" data
The data suggests that in "mm" mode the position is sent in 100s of a millimeter using straight binary encoding for both positive and negative numbers. In "inch" mode the caliper uses 2000 ticks per inch (i.e. the position is reported in 1/2 thousandths). Based on these finding I was able to start working on the firmware design, which will be covered in the next post.
Side note:I wasn’t able to determine if the 22nd and 23rd bits have any meaning. Additionally there is no evidence that all of the first 20 bits are used. Using 16 bit the caliper can measure to a bit over 65 cm or 32 inches. For the DRO it’s irrelevant since I’m using 32-bit signed integers (in order to accommodate the 24-bit scales); otherwise a 16 bit integer should be enough for most situations.