#include #include #include #include #include #include #include #include #include #include /* * Scale interface * * Simon Kirby, 2013-02-14 Capacity (kg) 5 Outline Size (mm) 130X30X22 Non-Linearity (%FS) 0.017 Hysteresis, Non-Repeatability (%FS) 0.01 Creep (%FS/30min) 0.015 Temperature effect on span (%FS/10C) 0.014 Temperature effect on zero (%FS/10C) 0.017 Temperature, compensated(C) -10-to +40 Temperature, operation(C) -35 to +65 Safe Overload(%FS) 150 Ultimate Overload(%FS) 300 Protection Class IP65 Cable Length (m) 1.5 */ char *dev = "/dev/hidraw1"; void usage_exit(void) { fprintf(stderr, "usage: tmc []\n"); exit(1); } #define BUFSIZE 4096 unsigned char buf[BUFSIZE]; int main(int argc, char *argv[]) { const char *f; ssize_t r; int fd; int input; double grams = 0, tare = 0; double k = 0; double x = 0; double p = 1; long o = 0; if (argc > 1) f = argv[1]; else f = dev; fd = open(f, O_RDONLY | O_APPEND); if (fd == -1) { fprintf(stderr, "open(%s): %s\n", f, strerror(errno)); exit(1); } for (;;) { r = read(fd, buf, 8); if (r == -1) { perror("read"); break; } else if (r == 0) { break; } else if (r != 8) { fprintf(stderr, "read() returned %zi?\n", r); break; } if (buf[0] != 3) { fprintf(stderr, "First byte is %u instead of 3", buf[0]); break; } if (buf[1] != 4) { fprintf(stderr, "Second byte is %u instead of 4", buf[1]); break; } input = (buf[4] << 16) | (buf[5] << 8) | buf[6]; /* * Calibration 2013-02-14 with 245.7g powerball * 245.7 / (8609030 - 8375600) */ // grams = input * .00105256393779719830; /* * Calibration 2013-02-18 with 48.68g lipo */ grams = input * .00105040616014693754; if (!x) { x = grams; } else { k = p / (p + .2); // Compute Kalman gain x+= k * (grams - x); // Update estimate // p*= 1 - k; // Update error covariance k = grams > x ? grams - x : x - grams; p = (1 - p) * p + (p * (k / (k + 10))); } if (++o == 160) tare = x; fprintf(stderr, "\rScale (%i): grams: %8.2fg x: %8.2fg k: %7.2f p: %7.4f\033[K", buf[2], grams - tare, x - tare, k, p); } close(fd); return 1; }