Editing
Vernier Go Temp USB device in Linux
Jump to navigation
Jump to search
Warning:
You are not logged in. Your IP address will be publicly visible if you make any edits. If you
log in
or
create an account
, your edits will be attributed to your username, along with other benefits.
Anti-spam check. Do
not
fill this in!
I've got a [http://www.vernier.com/go/gotemp.html USB thermometer] that is recognized by Linux when I plug it in, but I have no idea how to read it. Below are the steps I went through to figure out how to get Linux to read it, but you should skip to the end and download the [http://www.vernier.com/downloads/gosdk.html Vernier Linux SDK], which I was unaware of when I started solving this puzzle. /proc/bus/usb/devices says this about it: <pre> T: Bus=02 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 2 Spd=1.5 MxCh= 0 D: Ver= 1.10 Cls=00(>ifc ) Sub=00 Prot=00 MxPS= 8 #Cfgs= 1 P: Vendor=08f7 ProdID=0002 Rev= 1.53 S: Manufacturer=Vernier Software & Technology S: Product=Go! Temp ver 1.53 C:* #Ifs= 1 Cfg#= 1 Atr=80 MxPwr=100mA I: If#= 0 Alt= 0 #EPs= 1 Cls=03(HID ) Sub=00 Prot=00 Driver=ldusb E: Ad=81(I) Atr=03(Int.) MxPS= 8 Ivl=10ms </pre> udev says that it has created a device for the ldusb driver called /dev/ldusb0 here (implemented in the Kernel as ldusb.c): crw-rw---- 1 root root 180, 176 2008-01-05 11:17 /dev/ldusb0 That's hopeful, but how do I poke at that device, exactly? Googling for ldusb0 I found someone who has the same device ( http://www.thok.org/intranet/python/vernier/README.html) and says that this code works to read it: <pre> #!/usr/bin/python import time import struct ldusb = file("/dev/ldusb0") time.sleep(0.5) # for n in range(10): while True: # time.sleep(0.5) pkt = ldusb.read(8) parsed_pkt = list(struct.unpack("<BBHHH", pkt)) num_samples = parsed_pkt.pop(0) seqno = parsed_pkt.pop(0) for sample in range(num_samples): print seqno+sample, parsed_pkt[sample]/100.0 # time.sleep(0.5) </pre> But it doesn't work for me. I picked a bad day to not learn python. Perhaps I can grok it enough to write a perl script to do the same thing. From the above article: <pre> 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. It appears to generate around 2.5 samples per second, which is probably overkill.</pre> It looks like the perl should be something like this: my $buf; open(DEV, "/dev/ldusb0") || die "couldn't open device file"; my $number_read = read(DEV, $buf, 8); my ($samplecount, $sequence, $temp1, $temp2, $temp3) = unpack("c c s s s", $buf); print "$samplecount, $sequence, $temp1, $temp2, $temp3\n"; And it works! 3, 127, 2840, 2840, 2840 Now, what are those numbers? Room temperature seems to be from 2400 to 2800. Grabbing the thermometer yields about 4280. Putting it into a hole into our uninsulated wall when it is 8 degrees Celsius outside seems to stabilize about 2000. Putting the sensor in the heater vent when it blowing shows about 4000. I've tried telling unpack to treat the value as different formats but to no effect. v (little-endian short) S (unsigned short) s (signed short) All seem to yield the same value after unpacking. The advertised specifications for the sensor are: <pre> Range: -20°C – 110°C Maximum temperature that the sensor can tolerate without damage: 130°C Resolution: 0.07°C Accuracy: +/- 0.5°C Response time: 4s (to 90% of full reading in water) </pre> Here is the graph of heater vent using the thermometer: http://finninday.net/temp/vernier.html ===Conversion formula=== My formula for converting the Vernier probe data to Celsius is this: C = V / 126.74 - 5.4 I arrived at that formula after taking these measurements with a cup of hot water and a cup of ice water. I used a kitchen thermometer to provide half the data. {|border="1" cellspacing="0" cellpadding="5" align="center" |Vernier |Fahrenheit |Celsius |V/C Ratio | | |- |8504 |143.2 |61.7 |67.1 |5.4 |61.7 |- |8464 |142.5 |61.4 |66.78 |5.38 |61.38 |- |848 |33.6 |0.8 |6.69 |5.89 |1.29 |- |824 |33.3 |0.7 |6.5 |5.8 |1.1 |- |760 |33.1 |0.6 |6 |5.4 |0.6 |- |- |7744 | |61.1 |126.74 | | |} 7744 is the difference between the maximum and the minimum of the Vernier values. 61.1 is the difference between the maximum and the minimum of the Celsius measurements. 126.74 is the ratio of the differences. The V/C Ratio column is the result of multiplying the Vernier values by 126.74. From there I can see that I'm generally about 5.4 degrees too high. == Official Linux SDK == As of September 2010, Vernier Software & Technology offers an official [http://www.vernier.com/downloads/gosdk.html USB Linux temperature reading SDK] for the device. This appears sufficient for server room monitoring. == probe shows up as /dev/usb/hiddev0 under Fedora 23== It looks like usb devices in /dev/usb/hiddev0 present data in a different way that /dev/ldusb. I haven't made it work in Fedora yet, but it looks like the data is still there, just at a different offset. With enough experimenting with <pre> cat /dev/usb/hiddev0 | od </pre> I could figure out where the temperature data is now. I'm used to the Go Temp data appearing like this through /dev/ldusb0: <pre> [root@hyper1 bin]# cat /dev/ldusb0 | od 0000000 075403 005300 005300 005300 003003 005270 005270 005270 0000020 004401 005270 005270 005270 005001 005270 005270 005270 0000040 005401 005270 005270 005270 006001 005270 005270 005270 0000060 006401 005270 005270 005270 007001 005270 005270 005270 0000100 007401 005270 005270 005270 010001 005270 005270 005270 0000120 010401 005270 005270 005270 011001 005270 005270 005270 0000140 011401 005270 005270 005270 012001 005270 005270 005270 0000160 012401 005270 005270 005270 013001 005270 005270 005270 ^C </pre> Coming through /dev/usb/hiddev0, it looks like this: <pre> # cat /dev/usb/hiddev0 | od 0000000 000106 000001 000001 000000 000106 000001 177716 177777 0000020 000106 000001 000100 000000 000106 000001 000013 000000 0000040 000106 000001 000150 000000 000106 000001 000016 000000 * 0000100 000106 000001 000001 000000 000106 000001 177717 177777 0000120 000106 000001 000110 000000 000106 000001 000013 000000 0000140 000106 000001 000150 000000 000106 000001 000016 000000 * 0000200 000106 000001 000001 000000 000106 000001 177720 177777 0000220 000106 000001 000110 000000 000106 000001 000013 000000 0000240 000106 000001 000150 000000 000106 000001 000016 000000 * </pre> == Using /dev/hidraw0 == Now I'm using this python program to read samples from the Go Temp USB <pre> #!/usr/bin/python import time import struct ldusb = file("/dev/hidraw0") time.sleep(0.5) pkt = ldusb.read(8) parsed_pkt = list(struct.unpack("<BBHHH", pkt)) num_samples = parsed_pkt.pop(0) seqno = parsed_pkt.pop(0) for sample in range(num_samples): cel = parsed_pkt[sample]/128.0 fahr = (9.0/5.0 * cel) + 32.0 print fahr </pre>
Summary:
Please note that all contributions to finninday may be edited, altered, or removed by other contributors. If you do not want your writing to be edited mercilessly, then do not submit it here.
You are also promising us that you wrote this yourself, or copied it from a public domain or similar free resource (see
Finninday:Copyrights
for details).
Do not submit copyrighted work without permission!
Cancel
Editing help
(opens in new window)
Navigation menu
Personal tools
Not logged in
Talk
Contributions
Log in
Namespaces
Page
Discussion
English
Views
Read
Edit
View history
More
Search
Navigation
Main Page
Recent changes
Food
Travel
Tools
What links here
Related changes
Special pages
Page information