Python USB hacks.
A few years back I picked up a Radio Shack USB Electronic Scale, on clearance, on the theory that it might work someday - or else I'd get at least that much value out of taking it apart...
I found it on a shelf today, plugged it in, did a google search for the USB id, and found user-space code that talked to
hiddev0 and turned the events into weights. As much for the practice as anything, I converted it to python - handling
ioctls isn't particularly tricky, but it took some poking to determine that the event values were sign-extended bytes, and the multiple reassignments to different variables in the C code actually mattered.
The python code probably needs to run as
root unless you do some
udev tweaking; fire it up with the scale empty, when you get the prompt, put something on it, hit enter, and read the weight in grams. Not terribly exciting... but the next step might be to keep reading until the new value stabilizes. Ultimately I'd like to put this in the kitchen, maybe hooked to a chumby, with code that lets you set a target weight, then beeps in one tone when you get close, and another when you hit the actual value (or something more sophisticated.) Basically to let me look at what I'm pouring rather than at the display... could also do multiple targets for mixing, have it even "speak" the next item to add (or for things that are strictly proportional, adjust later measurements based on the initial one, though that seems like it might not be that useful compared to just being accurate.)
note added 20140224 I wonder if the app attached to the Adaptics "Drop" connected-scale will include that, it at least does sophisticated recipe integration...
What changes should I make next?
eichin-python-comments-2007 at this domain, as I haven't narrowed it down enough to put it on http://doxory.com instead :-)
As part of tonight's Best Practical Hackathon, I implemented software limit switches. use_launcher_1.py now
It's still horribly messy code, but now that it does what I want it to, I can refactor it into something cleaner... and even in its current state, it's pretty readable.
I finally picked up one of the popular USB foam-rocket launchers, http://www.cyberguys.com/templates/searchdetail.asp?productID=13430 and started looking for linux code (and, of course, by preference Python code) to talk to it.
Learned a few things right off:
There were a few chunks of useful reference material:
self.dev.handle.controlMsg(0x21, 0x09, self.INITA, 0x02, 0x01)which gives no hints as to what is actually going on; the
usbmodule has symbolic constants for these, after all. My version is, instead,
handle.controlMsg(reqType, usb.REQ_SET_CONFIGURATION, reqBuffer, value=usb.DT_CONFIG, index=0)and that's nearly self-documenting :-)
So, I spent an evening understanding the device (and generic USB) parts from David Wilson's work, and working backwards to python code based on Scott Weston's work. use_launcher_0.py is the "zeroeth" version, most of which is useful for playing with in an interactive shell.
Next step: it turns out that the DreamCheeky relies on the driver for "safety" features; when you hit the edge of the range of motion, the device keeps grinding until you make it stop. It does, however, report the value of the four limit switches via
handle.interruptRead(endpoint.address, 8), so you just have to check that every so often while you're commanding it.