Stamps.com USB Scale on macOS

I’m a lawyer. We still send lots of paper around (even though I’m of the opinion 99.995% of our dead tree activity could and should be PDF - but I digress). I’ve been using a Model 510 scale I got with a stamps.com subscription years ago, to weigh mailings so I can print exact postage with Endicia. But the scale doesn’t show up in the Endicia app, and so I’ve been booting into a Linux virtual machine to get weights. Clumsy. So, I took at look at the code for the little program I was using, usbscale. It relies on libusb, which is a cross-platform library. So far so good.

Some initial setup stuff, if you don’t already have a full dev environment setup, first install brew, and then:

% brew install autoconf automake

I downloaded source for both packages from github, and first installed libusb:
 
% mkdir usbscale
% cd usbscale 
% git clone https://github.com/libusb/libusb.git
% git clone https://github.com/erjiang/usbscale.git

In the libusb directory:

./bootstrap.sh

$ ./configure && make && make install

$ find /usr/local -name "libusb.h"

/usr/local/include/libusb-1.0/libusb.h


The usbscale code needed a little help (there’s no native le16toh). Created the file /usr/local/include/endian.h  which I shamelessly stole from Dendi Suhubdy:

#ifndef __FINK_ENDIANDEV_PKG_ENDIAN_H__

#define __FINK_ENDIANDEV_PKG_ENDIAN_H__ 1

/** compatibility header for endian.h

 * This is a simple compatibility shim to convert

 * BSD/Linux endian macros to the Mac OS X equivalents.

 * It is public domain.

 * */


#ifndef __APPLE__

    #warning "This header file (endian.h) is MacOS X specific.\n"

#endif  /* __APPLE__ */



#include <libkern/OSByteOrder.h>


#define htobe16(x) OSSwapHostToBigInt16(x)

#define htole16(x) OSSwapHostToLittleInt16(x)

#define be16toh(x) OSSwapBigToHostInt16(x)

#define le16toh(x) OSSwapLittleToHostInt16(x)


#define htobe32(x) OSSwapHostToBigInt32(x)

#define htole32(x) OSSwapHostToLittleInt32(x)

#define be32toh(x) OSSwapBigToHostInt32(x)

#define le32toh(x) OSSwapLittleToHostInt32(x)


#define htobe64(x) OSSwapHostToBigInt64(x)

#define htole64(x) OSSwapHostToLittleInt64(x)

#define be64toh(x) OSSwapBigToHostInt64(x)

#define le64toh(x) OSSwapLittleToHostInt64(x)


#endif  /* __FINK_ENDIANDEV_PKG_ENDIAN_H__ */

I added an #include in usbscale/usbscale.c:


...

#include <libusb-1.0/libusb.h>

#include <endian.h>

...


And then compiled it normally:


$ make

cc -Os -Wall usbscale.c -lm -lusb-1.0 -o usbscale


Voila, it’s alive:

$ ./usbscale 

5 oz


Sweet. I don’t have to have a Linux VMware instance spun up to get a weight off this scale. This makes my life slightly easier.

I’ll take it.

For troubleshooting, as necessary, I added a debug flag to the Makefile for usbscale and recompiled it:

$ cd usbscale-master

$ vim Makefile

#CFLAGS=-Os -Wall 

CFLAGS=-Wall -DDEBUG

$ make clean; make usbscale

rm -f lsscale

rm -f usbscale

cc -Wall -DDEBUG usbscale.c -lm -lusb-1.0 -o usbscale


I also built some of the example programs bundled with libusb, and the lsusb program included with usbscale:

$ cc -Os -Wall lsusb.c -lm -lusb-1.0 -o lsusb

$ cd ../libusb-master/examples/

$ ln -s /usr/local/include/libusb-1.0/libusb.h .

cc -Os -Wall testlibusb.c -lm -lusb-1.0 -o testlibusb

cc -Os -Wall listdevs.c -lm -lusb-1.0 -o listdevs


All the programs find the 510 scale:


$ ./listdevs 

1446:6a73 (bus 26, device 6) path: 1.4.4

$ ./testlibusb 

Dev (bus 26, device 6): 1446 - 6A73 speed: 1.5M

  Product:                   Stamps.com Model 510 5LB USB Scale

$ ../../usbscale-master/lsusb 

1446:6a73 (bus 26, device 6)


Edit: I've confirmed this still works (mostly?) at least as of Big Sur (11.6.7):


% uname -a
Darwin Mac-mini.local 20.6.0 Darwin Kernel Version 20.6.0: Tue Apr 19 21:04:45 PDT 2022; root:xnu-7195.141.29~1/RELEASE_X86_64 x86_64


% ./listdevs
1446:6a73 (bus 26, device 6) path: 1.2.3


% ./testlibusb

Dev (bus 26, device 6): 1446 - 6A73 speed: 1.5M


% ./usbscale/usbscale
Found scale 1446:6a73 (bus 26, device 6)
It has descriptors:
    manufc: 1
    prodct: 2
    serial: 3
    class: 0
    subclass: 0
libusb: warning [darwin_open] USBDeviceOpen: could not establish a connection to the Darwin kernel
zsh: segmentation fault  ./usbscale/usbscale



Comments