Talking to a Vernier GoTemp (USB temperature probe) from python.
Thanks to Federico Grau (for going back and forth with Vernier) for
finding a calibration mechanism, but also for noting that Greg Kroah
Hartman's tutorial and example code (in particular, the user-space
get_temp
wrapper) actually multiplies by the cryptic-looking
value 0.0078125 to get Celsius values.
Thanks also to johnl
for pointing out that his device was
calibrated in units of 128ths of a degree, instead of 100ths; when he
pointed that out, I went back and looked at the cryptic-looking
number, and realized that my "computational numerology" skills had
failed me - 0.0078125 is 1/128 (my original 1/100 was an entirely
unjustified guess.)
(Also, thanks to Dave Vernier for his feedback, which hasn't yet been incorporated into the code - that's right, Vernier isn't just a clever name for a measurement company, it's an actual person :-)
Footnotes:
I did update the print server machine to Ubuntu Gutsy, which has a
kernel with working LDUSB
, so gotemp-ldusb.py works fine.
However, I just did a simple icebath test, and it reads no lower than
0.72C...
I got email from someone who's in touch with the vendor; it turns out that they have an SDK and that there's a calibration step that one should use when talking to the hardware, but which isn't documented anywhere else. Some poking around points to http://www.vernier.com/diy/ which is mostly about the LabPro products, but there are some Go! drivers there that I should clearly take a look at.
Tried the LDUSB
path on my print server (a silent machine on the south
end of the house, which would serve as another data point.) It's an
Ubuntu Edgy (6.10) machine, running the stock 2.6.17 kernel... which
has a recently (early 2007) fixed bug in the driver:
ldusb 1-2:1.0: Read buffer overflow, 1937069164 bytes dropped
That's a good reason to update the machine, I suppose :-) but is a
(very minor) downside the the LDUSB
path, in terms of just slapping
probes on random ambient machines without turning the whole thing into
an infrastructure modernization project. (Of course, Edgy doesn't
include python-pyusb
either...)
This inspires me to check the chumby versions of things: turns out the production chumby ships with a 2.6.16 kernel (which is old enough that it doesn't have the LDUSB fixes) but it also turns out that
# CONFIG_USB_LD is not set
in linux-2.6.16/.config
so that wouldn't work anyway. (On the
positive side, LDUSB won't be grabbing the device, so I won't have the
detachKernelDriver
problem either...)
Footnotes:
Picked up a Vernier GoTemp, a $40 USB temperature probe designed for
the science education market (there are bulk discounts, and courseware
examples on their site) with an eye towards having the Chumby record
and forward local temperatures to a central logging and analysis
server (I'm still looking for ideas and/or solutions for that part -
the popular first guess, rrdtool
, isn't really the right
answer for accumulating long-baseline data...)
Turns out to be a quite solidly-made device, ie. "will survive extensive student use" rather than just "cheap enough for schools to afford". I'm pleased, given the extent to which I bang things around :-)
It is recognized under Linux via the LDUSB
driver, and it looks like
that's enough to read packets from it; turns out that an 8-byte read
(from /dev/ldusb0
) gets you a one-byte sample count, a one-byte
sequence number, and three two-byte little-endian temperature samples
which appear to be 100ths of a degree celsius EDIT 128ths! see later post. It appears to generate
around 2.5 samples per second, which is probably overkill.
gotemp-ldusb.py has the terribly simple code.
One can also talk to it with pyusb
as well (0.3.5-4 from Ubuntu
Gutsy), and I started with the code I used for the Foam Rocket
Launcher; the only real issues were that detachKernelDriver
caused an error if LDUSB
was already detached by a previous run of the
script, and that if I read too soon, interruptRead
would raise
usb.USBError: No error
. On the positive side, this path gets
consistent zero values for unused sample slots (there is space for
three samples in every packet, but the leading count tells you how
many of them are actually supplied), where the LDUSB
path appears to
leak values from the previous packet; as far as getting samples out
goes, this doesn't matter at all, since you've got to go by the sample
count, not the value, anyway. gotemp-pyusb.py
The LDUSB
approach probably has the edge, in that one can configure
udev
to make the device accessible, where as the direct usb
driver needs root. pyusb
might be more useful in distinguishing
among multiple probes on the same machine, based on USB topology, but
/sys/class/usb/ldusb0
appears to have equivalent information.
Amusingly, a good source of information on talking to this probe from Linux was Greg Kroah-Hartman himself - at the 2005 Ottawa Linux Symposium, he gave a "Write a Real Linux Driver" tutorial, and used the GoTemp as the example hardware, providing a single "temperature now" value from it. (It's not really worth the trouble for my application, it still layers on top of LDUSB after all - but it's an excellent skeleton for figuring out what the USB pieces are all about.)
Footnotes:
ols_2005_driver_tutorial_example_code.tar.gz
is linked from http://kroah.com/linux/
08f7:0002 Vernier EasyTemp
"