Browse Source

cleanup

git-svn-id: https://bucket.mit.edu/svn/nilm/zoom@7987 ddd99763-3ecb-0310-9145-efcb8ce7c51f
tags/zoom-1.0
jim 12 years ago
parent
commit
e9530e6b1e
2 changed files with 167 additions and 28 deletions
  1. +161
    -28
      pc/dctest.c
  2. +6
    -0
      pc/test.txt

+ 161
- 28
pc/dctest.c View File

@@ -15,13 +15,14 @@
#include "zoom.h"
#include "math.h"
#include <pthread.h>
#include <ctype.h>

#define info(x...) fprintf(stderr,x)

void dctest(int zoom, int gpib);
static void dctest(int zoom, int gpib);

int g_quit = 0;
void handle_sig(int sig) { g_quit = 1; }
static void handle_sig(int sig) { g_quit = 1; }

int main(int argc, char *argv[])
{
@@ -95,72 +96,204 @@ int main(int argc, char *argv[])
return 0;
}

struct keithley_t {
pthread_mutex_t mutex;
double desired;
double actual;
int stable;
};

struct threadinfo_t {
int quit_flag;
int fd;
float calibration;
struct keithley_t k;
};

void *read_data(void *arg)
int process_adc_dac(const uint8_t *buf, struct threadinfo_t *ti)
{
uint16_t dac, tmp;
int16_t adc;
int overflow;
double idesired, iactual;
int stable;

/* data OK? */
if ((buf[0] & 0xC0) != 0) return 0;

/* extract */
overflow = (buf[0] & 0x10) ? 1 : 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];

/* get keithley data */
pthread_mutex_lock(&ti->k.mutex);
idesired = ti->k.desired;
iactual = ti->k.actual;
stable = ti->k.stable;
pthread_mutex_unlock(&ti->k.mutex);

/* write it out */
printf("%d %.8f %.8f %.8f %5d %5d %d\n",
stable,
idesired,
iactual,
ti->calibration,
dac,
adc,
overflow);

return 1;
}

static int process_calibration(const uint8_t *buf, struct threadinfo_t *ti)
{
float f = *(float *)buf;
ti->calibration = f;
info("new calibration value: %.8f\n", ti->calibration);
return 1;
}

static int process(const uint8_t *buf, int len, struct threadinfo_t *ti)
{
int n = 0;

/* Process blocks */
retry:
for (; (n + 5) <= len; buf += 5, n += 5) {
int ok = 0;
switch (buf[0]) {
case 0xA0:
if (process_adc_dac(buf + 1, ti)) ok = 1;
break;
case 0xA1:
if (process_calibration(buf + 1, ti)) ok = 1;
break;
default:
break;
}
if (!ok) {
/* badly formed data; eat one byte and retry */
info("throwing away 0x%02x '%c'\n", buf[0], isprint(buf[0]) ? buf[0] : '.');
buf++;
n++;
goto retry;
}
}

return n;
}

static void *read_data(void *arg)
{
struct threadinfo_t *ti = (struct threadinfo_t *)arg;
char buf[1024];
int len;

printf("ti->fd=%d\n", ti->fd);
/* read data in a loop. Use saferead_timeout here so we can
notice quit_flag before too long. */
len = 0;
while (!ti->quit_flag) {
printf("thread sleeping\n");
sleep(1);
int processed, n;
n = saferead_timeout(ti->fd,
buf + len,
sizeof(buf) - len,
1000);
if (n < 0)
err(1, "read");
if (n == 0)
continue;
len += n;
processed = process((uint8_t *) buf, len, ti);
memmove(buf, buf + processed, len - processed);
len -= processed;
}
printf("thread quitting\n");
info("read thread quitting\n");
return NULL;
}

void dctest(int zoom, int gpib)
/* change keithley and update keithley_t structure with locking */
static int keithley_change(int gpib, double desired, struct keithley_t *k)
{
double actual;

pthread_mutex_lock(&k->mutex);
k->stable = 0;
k->desired = desired;
pthread_mutex_unlock(&k->mutex);

if (keithley_current(gpib, desired) < 0)
return -1;

actual = keithley_read(gpib);
if (isnan(actual))
return -1;

pthread_mutex_lock(&k->mutex);
k->actual = actual;
pthread_mutex_unlock(&k->mutex);
return 0;
}

static void dctest(int zoom, int gpib)
{
// double idesired, iactual;
// int i;
// int zero;
// int dac[ZOOM_SWEEP_COUNT];
// int adc[ZOOM_SWEEP_COUNT];
pthread_t thread;
struct threadinfo_t threadinfo;
struct threadinfo_t ti;
/* Do a calibration with Keithley off */
info("Triggering calibration\n");
zoomrun_trigger_calibrate(zoom);
usleep(500000);
usleep(1000000);

printf("zoom=%d gpib=%d\n", zoom,gpib);
/* Init Keithley */
info("Initializing GPIB\n");
// if (gpib_init(gpib) < 0) { info("failed\n"); goto out1; }
if (gpib_init(gpib) < 0) { info("failed\n"); goto out1; }
info("Initializing Keithley\n");
// if (gpib_addr(gpib, 24) < 0) { info("failed\n"); goto out1; }
// if (keithley_init(gpib) < 0) { info("failed\n"); goto out2; }
// if (keithley_current(gpib, 0) < 0) { info("failed\n"); goto out2; }
// if (isnan(keithley_read(gpib))) { info("failed\n"); goto out2; }
if (gpib_addr(gpib, 24) < 0) { info("failed\n"); goto out1; }
if (keithley_init(gpib) < 0) { info("failed\n"); goto out2; }
if (keithley_current(gpib, 0) < 0) { info("failed\n"); goto out2; }
if (isnan(keithley_read(gpib))) { info("failed\n"); goto out2; }

/* Start the thread that reads and dumps data */
info("Spawning thread\n");
threadinfo.quit_flag = 0;
threadinfo.fd = zoom;
if (pthread_create(&thread, NULL, read_data, &threadinfo) != 0) {
if (pthread_mutex_init(&ti.k.mutex, NULL) != 0) {
info("failed\n");
goto out2;
}
ti.calibration = 1.0;
ti.k.desired = 0;
ti.k.actual = 0;
ti.k.stable = 0;
ti.quit_flag = 0;
ti.fd = zoom;
if (pthread_create(&thread, NULL, read_data, &ti) != 0) {
info("failed\n");
goto out2;
}

/* Do another calibration now */
info("Triggering calibration\n");
if (keithley_change(gpib, 0.0, &ti.k) < 0) { info("failed\n"); goto out3; }
zoomrun_trigger_calibrate(zoom);
usleep(1000000);

/* Change Keithley values */
while (!g_quit) {
info("sleeping\n");
sleep(1);
}
printf("quitting\n");
printf("main thread quitting\n");

threadinfo.quit_flag = 1;
out3:
ti.quit_flag = 1;
pthread_join(thread, NULL);
out2:
keithley_off(gpib);


+ 6
- 0
pc/test.txt View File

@@ -0,0 +1,6 @@
Window is something like +- 2A equivalent

- Run Zoom NILM in "normal" mode
- Switch Keithley around randomly:
1 big jump (anywhere in 50A window)
1000 small jumps (within a 1A window)

Loading…
Cancel
Save