-
-
Notifications
You must be signed in to change notification settings - Fork 10
/
usbscale.c
85 lines (73 loc) · 2.07 KB
/
usbscale.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
/*
* Simple standard USB scale reading program.
*
* Copyright (c) 2015 Alexey Kopytko
* Released under the MIT license.
*/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#if defined(__APPLE__) && defined(__MACH__)
#include <machine/endian.h>
#include <libkern/OSByteOrder.h>
#define le16toh(x) OSSwapLittleToHostInt16(x)
#else
#include <endian.h>
#endif
#include "usbscale.h"
const char* unitAbbrev[] = {"unknown", "mg", "g", "kg", "cd", "taels", "gr", "dwt", "tonnes", "tons", "ozt", "oz", "lbs"};
struct data {
enum report report;
enum status status;
enum unit unit;
signed char exponent;
unsigned short raw_weight; // 16 bit, little endian
float weight;
};
int main(int argc, char** argv)
{
if (argc < 2) {
fprintf(stderr, "Usage: %s /dev/hidrawX\n", argv[0]);
return 1;
}
FILE* fp = fopen(argv[1], "rb");
if (fp == NULL) {
fprintf(stderr, "Unable to open %s\n", argv[1]);
return 1;
}
unsigned char buffer[6] = {0};
fread(buffer, 1, sizeof(buffer), fp);
fclose(fp);
#ifdef DEBUG
for (int i = 0; i < sizeof(buffer); i += 1) {
printf("byte %i = %x\n", i, buffer[i]);
}
#endif
struct data result;
result.report = buffer[0];
result.status = buffer[1];
result.unit = buffer[2];
result.exponent = buffer[3];
// shall be little endian
result.raw_weight = le16toh(buffer[5] << 8 | buffer[4]);
#ifdef DEBUG
printf("report = %i\n", result.report);
printf("status = %i\n", result.status);
printf("unit = %i\n", result.unit);
printf("exponent = %i\n", result.exponent);
printf("raw weight = %i\n", result.raw_weight);
#endif
// Scale Data Report and Positive Weight Status
if (result.report == DATA && result.status == POSITIVE) {
// ...the scaling applied to the data as a base ten exponent
result.weight = result.raw_weight * pow(10, result.exponent);
if (result.unit == OUNCE) {
// convert ounces to grams
result.weight *= 28.349523125;
// and change unit to grams
result.unit = GRAM;
}
printf("%.2f %s\n", result.weight, unitAbbrev[result.unit]);
}
return 0;
}