-
Notifications
You must be signed in to change notification settings - Fork 50
TEMPerV1.2
Interface type: HID
Common name: TEMPer
TEMPered status: works
USB IDs: 0C45:7401
Usable interface number: 1
Manufacturer string: RDing
Product string: TEMPerV1.2
Subtype ID: 1
Temperature sensors: 1 internal FM75
Humidity sensors: 0
This device has one internal temperature sensor, which appears to be an FM75 or compatible sensor chip.
This was the first device owned by me (EdorFaus), and hence was the first one to be supported, and sees the most testing during development.
I bought mine on DealExtreme, SKU 48285, where it was added on 2010-10-12 by OPURSTECH.
This is the type Cray's pcsensor program was written for.
To get the temperature, query with 01 80 33 01 00 00 00 00
.
A typical response is 80 02 1e f0 d4 cc 38 0b
, where the temperature is in the third and fourth byte, and the last 4 vary (especially the last 3 seem to change each time the device is plugged in).
To calculate the temperature, use the FM75 method; high byte is in offset 2, low byte in offset 3.
I have done some experimenting on this device type using the hid-query utility, sending more or less random data to the device and seeing what I get back, if anything. A lot of what I tried to send simply locks up the device, making me have to unplug it and plug it back in before it will respond to anything (even the known queries), but there are also quite a few queries that do provide responses.
Most of those that do respond do so with something like 01 80 01 cc d4 cc 38 0b
, where the last 4 are the same as for the temperature query - which seems to be some kind of error message. A few replace the cc with 55 - I don't know what that means, if anything.
I started by checking each of the nonzero bytes separately, starting at the fourth and moving towards the first, but got somewhat sidetracked before I checked anything other than 01 in the first byte. That is, I took the temperature query, and for each of the fourth, third and second byte, looped from 0x00 to 0xff and queried the device with that byte position replaced by the loop value.
I found that the fourth byte didn't seem to matter, as everything returned the same response as with it set to 01.
The third byte, however, did matter - I got the temperature only when it was 0x33, and otherwise got the error response mentioned above.
The second byte also mattered, and more severely so - values from 0x80 to 0x86 gave responses, while the rest locked up the device. 80 gave the temperature, obviously, while 81 to 86 gave an error response like the example above, except the second byte of the response matches the second byte of the query.
This is where I got a bit sidetracked, and ended up looping the third byte again, for each of the responding values I'd found for the second byte. As mentioned, most gave an error response, a few with 55 instead of cc - to be exact, 81 55
, 83 99
, 84 bb
and 85 dd
(which is suspiciously regular, especially when you include the non-error queries 80 33
, 82 77
and 86 ff
).
I ended up finding two queries other than the temperature one that seem like they might be useful. As it turns out, both of these were actually already known, being used by Cray's pcsensor program, which I believe was made by looking at dumps of the USB traffic caused by the Windows program that comes with the device.
Cray's pcsensor program uses these two queries to initialize the device before it starts reading the temperature data. TEMPered does not currently do this, as I didn't find it necessary when I wrote it, but we may want it to do so in the future - and I suspect that the first is an identification query more than initialization.
The first of these queries writes 01 82 77 01 00 00 00 00
, and gives e.g. 82 01 00 f0 d4 cc 38 0b
back, where only the first three bytes seem to be significant - the last four are the same as the temperature query, and the fourth byte seems to not change from whatever was last returned in that position (so if a temperature query was the last one sent, this still holds the low byte of the temperature).
This leads me to suspect that successful queries respond with 8n xx ....
where 8n is the second byte of the query, and xx is the number of significant bytes that follow, since xx is 02 for the temperature query and 01 for this one.
It also led me to suspect that the third byte here was an identification byte, similar to that of the 1130:660C devices, except that it's 00 - so I'd have to see what the other subtypes return for this query to confirm or deny that.
I've since been given the response to this query for a TEMPer2V1.3, which had the same 00 in the third byte, but another 00 in the fourth, and an 02 in the second. So, while it's apparently not the subtype ID, it's not clear what these bytes are actually for - possibly some kind of sensor type ID?
The second query, however, is quite different in what it returns. It writes 01 86 ff 01 00 00 00 00
, and gets two responses back - yes, not a double-length response, but two responses, that are read by issuing two calls to hid_read(). The same two responses are returned every time, at least for my devices:
54 45 4d 50 65 72 46 31
followed by
2e 32 4d 50 65 72 46 31
.
[ Note: In ASCII, the first 10 bytes of this read "TEMPerF1.2" ]
Not only that, but after this is called, the temperature query (and all the others) always return 65 72 46 31
in the last four bytes. This, combined with the randomness of those bytes before this is called, leads me to suspect that they are simply not initialized before this is called.
In other words, it seems that the device always responds with 8-byte blocks, but only sets those bytes that are actually used. If that holds true, this second query probably has a response that is 10 bytes long, since the last 6 bytes of the second response equal those in the first.
Now, earlier I said I suspected the first query to hold the subtype identification. It is also plausible that this query does that instead of the first one. Unfortunately, I have no way to tell, and wouldn't know which byte from this query to use as an ID, as it's not immediately obvious from the data for the types I have it for.