I bought myself a couple of temper USB sensors from [[http://dx.com/p/temper-usb-thermometer-temperature-recorder-for-pc-laptop-81105?item=2|DX]] and found pcsensor.c which could read from the device. I bought 2 and had 2 more on the way, but the code only supported 1 device. Fortunately the code was open source, so I slightly modified it. Use -d to specify a device. Examples: * device0: ./pcsensor -c -d0 -l1 * device1: ./pcsensor -c -d1 -l1 Thanks to the people who made this code. __WARNING: Only tested with temper 1.2__ Here's the code with my modifications: /* * pcsensor.c by Juan Carlos Perez (c) 2011 (cray@isp-sl.com) * based on Temper.c by Robert Kavaler (c) 2009 (relavak.com) * All rights reserved. * * Temper driver for linux. This program can be compiled either as a library * or as a standalone program (-DUNIT_TEST). The driver will work with some * TEMPer usb devices from RDing (www.PCsensor.com). * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * THIS SOFTWARE IS PROVIDED BY Juan Carlos Perez ''AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL Robert kavaler BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #include #include #include #include #include #include #define VERSION "1.0.0" #define VENDOR_ID 0x0c45 #define PRODUCT_ID 0x7401 #define INTERFACE1 0x00 #define INTERFACE2 0x01 const static int reqIntLen=8; const static int reqBulkLen=8; const static int endpoint_Int_in=0x82; /* endpoint 0x81 address for IN */ const static int endpoint_Int_out=0x00; /* endpoint 1 address for OUT */ const static int endpoint_Bulk_in=0x82; /* endpoint 0x81 address for IN */ const static int endpoint_Bulk_out=0x00; /* endpoint 1 address for OUT */ const static int timeout=5000; /* timeout in ms */ const static char uTemperatura[] = { 0x01, 0x80, 0x33, 0x01, 0x00, 0x00, 0x00, 0x00 }; const static char uIni1[] = { 0x01, 0x82, 0x77, 0x01, 0x00, 0x00, 0x00, 0x00 }; const static char uIni2[] = { 0x01, 0x86, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00 }; static int bsalir=1; static int debug=0; static int devid=0; static int seconds=5; static int formato=0; static int mrtg=0; static int calibration=0; void bad(const char *why) { fprintf(stderr,"Fatal error> %s\n",why); exit(17); } usb_dev_handle *find_lvr_winusb(); void usb_detach(usb_dev_handle *lvr_winusb, int iInterface) { int ret; ret = usb_detach_kernel_driver_np(lvr_winusb, iInterface); if(ret) { if(errno == ENODATA) { if(debug) { printf("Device already detached\n"); } } else { if(debug) { printf("Detach failed: %s[%d]\n", strerror(errno), errno); printf("Continuing anyway\n"); } } } else { if(debug) { printf("detach successful\n"); } } } usb_dev_handle* setup_libusb_access() { usb_dev_handle *lvr_winusb; if(debug) { usb_set_debug(255); } else { usb_set_debug(0); } usb_init(); usb_find_busses(); usb_find_devices(); if(!(lvr_winusb = find_lvr_winusb())) { printf("Couldn't find the USB device, Exiting\n"); return NULL; } usb_detach(lvr_winusb, INTERFACE1); usb_detach(lvr_winusb, INTERFACE2); if (usb_set_configuration(lvr_winusb, 0x01) < 0) { printf("Could not set configuration 1\n"); return NULL; } // Microdia tiene 2 interfaces if (usb_claim_interface(lvr_winusb, INTERFACE1) < 0) { printf("Could not claim interface\n"); return NULL; } if (usb_claim_interface(lvr_winusb, INTERFACE2) < 0) { printf("Could not claim interface\n"); return NULL; } return lvr_winusb; } usb_dev_handle *find_lvr_winusb() { int loopval = 0; struct usb_bus *bus; struct usb_device *dev; for (bus = usb_busses; bus; bus = bus->next) { for (dev = bus->devices; dev; dev = dev->next) { if (dev->descriptor.idVendor == VENDOR_ID && dev->descriptor.idProduct == PRODUCT_ID ) { usb_dev_handle *handle; if (loopval != devid) { loopval++; if (debug) { printf("Increased loopval - loopval: %i - devid: %i\n", loopval, devid); } } else { if(debug) { printf("lvr_winusb with Vendor Id: %x and Product Id: %x found.\n", VENDOR_ID, PRODUCT_ID); } if (!(handle = usb_open(dev))) { printf("Could not open USB device\n"); return NULL; } return handle; } } } } return NULL; } void ini_control_transfer(usb_dev_handle *dev) { int r,i; char question[] = { 0x01,0x01 }; r = usb_control_msg(dev, 0x21, 0x09, 0x0201, 0x00, (char *) question, 2, timeout); if( r < 0 ) { perror("USB control write"); bad("USB write failed"); } if(debug) { for (i=0;itm_hour, local->tm_min); printf("pcsensor\n"); } else { printf("%04d/%02d/%02d %02d:%02d:%02d ", local->tm_year +1900, local->tm_mon + 1, local->tm_mday, local->tm_hour, local->tm_min, local->tm_sec); if (formato==2) { printf("Temperature %.2fF\n", (9.0 / 5.0 * tempc + 32.0)); } else if (formato==1) { printf("Temperature %.2fC\n", tempc); } else { printf("Temperature %.2fF %.2fC\n", (9.0 / 5.0 * tempc + 32.0), tempc); } } if (!bsalir) sleep(seconds); } while (!bsalir); usb_release_interface(lvr_winusb, INTERFACE1); usb_release_interface(lvr_winusb, INTERFACE2); usb_close(lvr_winusb); return 0; }