Skip to content

Instantly share code, notes, and snippets.

@jjeffery
Last active March 27, 2019 04:12
Show Gist options
  • Save jjeffery/0f35efb5aa98e0f161027e8092f851d8 to your computer and use it in GitHub Desktop.
Save jjeffery/0f35efb5aa98e0f161027e8092f851d8 to your computer and use it in GitHub Desktop.
Temper1 temperature sensor code
SUBSYSTEMS=="usb", ACTION=="add", ATTRS{idVendor}=="1130", ATTRS{idProduct}=="660c", MODE="666"
all: temper temperature.so
CFLAGS = -O2 -Wall
temper: temper.c
${CC} -DUNIT_TEST -o $@ $^ -lusb
temperature.so: temper.c
${CC} -o $@ $< -shared -fPIC -DPIC -I/home/temperature/src/ruby-1.8.7-p330 -lusb
clean:
rm -f temper *.o *.so
rules-install: # must be superuser to do this
cp 99-tempsensor.rules /etc/udev/rules.d
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <usb.h>
#include <errno.h>
/*
* 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 Robert Kavaler ''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 "temper.h"
#define VENDOR_ID 0x1130
#define PRODUCT_ID 0x660c
struct Temper {
struct usb_device *device;
usb_dev_handle *handle;
int debug;
int timeout;
};
Temper *
TemperCreate(struct usb_device *dev, int timeout, int debug)
{
Temper *t;
int ret;
t = calloc(1, sizeof(*t));
t->device = dev;
t->debug = debug;
t->timeout = timeout;
t->handle = usb_open(t->device);
if(!t->handle) {
free(t);
return NULL;
}
if(t->debug) {
printf("Trying to detach kernel driver\n");
}
ret = usb_detach_kernel_driver_np(t->handle, 0);
if(ret) {
if(errno == ENODATA) {
if(t->debug) {
printf("Device already detached\n");
}
} else {
if(t->debug) {
printf("Detach failed: %s[%d]\n",
strerror(errno), errno);
printf("Continuing anyway\n");
}
}
} else {
if(t->debug) {
printf("detach successful\n");
}
}
ret = usb_detach_kernel_driver_np(t->handle, 1);
if(ret) {
if(errno == ENODATA) {
if(t->debug)
printf("Device already detached\n");
} else {
if(t->debug) {
printf("Detach failed: %s[%d]\n",
strerror(errno), errno);
printf("Continuing anyway\n");
}
}
} else {
if(t->debug) {
printf("detach successful\n");
}
}
if(usb_set_configuration(t->handle, 1) < 0 ||
usb_claim_interface(t->handle, 0) < 0 ||
usb_claim_interface(t->handle, 1)) {
usb_close(t->handle);
free(t);
return NULL;
}
return t;
}
Temper *
TemperCreateFromDeviceNumber(int deviceNum, int timeout, int debug)
{
struct usb_bus *bus;
int n;
n = 0;
for(bus=usb_get_busses(); bus; bus=bus->next) {
struct usb_device *dev;
for(dev=bus->devices; dev; dev=dev->next) {
if(debug) {
printf("Found device: %04x:%04x\n",
dev->descriptor.idVendor,
dev->descriptor.idProduct);
}
if(dev->descriptor.idVendor == VENDOR_ID &&
dev->descriptor.idProduct == PRODUCT_ID) {
if(debug) {
printf("Found deviceNum %d\n", n);
}
if(n == deviceNum) {
return TemperCreate(dev, timeout, debug);
}
n++;
}
}
}
return NULL;
}
void
TemperFree(Temper *t)
{
if(t) {
if(t->handle) {
usb_close(t->handle);
}
free(t);
}
}
static int
TemperSendCommand(Temper *t, int a, int b, int c, int d, int e, int f, int g, int h)
{
unsigned char buf[32];
int ret;
bzero(buf, 32);
buf[0] = a;
buf[1] = b;
buf[2] = c;
buf[3] = d;
buf[4] = e;
buf[5] = f;
buf[6] = g;
buf[7] = h;
if(t->debug) {
printf("sending bytes %d, %d, %d, %d, %d, %d, %d, %d\n",
a, b, c, d, e, f, g, h);
}
ret = usb_control_msg(t->handle, 0x21, 9, 0x200, 0x01,
(char *) buf, 32, t->timeout);
if(ret != 32) {
perror("usb_control_msg failed");
return -1;
}
return 0;
}
static int
TemperGetData(Temper *t, char *buf, int len)
{
int ret;
return usb_control_msg(t->handle, 0xa1, 1, 0x300, 0x01,
(char *) buf, len, t->timeout);
}
int
TemperGetTemperatureInC(Temper *t, float *tempC)
{
char buf[256];
int ret, temperature, i;
TemperSendCommand(t, 10, 11, 12, 13, 0, 0, 2, 0);
TemperSendCommand(t, 0x54, 0, 0, 0, 0, 0, 0, 0);
for(i = 0; i < 7; i++) {
TemperSendCommand(t, 0, 0, 0, 0, 0, 0, 0, 0);
}
TemperSendCommand(t, 10, 11, 12, 13, 0, 0, 1, 0);
ret = TemperGetData(t, buf, 256);
if(ret < 2) {
return -1;
}
temperature = (buf[1] & 0xFF) + (buf[0] << 8);
temperature += 640;//1152; // calibration value
*tempC = temperature * (125.0 / 32000.0);
return 0;
}
int
TemperGetOtherStuff(Temper *t, char *buf, int length)
{
TemperSendCommand(t, 10, 11, 12, 13, 0, 0, 2, 0);
TemperSendCommand(t, 0x52, 0, 0, 0, 0, 0, 0, 0);
TemperSendCommand(t, 10, 11, 12, 13, 0, 0, 1, 0);
return TemperGetData(t, buf, length);
}
#ifdef UNIT_TEST
#define USB_TIMEOUT 1000 /* milliseconds */
int
main(void)
{
Temper *t;
char buf[256];
int i, ret;
usb_set_debug(0);
usb_init();
usb_find_busses();
usb_find_devices();
t = TemperCreateFromDeviceNumber(0, USB_TIMEOUT, 0);
if(!t) {
perror("TemperCreate");
exit(-1);
}
/*
TemperSendCommand(t, 10, 11, 12, 13, 0, 0, 2, 0);
TemperSendCommand(t, 0x43, 0, 0, 0, 0, 0, 0, 0);
TemperSendCommand(t, 0, 0, 0, 0, 0, 0, 0, 0);
TemperSendCommand(t, 0, 0, 0, 0, 0, 0, 0, 0);
TemperSendCommand(t, 0, 0, 0, 0, 0, 0, 0, 0);
TemperSendCommand(t, 0, 0, 0, 0, 0, 0, 0, 0);
TemperSendCommand(t, 0, 0, 0, 0, 0, 0, 0, 0);
TemperSendCommand(t, 0, 0, 0, 0, 0, 0, 0, 0);
*/
bzero(buf, 256);
ret = TemperGetOtherStuff(t, buf, 256);
float tempc;
if(TemperGetTemperatureInC(t, &tempc) < 0) {
perror("TemperGetTemperatureInC");
exit(1);
}
printf("%.2f\n", tempc);
return 0;
}
#else
#include <ruby.h>
#define USB_TIMEOUT 1000 /* milliseconds */
VALUE get_temperature_value(VALUE class);
void Init_temperature() {
VALUE Temper;
Temper = rb_define_class("Temper", rb_cObject);
rb_define_singleton_method(Temper, "temperature", get_temperature_value, 0);
}
VALUE get_temperature_value(VALUE class) {
Temper *t;
char buf[256];
int i, ret;
usb_set_debug(0);
usb_init();
usb_find_busses();
usb_find_devices();
t = TemperCreateFromDeviceNumber(0, USB_TIMEOUT, 0);
if(!t) {
perror("TemperCreate");
exit(-1);
}
bzero(buf, 256);
ret = TemperGetOtherStuff(t, buf, 256);
float tempc;
if(TemperGetTemperatureInC(t, &tempc) < 0) {
perror("TemperGetTemperatureInC");
exit(1);
}
return rb_float_new(tempc);
}
#endif
#ifndef TEMPER_H
#define TEMPER_H
/*
* Temper.h 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 Robert Kavaler ''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.
*
*/
typedef struct Temper Temper;
Temper *TemperCreateFromDeviceNumber(int deviceNum, int timeout, int debug);
void TemperFree(Temper *t);
int TemperGetTemperatureInC(Temper *t, float *tempC);
int TempterGetOtherStuff(Temper *t, char *buf, int length);
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment