The good news is this cheap Xiamen ELANE.NET load cell powers-up on USB into Report 3 mode; barfing its current weight in grams, constantly.
Here's its datasheet:
http://www.elane.net/USBscales/List_USB_Digital_Load_Cell_Commands_and_Data_Format_User.pdf
I can read that with standard pyusb
calls. This sample could read the scale...
http://www.orangecoat.com/how-to/read-and-decode-data-from-your-mouse-using-this-pyusb-hack
... if you replace the device lookup with usb.core.find(idVendor=0x7b7c, idProduct=0x301)
(I also abuse sudo
to run my program, bc I decline to muck around with the device permissions, and sudo
is easy on a Raspberry Pi.)
Using standard pyusb
calls, I can read my scale's spew like this:
device.read(endpoint.bEndpointAddress, endpoint.wMaxPacketSize)
That returns a 6 byte array:
+--------------------- Report type
| +------------------ Weight Stable (tray not moving)
| | +--------------- grams (not pounds)
| | | +------------ whatever
| | | | +--------- 2 grams
| | | | | +------ 0 x 256 grams
| | | | | |
V V V V V V
[3, 4, 2, 0, 2, 0]
Now the fun starts when I try to send commands to the scale. The command to zero-out the current weight (Zero Weight, aka "tare") might be 7 4 2 0 0 0
.
If I use sample code like https://github.com/walac/pyusb/blob/master/docs/tutorial.rst to find the ENDPOINT_OUT endpoint, and write to it using either of these lines, I can't tare:
# ep_out.write('\x07\x04\x02\x00\x00\x00', 6)
ep_out.write([0x07, 0x04, 0x02, 0x00, 0x00, 0x00], 6)
(The symptom is, I can put a load on my load cell, weigh it with the above .read()
line, then tare, then not get a zero when I .read()
again.)
Okay, we're not dead yet. We haven't tried any HIDAPI. So I apt-get
me some libusbhid-common
, some cython-dev
, some libusb-dev
, some libusb-1.0.0-dev
, and some libudev-dev
, and I upgrade the HIDAPI C example code to attempt a tare:
handle = hid_open(0x7b7c, 0x301, NULL);
buf[0] = 0x07;
buf[1] = 0x04;
buf[2] = 0x02;
res = hid_write(handle, buf, 3);
And that tares.
To replicate my one success in Python (despite how tempting rewriting one small layer of my app in C++ is!), I whip out some Cython-hidapi (presumably from git://github.com/signal11/hidapi.git
), and upgrade their try.py
example code:
h = hid.device()
h.open(0x7b7c, 0x301)
print("Manufacturer: %s" % h.get_manufacturer_string())
print("Product: %s" % h.get_product_string())
print("Serial No: %s" % h.get_serial_number_string())
res = h.write([0x07, 0x04, 0x02, 0,0,0])
Guess what? The last line does not tare. But it DOES tare if I run it 3 times!
res = h.write([0x07, 0x04, 0x02, 0,0,0])
res = h.write([0x07, 0x04, 0x02, 0,0,0])
res = h.write([0x07, 0x04, 0x02, 0,0,0])
So, before I write a loop that calls the tare line over and over until the read returns a level zero, could someone check my math and suggest a shortcut? A raw pyusb
solution would work great, too.