About the product:
lsusb shows 0c45:7403 (Microdia Foot Switch)
[13448.536120] usb 6-1: new low-speed USB device number 3 using uhci_hcd [13448.709126] usb 6-1: New USB device found, idVendor=0c45, idProduct=7403 [13448.709139] usb 6-1: New USB device strings: Mfr=1, Product=2, SerialNumber=0 [13448.709146] usb 6-1: Product: TH1000isoV1.5 [13448.709152] usb 6-1: Manufacturer: RDing
Getting it to work:
You can use the same program as in this post: http://verahill.blogspot.com.au/2013/12/532-temper-temperature-monitoring-usb.html with some minor modifications. Before running
sudo python setup.py install
make some changes in temperusb/temper.py.
Firstly, you need to allow for the detection of devices with the 0c45:7403 ID
Secondly, you need to make sure that the program knows which device is which and treats them differently. Finally, you need to collect the right data-- the TEMPer1k4 returns a data_s with a length of 8 (caveat -- I haven't checked what the output from 0c45:7401 looks like. Maybe it too yields 8 fields), and the [2:4] data block contains the internal temperature of the USB device, while the [4:6] data block holds the thermocouple junction temperature. Of a sort -- you get a number which you need to translate into a temperature. See the bottom of this post for how I worked it all out. Please note that you should calibrate the thermocouple -- the uncorrected output seems to be at least 2-3 degrees too high.15 VIDPIDs = [(0x0c45L,0x7401L),(0x0c45L,0x7403L)]
Beyond this, follow the instructions in http://verahill.blogspot.com.au/2013/12/532-temper-temperature-monitoring-usb.html and make sure to set up a rules file with the correct USB ID for this device.120 data = self._interrupt_read(self._handle) 121 data_s = "".join([chr(byte) for byte in data]) 122 if len(data_s)==8: 123 # print '24 ',struct.unpack('>h', data_s[2:4])/16.0 124 # print '46 ',struct.unpack('>h', data_s[4:6]) 125 temp_thermocouple = struct.unpack('>h', data_s[4:6]) 126 temp_internal = 0.0625*(struct.unpack('>h', data_s[2:4])/16.0)+0.0025 127 temp_c=(temp_thermocouple*0.25+1.50) 128 if calibrate==True: 129 temp_c=temp_thermocouple #uncomment for calibration 130 else: 131 temp_c = 125.0/32000.0*(struct.unpack('>h', data_s[2:4])) 132 temp_c = temp_c * self._scale + self._offset 133 if format == 'celsius':
If you're curious about the details, have a look below.
Analysing USB traffic:
Since I wasn't quite sure where to start I figured the easiest approach would be to sniff the traffic between the usb device and the offically supported programme from PC Sensors. So I installed it Win XP in virtualbox, read a couple of temperatures and compared them with the captured data.
To capture data I did:
sudo apt-get install tshark sudo modprobe usbmon lsusbBus 008 Device 003: ID 17ef:4815 Lenovo Integrated Webcam [R5U877] Bus 008 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub Bus 006 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub Bus 005 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub Bus 004 Device 043: ID 0c45:7403 Microdia Foot Switch Bus 004 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub Bus 004 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub Bus 007 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub Bus 003 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub Bus 002 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub Bus 001 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hubsudo tshark -D1. eth0 2. wlan0 3. nflog 4. nfqueue 5. usbmon1 6. usbmon2 7. usbmon3 8. usbmon4 9. usbmon5 10. usbmon6 11. usbmon7 12. usbmon8 13. any 14. lo (Loopback)touch 1.pcap chmod ugo+w 1.pcap sudo tshark -i usbmon4 -w $HOME/1.pcap
I opened the 1.pcap file in wireshark and looked for fields called leftover data.
Here are two examples of such 'leftover data' fields:
Host to USB: 01 80 00 00 00 00 00 00 USB to Host: 80 06 17 f0 00 5c 0f ff
Subjecting the system to different temperatures helped me figure out what fields where changing -- I've marked them in bold above (blue for the thermocouple, red for the internal temperature). Interestingly, I got overflow when freezing the thermocouple between two ice cubes, which indicated that there was a fairly high lower limit (1.5 degrees)
The following are some of the data I harvested. The temperature is in the first column, the hex code is in the second one and the decimal value is in the third one:
Internal:In other words, T(thermo)=output(thermo)*0.25+1.50 and T(int.)=(output(int.)-0.0025)/0.0625. Because the internal data is in fields 2:4 it's seen as e.g. 17b0 instead of 17b, so the decimal version needs to be divided by 16 (line 126 above).
23.63 17a 378 23.69 17b 379 23.94 17f 383 23.75 17c 380 21.88 15e 350 22.31 165 357 22.88 16e 366
Thermocouple: 23.75 05f 95 23.50 05e 9 38.25 099 153 24.00 066 102 87.50 15e 350 79.50 13e 318
I also set up an /etc/temper.conf file and did chown $USER /etc/temper.conf in order to be able to read it (must be a better way). I tried to calibrate the thermocouple in my kitchen with iced water and boiling water. The boiling water gave a reading of 102 degrees, while the iced water gave me 7.5 degrees Celsius even after what should've been long enough to achieve equilibrium. I'll calibrate it in the lab later. So for now a simple offset might be enough to give a working temperature.
temper-poll -pso temper.conf becameDevice #0 (bus 2 - port 2)
2-2: scale = 1.00, offset = -4.0