From 89eede04c885cd6717e8a6ec1712f9a59cd616ff Mon Sep 17 00:00:00 2001 From: Eric Jiang Date: Sun, 13 Feb 2011 21:53:57 -0500 Subject: [PATCH] Working! with print formatting and everything! --- usbscale.c | 163 ++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 137 insertions(+), 26 deletions(-) diff --git a/usbscale.c b/usbscale.c index d029aeb..e6844a9 100644 --- a/usbscale.c +++ b/usbscale.c @@ -1,21 +1,36 @@ #include #include +#include +#include #include #include "scales.h" -#define DEBUG 1 +//#define DEBUG /* * These constants are from libhid/include/constants.h * and usage based on libhid/src/hid_exchange.c * also vvvoutput.txt */ -#define HID_REPORT_GET 0x01 -#define HID_RT_INPUT 0x01 -#define WEIGH_REPORT_ID 0x06 // Scale Data Report ID #define WEIGH_REPORT_SIZE 0x06 static libusb_device* find_scale(libusb_device**); +static int print_scale_data(char*); +const char* UNITS[13] = { + "units", // unknown unit + "mg", // milligram + "g", // gram + "kg", // kilogram + "cd", // carat + "taels", // lian + "gr", // grain + "dwt", // pennyweight + "tonnes", // metric tons + "tons", // avoir ton + "ozt", // troy ounce + "oz", // ounce + "lbs" // pound +}; int main(void) { @@ -50,29 +65,48 @@ int main(void) #endif libusb_claim_interface(handle, 0); + + /* * Try to transfer data about status * - * http://www.beyondlogic.org/usbnutshell/usb6.shtml - * test_libhid.c + * http://rowsandcolumns.blogspot.com/2011/02/read-from-magtek-card-swipe-reader-in.html */ unsigned char data[WEIGH_REPORT_SIZE]; unsigned int len; - unsigned int res = libusb_interrupt_transfer( - handle, - //bmRequestType => direction: in, type: class, - // recipient: interface - LIBUSB_ENDPOINT_IN | //LIBUSB_REQUEST_TYPE_CLASS | - LIBUSB_RECIPIENT_INTERFACE, - data, - WEIGH_REPORT_SIZE, // length of data - &len, - 10000 //timeout => 10 sec - ); - int i; - printf("Got %d bytes from control transfer:\n", len); - for(i = 0; i < WEIGH_REPORT_SIZE; i++) { - printf("%x\n", data[i]); + unsigned int res; + int continue_reading = 0; + int scale_result = -1; + + for(;;) { + res= libusb_interrupt_transfer( + handle, + //bmRequestType => direction: in, type: class, + // recipient: interface + LIBUSB_ENDPOINT_IN | //LIBUSB_REQUEST_TYPE_CLASS | + LIBUSB_RECIPIENT_INTERFACE, + data, + WEIGH_REPORT_SIZE, // length of data + &len, + 10000 //timeout => 10 sec + ); + + if(res == 0) { +#ifdef DEBUG + int i; + for(i = 0; i < WEIGH_REPORT_SIZE; i++) { + printf("%x\n", data[i]); + } +#endif + scale_result = print_scale_data(data); + if(scale_result != 1) + break; + } + else { + fprintf(stderr, "Error in USB transfer\n"); + scale_result = -1; + break; + } } @@ -86,13 +120,87 @@ int main(void) libusb_close(handle); libusb_free_device_list(devs, 1); libusb_exit(NULL); - return 0; + + return scale_result; +} + +// +// print_scale_data +// ---------------- +// +// **print_scale_data** takes the 6 bytes of binary data sent by the scale and +// interprets and prints it out. +// +// **Returns:** `0` if weight data was successfully read, `1` if the data +// indicates that more data needs to be read (i.e. keep looping), and `-1` if +// the scale data indicates that some error occurred and that the program +// should terminate. +// +static int print_scale_data(char* dat) { + + static uint8_t lastStatus = 0; + + uint8_t report = dat[0]; + uint8_t status = dat[1]; + uint8_t unit = dat[2]; + uint8_t expt = dat[3]; + long weight = dat[4] + (dat[5] << 8); + + if(expt != 255 && expt != 0) { + weight = pow(weight, expt); + } + + if(report != 0x03) { + fprintf(stderr, "Error reading scale data\n"); + return -1; + } + + switch(status) { + case 0x01: + fprintf(stderr, "Scale reports Fault\n"); + return -1; + case 0x02: + if(status != lastStatus) + fprintf(stderr, "Scale is zero'd...\n"); + break; + case 0x03: + if(status != lastStatus) + fprintf(stderr, "Weighing...\n"); + break; + case 0x04: + printf("%ld %s\n", weight, UNITS[unit]); + return 0; + case 0x05: + if(status != lastStatus) + fprintf(stderr, "Scale reports Under Zero\n"); + break; + case 0x06: + if(status != lastStatus) + fprintf(stderr, "Scale reports Over Weight\n"); + break; + case 0x07: + if(status != lastStatus) + fprintf(stderr, "Scale reports Calibration Needed\n"); + break; + case 0x08: + if(status != lastStatus) + fprintf(stderr, "Scale reports Re-zeroing Needed!\n"); + break; + default: + if(status != lastStatus) + fprintf(stderr, "Unknown status code: %d\n", status); + return -1; + } + + lastStatus = status; + return 1; } static libusb_device* find_scale(libusb_device **devs) { - if(DEBUG) +#ifdef DEBUG libusb_set_debug(NULL, 3); +#endif int i = 0; libusb_device* dev; @@ -117,13 +225,15 @@ static libusb_device* find_scale(libusb_device **devs) */ #ifdef DEBUG - printf("Found scale %04x:%04x (bus %d, device %d)\n", + fprintf(stderr, + "Found scale %04x:%04x (bus %d, device %d)\n", desc.idVendor, desc.idProduct, libusb_get_bus_number(dev), libusb_get_device_address(dev)); - printf("It has descriptors:\n\tmanufc: %d\n\tprodct: %d\n\tserial: %d\n\tclass: %d\n\tsubclass: %d\n", + fprintf(stderr, + "It has descriptors:\n\tmanufc: %d\n\tprodct: %d\n\tserial: %d\n\tclass: %d\n\tsubclass: %d\n", desc.iManufacturer, desc.iProduct, desc.iSerialNumber, @@ -139,7 +249,8 @@ static libusb_device* find_scale(libusb_device **devs) r = libusb_get_string_descriptor_ascii(hand, desc.iManufacturer, string, 256); - printf("Manufacturer: %s\n", string); + fprintf(stderr, + "Manufacturer: %s\n", string); libusb_close(hand); #endif return dev;