From bd726e009516ddedfb8adf5511c211f99cc8ec67 Mon Sep 17 00:00:00 2001 From: jim Date: Tue, 21 Jul 2009 22:15:33 +0000 Subject: [PATCH] some cleanups to the read utility git-svn-id: https://bucket.mit.edu/svn/nilm/zoom@7699 ddd99763-3ecb-0310-9145-efcb8ce7c51f --- pc/process/calibtest.m | 37 ++++++++++ pc/read.c | 152 ++++++++++++++++++++--------------------- 2 files changed, 110 insertions(+), 79 deletions(-) create mode 100644 pc/process/calibtest.m diff --git a/pc/process/calibtest.m b/pc/process/calibtest.m new file mode 100644 index 0000000..94319d8 --- /dev/null +++ b/pc/process/calibtest.m @@ -0,0 +1,37 @@ +if (length(who("calibdata")) == 0) + calibdata = load("../calibrate-25-second.log"); +endif +if (length(who("a")) == 0) + for i = 1 : (length(calibdata) / 4000) + block=1:4000; + a(i, block, 1) = calibdata((i-1) * 4000 + block, 2); + a(i, block, 2) = calibdata((i-1) * 4000 + block, 3); + a(i, block, 3) = calibdata((i-1) * 4000 + block, 1); + endfor +endif +clf; +figure(1); +hold on +#for i = 1:100 +# x(i) = a(i, 2000, 1); +# y(i) = a(i, 2000, 3); +#endfor +#plot(x, [diff(y) 0]); + + + +for i = 50 : 50 + unclamped = 1000:3000; + unclamped = 1:4000; + + x = a(i, unclamped, 1); + y = a(i, unclamped, 2); + + filterlen = 1; + y = filter(ones(1,filterlen)/filterlen,1,y); + + # y = [ diff(y) 0 ]; + plot(x(filterlen:(length(x)-1)), y(filterlen:(length(y)-1))); + endfor + + diff --git a/pc/read.c b/pc/read.c index 78f3cf9..c3f58e8 100644 --- a/pc/read.c +++ b/pc/read.c @@ -15,7 +15,6 @@ int hex = 0; int dec = 0; int screen = 0; int unprocessed = 0; -int total = 0; int process(const uint8_t *buf, int len); @@ -27,15 +26,16 @@ int main(int argc, char *argv[]) int getopt_index; char buf[1024]; int len; + int calibrate = 1; static struct option long_opts[] = { { "device", required_argument, NULL, 'd' }, { "rate", required_argument, NULL, 'r' }, { "hex", no_argument, NULL, 'x' }, { "dec", no_argument, NULL, 'D' }, - { "total", no_argument, NULL, 't' }, { "raw", no_argument, NULL, 'R' }, { "unprocessed", no_argument, NULL, 'u' }, + { "no-calibrate", no_argument, NULL, 'n' }, { "screen", no_argument, NULL, 's' }, { "help", no_argument, NULL, 'h' }, { 0, 0, 0, 0 } @@ -43,7 +43,7 @@ int main(int argc, char *argv[]) int help=0; char c; - while ((c = getopt_long(argc, argv, "d:r:xDutsh?", + while ((c = getopt_long(argc, argv, "d:r:xDunsh?", long_opts, &getopt_index)) != -1) { switch(c) { @@ -62,12 +62,12 @@ int main(int argc, char *argv[]) case 'D': dec = 1; break; - case 't': - total = 1; - break; case 'u': unprocessed = 1; break; + case 'n': + calibrate = 0; + break; case 's': screen = 1; break; @@ -86,8 +86,8 @@ int main(int argc, char *argv[]) fprintf(stderr, " -r, --rate %-16d baud rate\n", rate); fprintf(stderr, " -x, --hex hex out\n"); fprintf(stderr, " -u, --unprocessed dump raw unprocessed data\n"); + fprintf(stderr, " -n, --no-calibrate skip calibration routine\n"); fprintf(stderr, " -s, --screen send \\r instead of \\n\n"); - fprintf(stderr, " -t, --total just display total amps\n"); fprintf(stderr, " -h, --help this cruft\n"); return 1; } @@ -95,6 +95,11 @@ int main(int argc, char *argv[]) if ((fd = serial_open(device, rate)) == -1) err(1, "serial_open failed for %s", device); + if (calibrate) { + char c = 'c'; + write(fd, &c, 1); + } + len = 0; while (1) { int processed, n; @@ -110,49 +115,64 @@ int main(int argc, char *argv[]) return 1; } -uint16_t current_to_dac(float amps) +int process_adc_dac(const uint8_t *buf) { - float tmp; - uint16_t dacc; + uint16_t dac, tmp; + int16_t adc; + int overflow; + + /* data OK? */ + if ((buf[0] & 0xC0) != 0) + return 0; - tmp = 536.0 / 1.0 * amps + 32524; - if (tmp < 0) - tmp = 0; - if (tmp > 65535) - tmp = 65535; - dacc = (uint16_t)(tmp + 0.5); + /* extract */ + + if (buf[0] & 0x10) + overflow = 1; + else + overflow = 0; + + tmp = ((buf[0] & 0x0F) << 8) | buf[1]; + /* sign-extend ADC value */ + if (tmp & 0x0800) + tmp |= 0xF000; + else + tmp &= ~0xF000; + adc = (int16_t)tmp; + + dac = (buf[2] << 8) | buf[3]; + + /* send it out */ + if (hex) { + printf("%04x %03x", dac, adc & 0x0FFF); + } else if (dec) { + printf("%d %d", dac, adc & 0x0FFF); + } else { + printf("DAC: %5d ADC: % 5d Total: xxx", dac, adc); + if (overflow) + printf(" **** adc may have clamped"); + } + + if (screen) + printf("\033[K\r"); + else + printf("\n"); - return dacc; + return 1; } -/* Convert the DAC output value to an effective current in the measuring loop */ -float dac_to_current(uint16_t dacv) +int process_calibration(const uint8_t *buf) { - float amps; - amps = ((float)dacv - 32524.0) * 1.0 / 536.0; - return amps; -} + float f = *(float *)buf; -float adc12_to_current(int16_t picv) -{ - float amps; + printf("got calibration value: %f\n", f); - if (picv < 0) - picv = 0; - if (picv > 2047) - picv = 2047; - - amps = (picv - 1024.0) / 404.0; - return amps; + return 1; } int process(const uint8_t *buf, int len) { int n = 0; - uint16_t dac, tmp; - int16_t adc; - float idac = dac_to_current(dac); - float iadc = adc12_to_current(adc); if (unprocessed) { n = write(fileno(stdout), buf, len); @@ -163,52 +183,26 @@ int process(const uint8_t *buf, int len) /* Process blocks */ retry: - for (; (n + 4) <= len; buf += 4, n += 4) { - if ((!buf[0] & 0x80) || - (buf[1] & 0x80) || - (buf[2] & 0x80) || - (buf[3] & 0x80)) { - /* badly formed data, eat one byte and retry */ + for (; (n + 5) <= len; buf += 5, n += 5) { + int ok = 0; + switch (buf[0]) { + case 0xA0: + if (process_adc_dac(buf + 1)) ok = 1; + break; + case 0xA1: + if (process_calibration(buf + 1)) ok = 1; + break; + default: + break; + } + if (!ok) { + /* badly formed data; eat one byte and retry */ buf++; n++; goto retry; } - - tmp = ((buf[0] & 0x7f) << 5) | - ((buf[1] & 0x7c) >> 2); - dac = ((buf[1] & 0x03) << 14) | - (buf[2] << 7) | buf[3]; - - /* sign-extend ADC value */ - if (tmp & 0x0800) - tmp |= 0xF000; - else - tmp &= ~0xF000; - adc = (int16_t)tmp; - - /* compute floating-point currents */ - idac = dac_to_current(dac); - iadc = adc12_to_current(adc); - - /* send it out */ - if (hex) { - printf("%04x %03x", dac, adc & 0x0FFF); - } else if (dec) { - printf("%d %d", dac, adc & 0x0FFF); - } else if (total) { - printf("%.6f", idac - iadc); - } else { - printf("DAC: %5d (% f) ADC: % 5d (% f) Total: % 10.6f amps", - dac, idac, (int16_t)adc, iadc, idac - iadc); - - if (adc < 0 || adc >= 2047) - printf(" **** adc limit"); - } - - if (screen) - printf("\033[K\r"); - else - printf("\n"); } + return n; } +