You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

calibrate.c 11 KiB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <sys/types.h>
  4. #include <errno.h>
  5. #include <unistd.h>
  6. #include <getopt.h>
  7. #include <stdint.h>
  8. #include <string.h>
  9. #include <syslog.h>
  10. #include <err.h>
  11. #include <linux/serial.h>
  12. #include <sys/signal.h>
  13. #include "serial-util.h"
  14. #include "gpib.h"
  15. #include "zoom.h"
  16. #include "math.h"
  17. void zero(int zoom);
  18. void write_dac(int zoom, int dac);
  19. void single_sweep(int zoom);
  20. void calibrate(int zoom, int gpib);
  21. void sweep_ota(int zoom, int gpib, int ota_sweep_count);
  22. void hold_ota(int zoom, int gpib, int ota_cmd);
  23. void hold_ota2(int zoom, int gpib, int ota_cmd);
  24. #define info(x...) fprintf(stderr,x)
  25. int g_quit = 0;
  26. void handle_sig(int sig) { g_quit = 1; }
  27. int main(int argc, char *argv[])
  28. {
  29. // char *zoomdev=strdup("/dev/serial/by-id/usb-FTDI_FT232R_USB_UART_A6007wag-if00-port0");
  30. char *zoomdev=strdup("/dev/serial/by-id/usb-FTDI_FT232R_USB_UART_A6007wc5-if00-port0");
  31. char *gpibdev=strdup("/dev/serial/by-id/usb-Prologix_Prologix_GPIB-USB_Controller_PXQQY20G-if00-port0");
  32. int getopt_index;
  33. int zoom, gpib;
  34. int do_write = 0;
  35. int do_zero = 0;
  36. int write_cmd = 32768;
  37. int do_single_sweep = 0;
  38. int ota_opt = 0;
  39. int ota_sweep_count = 64;
  40. int ota_cmd = 32768;
  41. char *end;
  42. static struct option long_opts[] = {
  43. { "zoom-device", required_argument, NULL, 'Z' },
  44. { "gpib-device", required_argument, NULL, 'G' },
  45. { "write-dac", required_argument, NULL, 'w' },
  46. { "zero", no_argument, NULL, 'z' },
  47. { "single-sweep", no_argument, NULL, 's' },
  48. { "ota-sweep", required_argument, NULL, 'o' },
  49. { "ota-hold", required_argument, NULL, 'l' },
  50. { "help", no_argument, NULL, 'h' },
  51. { 0, 0, 0, 0}
  52. };
  53. int help=0;
  54. char c;
  55. while ((c = getopt_long(argc, argv, "Z:G:szw:o:l:h?",
  56. long_opts, &getopt_index)) != -1) {
  57. switch(c)
  58. {
  59. case 'Z':
  60. free(zoomdev);
  61. zoomdev = strdup(optarg);
  62. break;
  63. case 'G':
  64. free(gpibdev);
  65. gpibdev = strdup(optarg);
  66. break;
  67. case 'w':
  68. do_write = 1;
  69. write_cmd = strtoul(optarg, &end, 0);
  70. if (*end) {
  71. fprintf(stderr, "bad number %s\n", optarg);
  72. help = 1;
  73. }
  74. break;
  75. case 's':
  76. do_single_sweep = 1;
  77. break;
  78. case 'z':
  79. do_zero = 1;
  80. break;
  81. case 'o':
  82. ota_opt = 1;
  83. ota_sweep_count = strtoul(optarg, &end, 0);
  84. if (*end) {
  85. fprintf(stderr, "bad number %s\n", optarg);
  86. help = 1;
  87. }
  88. break;
  89. case 'l':
  90. ota_opt = 2;
  91. ota_cmd = strtoul(optarg, &end, 0);
  92. if (*end) {
  93. fprintf(stderr, "bad number %s\n", optarg);
  94. help = 1;
  95. }
  96. break;
  97. case 'h':
  98. case '?':
  99. default:
  100. help = 1;
  101. break;
  102. }
  103. }
  104. if (help) {
  105. fprintf(stderr, "Zoom Nilm Calibration Tool\n");
  106. fprintf(stderr, "usage: %s [options]\n\n", *argv);
  107. fprintf(stderr, " -Z, --zoom-device %-14s zoom NILM serial port\n", "/dev/xxx" /*zoomdev*/);
  108. fprintf(stderr, " -G, --gpib-device %-14s GPIB serial port\n", "/dev/xxx" /*gpibdev*/);
  109. fprintf(stderr, " -w, --write-dac %-14d write one value to the DAC constantly\n", write_cmd);
  110. fprintf(stderr, " -s, --single-sweep do a single sweep on the PIC\n");
  111. fprintf(stderr, " -z, --zero set DAC value such that ADC input is centered\n");
  112. fprintf(stderr, " -o, --ota-sweep %-14d sweep OTA\n", ota_sweep_count);
  113. fprintf(stderr, " -l, --ota-hold %-14d hold OTA constant\n", ota_cmd);
  114. fprintf(stderr, " -h, --help this help\n");
  115. return 1;
  116. }
  117. signal(SIGINT, handle_sig);
  118. if ((zoom = serial_open(zoomdev, 115200)) == -1)
  119. err(1, "failed to open zoom device %s", zoomdev);
  120. if (do_write) {
  121. write_dac(zoom, write_cmd);
  122. close(zoom);
  123. return 0;
  124. }
  125. if (do_zero) {
  126. zero(zoom);
  127. close(zoom);
  128. return 0;
  129. }
  130. if (do_single_sweep) {
  131. single_sweep(zoom);
  132. close(zoom);
  133. return 0;
  134. }
  135. if ((gpib = serial_open(gpibdev, 9600)) == -1)
  136. err(1, "failed to open gpib device %s", gpibdev);
  137. signal(SIGINT, handle_sig);
  138. switch (ota_opt) {
  139. case 1:
  140. sweep_ota(zoom, gpib, ota_sweep_count);
  141. break;
  142. case 2:
  143. hold_ota2(zoom, gpib, ota_cmd);
  144. break;
  145. default:
  146. calibrate(zoom, gpib);
  147. break;
  148. }
  149. close(zoom);
  150. close(gpib);
  151. return 0;
  152. }
  153. void calibrate(int zoom, int gpib)
  154. {
  155. double idesired, iactual;
  156. int i;
  157. int zero;
  158. int r = 0;
  159. int dac[ZOOM_SWEEP_COUNT];
  160. int adc[ZOOM_SWEEP_COUNT];
  161. info("Initializing Zoom NILM\n");
  162. if (zoom_init(zoom) < 0) goto fail;
  163. info("Zeroing\n");
  164. if (zoom_zero_start(zoom) < 0) goto fail;
  165. info("Initializing GPIB\n");
  166. if (gpib_init(gpib) < 0) goto fail;
  167. info("Initializing Keithley\n");
  168. if (gpib_addr(gpib, 24) < 0) goto fail;
  169. if (keithley_init(gpib) < 0) goto fail;
  170. if (keithley_current(gpib, 0) < 0) goto fail;
  171. if (isnan(keithley_read(gpib))) goto fail;
  172. info("Stop zeroing\n");
  173. if (zoom_zero_stop(zoom) < 0) goto fail;
  174. info("Sweeping\n");
  175. for (idesired = -1.0; idesired <= 1.0 && !g_quit; idesired += 0.10) {
  176. // for (idesired = -0.2; idesired <= 0.2 && !g_quit; idesired += 0.02) {
  177. info("Zeroing\n");
  178. if (zoom_zero_start(zoom) < 0) goto fail;
  179. info("Setting current: %.8f\n", idesired);
  180. keithley_current(gpib, idesired);
  181. usleep(100000);
  182. iactual = keithley_read(gpib);
  183. info("Actual current: %.8f\n", iactual);
  184. info("Stop zeroing\n");
  185. if ((zero = zoom_zero_stop(zoom)) < 0) goto fail;
  186. info("DAC zero point = %d\n", zero);
  187. info("Sweeping...\n");
  188. if ((r = zoom_sweep(zoom, dac, adc)) < 0) goto fail;
  189. info("Done\n");
  190. for (i = 0; i < ZOOM_SWEEP_COUNT; i++) {
  191. printf("%.8f %d %d\n", iactual, dac[i], adc[i]);
  192. }
  193. }
  194. safecleanup:
  195. zoom_zero_start(zoom);
  196. keithley_off(gpib);
  197. usleep(50000);
  198. zoom_zero_stop(zoom);
  199. return;
  200. fail:
  201. info("Failed (code %d)\n", r);
  202. goto safecleanup;
  203. }
  204. void write_dac(int zoom, int dac)
  205. {
  206. char buf[128];
  207. if (zoom_init(zoom) < 0)
  208. errx(1, "init failed");
  209. if (dac < 0)
  210. dac = 0;
  211. if (dac > 65535)
  212. dac = 65535;
  213. while (!g_quit) {
  214. sprintf(buf, "v%04x", dac);
  215. if (safewrite(zoom, buf, 5) != 5)
  216. errx(1, "write failed");
  217. if (fdgets(buf, 128, zoom, 1000) == NULL)
  218. errx(1, "read timeout");
  219. chomp(buf);
  220. printf("%s\n", buf);
  221. }
  222. }
  223. void single_sweep(int zoom)
  224. {
  225. int i, r;
  226. int dac[ZOOM_SWEEP_COUNT];
  227. int adc[ZOOM_SWEEP_COUNT];
  228. info("Initializing Zoom NILM\n");
  229. if (zoom_init_nozero(zoom) < 0) goto fail;
  230. info("Sweeping\n");
  231. if ((r = zoom_sweep(zoom, dac, adc)) < 0) goto fail;
  232. info("Done\n");
  233. for (i = 0; i < ZOOM_SWEEP_COUNT; i++) {
  234. printf("%d %d\n", dac[i], adc[i]);
  235. }
  236. return;
  237. fail:
  238. info("Failed (code %d)\n", r);
  239. return;
  240. }
  241. void zero(int zoom)
  242. {
  243. int r;
  244. int dac;
  245. info("Initializing Zoom NILM\n");
  246. if (zoom_init(zoom) < 0) goto fail;
  247. info("Starting zeroing, ^C to stop\n");
  248. if (zoom_zero_start(zoom) < 0) goto fail;
  249. while (!g_quit)
  250. usleep(100000);
  251. info("Stop zeroing\n");
  252. if ((dac = zoom_zero_stop(zoom)) < 0) goto fail;
  253. info("DAC zero point = 0x%04x %d\n", dac, dac);
  254. info("Done\n");
  255. return;
  256. fail:
  257. info("Failed (code %d)\n", r);
  258. return;
  259. }
  260. void sweep_ota(int zoom, int gpib, int ota_sweep_count)
  261. {
  262. double iactual;
  263. int i,j;
  264. int r = 0;
  265. char buf[128];
  266. char zcmd[128];
  267. int mycmd = 0;
  268. int cmd_inc = 4096;
  269. info("Initializing Zoom NILM\n");
  270. if (zoom_init(zoom) < 0) goto fail;
  271. info("Initializing GPIB\n");
  272. if (gpib_init(gpib) < 0) goto fail;
  273. info("Initializing Keithley 2002 Multimeter\n");
  274. if (gpib_addr(gpib, 23) < 0) goto fail;
  275. if (keithley2002_init(gpib) < 0) goto fail;
  276. if (isnan(keithley2002_read(gpib))) goto fail;
  277. buf[0] = '0';
  278. if (safewrite(zoom, buf, 1) != 1)
  279. errx(1, "write failed");
  280. if (fdgets(buf, 128, zoom, 1000) == NULL)
  281. errx(1, "read timeout");
  282. drain(zoom);
  283. info("Sweeping OTA\n");
  284. for (i = 0; i <= 16 && !g_quit; i++){
  285. for(j = -2; j <= 2; j++){
  286. if(mycmd+j > 65535 || mycmd+j < 0)
  287. continue;
  288. if(sprintf(zcmd,"v%.4x",(mycmd +j)) < 5)
  289. errx(1, "fail hex conversion");
  290. if (safewrite(zoom, zcmd, 5) != 5)
  291. errx(1, "write failed");
  292. if (fdgets(buf, 128, zoom, 1000) == NULL)
  293. errx(1, "read timeout");
  294. usleep(100);
  295. iactual = keithley2002_read(gpib);
  296. printf("%d %.8f\n",(int)(mycmd + j), iactual);
  297. }
  298. mycmd += cmd_inc;
  299. }
  300. // return to zero
  301. buf[0] = '0';
  302. if (safewrite(zoom, buf, 1) != 1)
  303. errx(1, "write failed");
  304. if (fdgets(buf, 128, zoom, 1000) == NULL)
  305. errx(1, "read timeout");
  306. safecleanup:
  307. return;
  308. fail:
  309. info("Failed (code %d)\n", r);
  310. goto safecleanup;
  311. }
  312. void hold_ota(int zoom, int gpib, int ota_cmd)
  313. {
  314. double iactual;
  315. double tx;
  316. int i;
  317. int r = 0;
  318. char buf[128];
  319. char zcmd[128];
  320. info("Initializing Zoom NILM\n");
  321. if (zoom_init(zoom) < 0) goto fail;
  322. info("Initializing GPIB\n");
  323. if (gpib_init(gpib) < 0) goto fail;
  324. info("Initializing Keithley 2002 Multimeter\n");
  325. if (gpib_addr(gpib, 23) < 0) goto fail;
  326. if (keithley2002_init2(gpib) < 0) goto fail;
  327. if (isnan(keithley2002_read(gpib))) goto fail;
  328. buf[0] = '0';
  329. if (safewrite(zoom, buf, 1) != 1)
  330. errx(1, "write failed");
  331. if (fdgets(buf, 128, zoom, 1000) == NULL)
  332. errx(1, "read timeout");
  333. drain(zoom);
  334. if(ota_cmd > 65535 || ota_cmd < 0)
  335. errx(1, "ota command out-of-range");
  336. if(sprintf(zcmd,"v%.4x",(ota_cmd)) < 5)
  337. errx(1, "fail hex conversion");
  338. if (safewrite(zoom, zcmd, 5) != 5)
  339. errx(1, "write failed");
  340. if (fdgets(buf, 128, zoom, 1000) == NULL)
  341. errx(1, "read timeout");
  342. usleep(100);
  343. info("Holding OTA\n");
  344. for (i = 0; i <= 500 && !g_quit; i++){
  345. iactual = keithley2002_read2(gpib, &tx);
  346. printf("%.8f %.8f\n", tx, iactual);
  347. }
  348. // return to zero
  349. buf[0] = '0';
  350. if (safewrite(zoom, buf, 1) != 1)
  351. errx(1, "write failed");
  352. if (fdgets(buf, 128, zoom, 1000) == NULL)
  353. errx(1, "read timeout");
  354. safecleanup:
  355. return;
  356. fail:
  357. info("Failed (code %d)\n", r);
  358. goto safecleanup;
  359. }
  360. void hold_ota2(int zoom, int gpib, int ota_cmd)
  361. {
  362. int i;
  363. int r = 0;
  364. char buf[128];
  365. char zcmd[128];
  366. int dac1, dac2, adc1, adc2;
  367. info("Initializing Zoom NILM\n");
  368. if (zoom_init(zoom) < 0) goto fail;
  369. //info("Initializing GPIB\n");
  370. //if (gpib_init(gpib) < 0) goto fail;
  371. //info("Initializing Keithley 2002 Multimeter\n");
  372. //if (gpib_addr(gpib, 23) < 0) goto fail;
  373. //if (keithley2002_init2(gpib) < 0) goto fail;
  374. //if (isnan(keithley2002_read(gpib))) goto fail;
  375. buf[0] = '0';
  376. if (safewrite(zoom, buf, 1) != 1)
  377. errx(1, "write failed");
  378. if (fdgets(buf, 128, zoom, 1000) == NULL)
  379. errx(1, "read timeout");
  380. drain(zoom);
  381. if(ota_cmd > 65535 || ota_cmd < 0)
  382. errx(1, "ota command out-of-range");
  383. if(sprintf(zcmd,"v%.4x",(ota_cmd)) < 5)
  384. errx(1, "fail hex conversion");
  385. if (safewrite(zoom, zcmd, 5) != 5)
  386. errx(1, "write failed");
  387. if (fdgets(buf, 128, zoom, 1000) == NULL)
  388. errx(1, "read timeout");
  389. usleep(100);
  390. zcmd[0] = ' ';
  391. info("Holding OTA\n");
  392. for (i = 0; i <= 1000 && !g_quit; i++){
  393. if(safewrite(zoom,zcmd,1) != 1)
  394. errx(1, "write failed");
  395. if (fdgets(buf, 128, zoom, 1000) == NULL)
  396. errx(1, "read timeout");
  397. if (sscanf(buf,"%x %d %x %d", &dac1, &dac2, &adc1, &adc2) != 4)
  398. errx(1, "read error");
  399. printf("%d %d\n", dac2, adc2);
  400. }
  401. // return to zero
  402. buf[0] = '0';
  403. if (safewrite(zoom, buf, 1) != 1)
  404. errx(1, "write failed");
  405. if (fdgets(buf, 128, zoom, 1000) == NULL)
  406. errx(1, "read timeout");
  407. safecleanup:
  408. return;
  409. fail:
  410. info("Failed (code %d)\n", r);
  411. goto safecleanup;
  412. }