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

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517
  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. switch (ota_opt) {
  138. case 1:
  139. sweep_ota(zoom, gpib, ota_sweep_count);
  140. break;
  141. case 2:
  142. hold_ota2(zoom, gpib, ota_cmd);
  143. break;
  144. default:
  145. calibrate(zoom, gpib);
  146. break;
  147. }
  148. close(zoom);
  149. close(gpib);
  150. return 0;
  151. }
  152. void calibrate(int zoom, int gpib)
  153. {
  154. double idesired, iactual;
  155. int i;
  156. int zero;
  157. int r = 0;
  158. int dac[ZOOM_SWEEP_COUNT];
  159. int adc[ZOOM_SWEEP_COUNT];
  160. info("Initializing Zoom NILM\n");
  161. if (zoom_init(zoom) < 0) goto fail;
  162. info("Zeroing\n");
  163. if (zoom_zero_start(zoom) < 0) goto fail;
  164. info("Initializing GPIB\n");
  165. if (gpib_init(gpib) < 0) goto fail;
  166. info("Initializing Keithley\n");
  167. if (gpib_addr(gpib, 24) < 0) goto fail;
  168. if (keithley_init(gpib) < 0) goto fail;
  169. if (keithley_current(gpib, 0) < 0) goto fail;
  170. if (isnan(keithley_read(gpib))) goto fail;
  171. info("Stop zeroing\n");
  172. if (zoom_zero_stop(zoom) < 0) goto fail;
  173. info("Sweeping\n");
  174. for (idesired = -1.0; idesired <= 1.0 && !g_quit; idesired += 0.10) {
  175. // for (idesired = -0.2; idesired <= 0.2 && !g_quit; idesired += 0.02) {
  176. info("Zeroing\n");
  177. if (zoom_zero_start(zoom) < 0) goto fail;
  178. info("Setting current: %.8f\n", idesired);
  179. keithley_current(gpib, idesired);
  180. usleep(100000);
  181. iactual = keithley_read(gpib);
  182. info("Actual current: %.8f\n", iactual);
  183. info("Stop zeroing\n");
  184. if ((zero = zoom_zero_stop(zoom)) < 0) goto fail;
  185. info("DAC zero point = %d\n", zero);
  186. info("Sweeping...\n");
  187. if ((r = zoom_sweep(zoom, dac, adc)) < 0) goto fail;
  188. info("Done\n");
  189. for (i = 0; i < ZOOM_SWEEP_COUNT; i++) {
  190. printf("%.8f %d %d\n", iactual, dac[i], adc[i]);
  191. }
  192. }
  193. safecleanup:
  194. zoom_zero_start(zoom);
  195. keithley_off(gpib);
  196. usleep(50000);
  197. zoom_zero_stop(zoom);
  198. return;
  199. fail:
  200. info("Failed (code %d)\n", r);
  201. goto safecleanup;
  202. }
  203. void write_dac(int zoom, int dac)
  204. {
  205. char buf[128];
  206. if (zoom_init(zoom) < 0)
  207. errx(1, "init failed");
  208. if (dac < 0)
  209. dac = 0;
  210. if (dac > 65535)
  211. dac = 65535;
  212. while (!g_quit) {
  213. sprintf(buf, "v%04x", dac);
  214. if (safewrite(zoom, buf, 5) != 5)
  215. errx(1, "write failed");
  216. if (fdgets(buf, 128, zoom, 1000) == NULL)
  217. errx(1, "read timeout");
  218. chomp(buf);
  219. printf("%s\n", buf);
  220. }
  221. }
  222. void single_sweep(int zoom)
  223. {
  224. int i, r;
  225. int dac[ZOOM_SWEEP_COUNT];
  226. int adc[ZOOM_SWEEP_COUNT];
  227. info("Initializing Zoom NILM\n");
  228. if (zoom_init_nozero(zoom) < 0) goto fail;
  229. info("Sweeping\n");
  230. if ((r = zoom_sweep(zoom, dac, adc)) < 0) goto fail;
  231. info("Done\n");
  232. for (i = 0; i < ZOOM_SWEEP_COUNT; i++) {
  233. printf("%d %d\n", dac[i], adc[i]);
  234. }
  235. return;
  236. fail:
  237. info("Failed (code %d)\n", r);
  238. return;
  239. }
  240. void zero(int zoom)
  241. {
  242. int r;
  243. int dac;
  244. info("Initializing Zoom NILM\n");
  245. if (zoom_init(zoom) < 0) goto fail;
  246. info("Starting zeroing, ^C to stop\n");
  247. if (zoom_zero_start(zoom) < 0) goto fail;
  248. while (!g_quit)
  249. usleep(100000);
  250. info("Stop zeroing\n");
  251. if ((dac = zoom_zero_stop(zoom)) < 0) goto fail;
  252. info("DAC zero point = 0x%04x %d\n", dac, dac);
  253. info("Done\n");
  254. return;
  255. fail:
  256. info("Failed (code %d)\n", r);
  257. return;
  258. }
  259. void sweep_ota(int zoom, int gpib, int ota_sweep_count)
  260. {
  261. double iactual;
  262. int i,j;
  263. int r = 0;
  264. char buf[128];
  265. char zcmd[128];
  266. int mycmd = 0;
  267. int cmd_inc = 4096;
  268. info("Initializing Zoom NILM\n");
  269. if (zoom_init(zoom) < 0) goto fail;
  270. info("Initializing GPIB\n");
  271. if (gpib_init(gpib) < 0) goto fail;
  272. info("Initializing Keithley 2002 Multimeter\n");
  273. if (gpib_addr(gpib, 23) < 0) goto fail;
  274. if (keithley2002_init(gpib) < 0) goto fail;
  275. if (isnan(keithley2002_read(gpib))) goto fail;
  276. buf[0] = '0';
  277. if (safewrite(zoom, buf, 1) != 1)
  278. errx(1, "write failed");
  279. if (fdgets(buf, 128, zoom, 1000) == NULL)
  280. errx(1, "read timeout");
  281. drain(zoom);
  282. info("Sweeping OTA\n");
  283. for (i = 0; i <= 16 && !g_quit; i++){
  284. for(j = -2; j <= 2; j++){
  285. if(mycmd+j > 65535 || mycmd+j < 0)
  286. continue;
  287. if(sprintf(zcmd,"v%.4x",(mycmd +j)) < 5)
  288. errx(1, "fail hex conversion");
  289. if (safewrite(zoom, zcmd, 5) != 5)
  290. errx(1, "write failed");
  291. if (fdgets(buf, 128, zoom, 1000) == NULL)
  292. errx(1, "read timeout");
  293. usleep(100);
  294. iactual = keithley2002_read(gpib);
  295. printf("%d %.8f\n",(int)(mycmd + j), iactual);
  296. }
  297. mycmd += cmd_inc;
  298. }
  299. // return to zero
  300. buf[0] = '0';
  301. if (safewrite(zoom, buf, 1) != 1)
  302. errx(1, "write failed");
  303. if (fdgets(buf, 128, zoom, 1000) == NULL)
  304. errx(1, "read timeout");
  305. safecleanup:
  306. return;
  307. fail:
  308. info("Failed (code %d)\n", r);
  309. goto safecleanup;
  310. }
  311. void hold_ota(int zoom, int gpib, int ota_cmd)
  312. {
  313. double iactual;
  314. double tx;
  315. int i;
  316. int r = 0;
  317. char buf[128];
  318. char zcmd[128];
  319. info("Initializing Zoom NILM\n");
  320. if (zoom_init(zoom) < 0) goto fail;
  321. info("Initializing GPIB\n");
  322. if (gpib_init(gpib) < 0) goto fail;
  323. info("Initializing Keithley 2002 Multimeter\n");
  324. if (gpib_addr(gpib, 23) < 0) goto fail;
  325. if (keithley2002_init2(gpib) < 0) goto fail;
  326. if (isnan(keithley2002_read(gpib))) goto fail;
  327. buf[0] = '0';
  328. if (safewrite(zoom, buf, 1) != 1)
  329. errx(1, "write failed");
  330. if (fdgets(buf, 128, zoom, 1000) == NULL)
  331. errx(1, "read timeout");
  332. drain(zoom);
  333. if(ota_cmd > 65535 || ota_cmd < 0)
  334. errx(1, "ota command out-of-range");
  335. if(sprintf(zcmd,"v%.4x",(ota_cmd)) < 5)
  336. errx(1, "fail hex conversion");
  337. if (safewrite(zoom, zcmd, 5) != 5)
  338. errx(1, "write failed");
  339. if (fdgets(buf, 128, zoom, 1000) == NULL)
  340. errx(1, "read timeout");
  341. usleep(100);
  342. info("Holding OTA\n");
  343. for (i = 0; i <= 500 && !g_quit; i++){
  344. iactual = keithley2002_read2(gpib, &tx);
  345. printf("%.8f %.8f\n", tx, iactual);
  346. }
  347. // return to zero
  348. buf[0] = '0';
  349. if (safewrite(zoom, buf, 1) != 1)
  350. errx(1, "write failed");
  351. if (fdgets(buf, 128, zoom, 1000) == NULL)
  352. errx(1, "read timeout");
  353. safecleanup:
  354. return;
  355. fail:
  356. info("Failed (code %d)\n", r);
  357. goto safecleanup;
  358. }
  359. void hold_ota2(int zoom, int gpib, int ota_cmd)
  360. {
  361. int i;
  362. int r = 0;
  363. char buf[128];
  364. char zcmd[128];
  365. int dac1, dac2, adc1, adc2;
  366. info("Initializing Zoom NILM\n");
  367. if (zoom_init(zoom) < 0) goto fail;
  368. //info("Initializing GPIB\n");
  369. //if (gpib_init(gpib) < 0) goto fail;
  370. //info("Initializing Keithley 2002 Multimeter\n");
  371. //if (gpib_addr(gpib, 23) < 0) goto fail;
  372. //if (keithley2002_init2(gpib) < 0) goto fail;
  373. //if (isnan(keithley2002_read(gpib))) goto fail;
  374. buf[0] = '0';
  375. if (safewrite(zoom, buf, 1) != 1)
  376. errx(1, "write failed");
  377. if (fdgets(buf, 128, zoom, 1000) == NULL)
  378. errx(1, "read timeout");
  379. drain(zoom);
  380. if(ota_cmd > 65535 || ota_cmd < 0)
  381. errx(1, "ota command out-of-range");
  382. if(sprintf(zcmd,"v%.4x",(ota_cmd)) < 5)
  383. errx(1, "fail hex conversion");
  384. if (safewrite(zoom, zcmd, 5) != 5)
  385. errx(1, "write failed");
  386. if (fdgets(buf, 128, zoom, 1000) == NULL)
  387. errx(1, "read timeout");
  388. usleep(100);
  389. zcmd[0] = ' ';
  390. info("Holding OTA\n");
  391. for (i = 0; i <= 1000 && !g_quit; i++){
  392. if(safewrite(zoom,zcmd,1) != 1)
  393. errx(1, "write failed");
  394. if (fdgets(buf, 128, zoom, 1000) == NULL)
  395. errx(1, "read timeout");
  396. if (sscanf(buf,"%x %d %x %d", &dac1, &dac2, &adc1, &adc2) != 4)
  397. errx(1, "read error");
  398. printf("%d %d\n", dac2, adc2);
  399. }
  400. // return to zero
  401. buf[0] = '0';
  402. if (safewrite(zoom, buf, 1) != 1)
  403. errx(1, "write failed");
  404. if (fdgets(buf, 128, zoom, 1000) == NULL)
  405. errx(1, "read timeout");
  406. safecleanup:
  407. return;
  408. fail:
  409. info("Failed (code %d)\n", r);
  410. goto safecleanup;
  411. }