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.
 
 
 
 

452 lines
9.5 KiB

  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. #define info(x...) fprintf(stderr,x)
  24. int g_quit = 0;
  25. void handle_sig(int sig) { g_quit = 1; }
  26. int main(int argc, char *argv[])
  27. {
  28. char *zoomdev=strdup("/dev/serial/by-id/usb-FTDI_FT232R_"
  29. "USB_UART_A6007wc5-if00-port0");
  30. char *gpibdev=strdup("/dev/serial/by-id/usb-Prologix_Prologix_"
  31. "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 "
  108. "zoom NILM serial port\n", "/dev/xxx" /*zoomdev*/);
  109. fprintf(stderr, " -G, --gpib-device %-14s "
  110. "GPIB serial port\n", "/dev/xxx" /*gpibdev*/);
  111. fprintf(stderr, " -w, --write-dac %-14d "
  112. "write one value to the DAC constantly\n", write_cmd);
  113. fprintf(stderr, " -s, --single-sweep "
  114. "do a single sweep on the PIC\n");
  115. fprintf(stderr, " -z, --zero "
  116. "set DAC value such that ADC input is centered\n");
  117. fprintf(stderr, " -o, --ota-sweep %-14d "
  118. "sweep OTA\n", ota_sweep_count);
  119. fprintf(stderr, " -l, --ota-hold %-14d "
  120. "hold OTA constant\n", ota_cmd);
  121. fprintf(stderr, " -h, --help "
  122. "this help\n");
  123. return 1;
  124. }
  125. signal(SIGINT, handle_sig);
  126. if ((zoom = serial_open(zoomdev, 115200)) == -1)
  127. err(1, "failed to open zoom device %s", zoomdev);
  128. if (do_write) {
  129. write_dac(zoom, write_cmd);
  130. close(zoom);
  131. return 0;
  132. }
  133. if (do_zero) {
  134. zero(zoom);
  135. close(zoom);
  136. return 0;
  137. }
  138. if (do_single_sweep) {
  139. single_sweep(zoom);
  140. close(zoom);
  141. return 0;
  142. }
  143. if ((gpib = serial_open(gpibdev, 9600)) == -1)
  144. err(1, "failed to open gpib device %s", gpibdev);
  145. switch (ota_opt) {
  146. case 1:
  147. sweep_ota(zoom, gpib, ota_sweep_count);
  148. break;
  149. case 2:
  150. hold_ota(zoom, gpib, ota_cmd);
  151. break;
  152. default:
  153. calibrate(zoom, gpib);
  154. break;
  155. }
  156. close(zoom);
  157. close(gpib);
  158. return 0;
  159. }
  160. void calibrate(int zoom, int gpib)
  161. {
  162. double idesired, iactual;
  163. int i;
  164. int zero;
  165. int r = 0;
  166. int dac[ZOOM_SWEEP_COUNT];
  167. int adc[ZOOM_SWEEP_COUNT];
  168. info("Initializing Zoom NILM\n");
  169. if (zoom_init(zoom) < 0) goto fail;
  170. info("Zeroing\n");
  171. if (zoom_zero_start(zoom) < 0) goto fail;
  172. info("Initializing GPIB\n");
  173. if (gpib_init(gpib) < 0) goto fail;
  174. info("Initializing Keithley\n");
  175. if (gpib_addr(gpib, 24) < 0) goto fail;
  176. if (keithley_init(gpib) < 0) goto fail;
  177. if (keithley_current(gpib, 0) < 0) goto fail;
  178. if (isnan(keithley_read(gpib))) goto fail;
  179. info("Stop zeroing\n");
  180. if (zoom_zero_stop(zoom) < 0) goto fail;
  181. info("Sweeping\n");
  182. for (idesired = -1.0; idesired <= 1.0 && !g_quit; idesired += 0.10) {
  183. // for (idesired = -0.2; idesired <= 0.2 && !g_quit; idesired += 0.02) {
  184. info("Zeroing\n");
  185. if (zoom_zero_start(zoom) < 0) goto fail;
  186. info("Setting current: %.8f\n", idesired);
  187. keithley_current(gpib, idesired);
  188. usleep(100000);
  189. iactual = keithley_read(gpib);
  190. info("Actual current: %.8f\n", iactual);
  191. info("Stop zeroing\n");
  192. if ((zero = zoom_zero_stop(zoom)) < 0) goto fail;
  193. info("DAC zero point = %d\n", zero);
  194. info("Sweeping...\n");
  195. if ((r = zoom_sweep(zoom, dac, adc)) < 0) goto fail;
  196. info("Done\n");
  197. for (i = 0; i < ZOOM_SWEEP_COUNT; i++) {
  198. printf("%.8f %d %d\n", iactual, dac[i], adc[i]);
  199. }
  200. }
  201. safecleanup:
  202. zoom_zero_start(zoom);
  203. keithley_off(gpib);
  204. usleep(50000);
  205. zoom_zero_stop(zoom);
  206. return;
  207. fail:
  208. info("Failed (code %d)\n", r);
  209. goto safecleanup;
  210. }
  211. void write_dac(int zoom, int dac)
  212. {
  213. char buf[128];
  214. if (zoom_init(zoom) < 0)
  215. errx(1, "init failed");
  216. if (dac < 0)
  217. dac = 0;
  218. if (dac > 65535)
  219. dac = 65535;
  220. while (!g_quit) {
  221. sprintf(buf, "v%04x", dac);
  222. if (safewrite(zoom, buf, 5) != 5)
  223. errx(1, "write failed");
  224. if (fdgets(buf, 128, zoom, 1000) == NULL)
  225. errx(1, "read timeout");
  226. chomp(buf);
  227. printf("%s\n", buf);
  228. }
  229. }
  230. void single_sweep(int zoom)
  231. {
  232. int i, r;
  233. int dac[ZOOM_SWEEP_COUNT];
  234. int adc[ZOOM_SWEEP_COUNT];
  235. info("Initializing Zoom NILM\n");
  236. if (zoom_init_nozero(zoom) < 0) goto fail;
  237. info("Sweeping\n");
  238. if ((r = zoom_sweep(zoom, dac, adc)) < 0) goto fail;
  239. info("Done\n");
  240. for (i = 0; i < ZOOM_SWEEP_COUNT; i++) {
  241. printf("%d %d\n", dac[i], adc[i]);
  242. }
  243. return;
  244. fail:
  245. info("Failed (code %d)\n", r);
  246. return;
  247. }
  248. void zero(int zoom)
  249. {
  250. int r = 0;
  251. int dac;
  252. info("Initializing Zoom NILM\n");
  253. if (zoom_init(zoom) < 0) goto fail;
  254. info("Starting zeroing, ^C to stop\n");
  255. if (zoom_zero_start(zoom) < 0) goto fail;
  256. while (!g_quit)
  257. usleep(100000);
  258. info("Stop zeroing\n");
  259. if ((dac = zoom_zero_stop(zoom)) < 0) goto fail;
  260. info("DAC zero point = 0x%04x %d\n", dac, dac);
  261. info("Done\n");
  262. return;
  263. fail:
  264. info("Failed (code %d)\n", r);
  265. return;
  266. }
  267. void sweep_ota(int zoom, int gpib, int ota_sweep_count)
  268. {
  269. double iactual;
  270. int i,j;
  271. int r = 0;
  272. char buf[128];
  273. char zcmd[128];
  274. int mycmd = 0;
  275. int cmd_inc = 4096;
  276. info("Initializing Zoom NILM\n");
  277. if (zoom_init(zoom) < 0) goto fail;
  278. info("Initializing GPIB\n");
  279. if (gpib_init(gpib) < 0) goto fail;
  280. info("Initializing Keithley 2002 Multimeter\n");
  281. if (gpib_addr(gpib, 23) < 0) goto fail;
  282. if (keithley2002_init(gpib) < 0) goto fail;
  283. if (isnan(keithley2002_read(gpib))) goto fail;
  284. buf[0] = '0';
  285. if (safewrite(zoom, buf, 1) != 1)
  286. errx(1, "write failed");
  287. if (fdgets(buf, 128, zoom, 1000) == NULL)
  288. errx(1, "read timeout");
  289. drain(zoom);
  290. info("Sweeping OTA\n");
  291. for (i = 0; i <= 16 && !g_quit; i++){
  292. for(j = -2; j <= 2; j++){
  293. if(mycmd+j > 65535 || mycmd+j < 0)
  294. continue;
  295. if(sprintf(zcmd,"v%.4x",(mycmd +j)) < 5)
  296. errx(1, "fail hex conversion");
  297. if (safewrite(zoom, zcmd, 5) != 5)
  298. errx(1, "write failed");
  299. if (fdgets(buf, 128, zoom, 1000) == NULL)
  300. errx(1, "read timeout");
  301. usleep(100);
  302. iactual = keithley2002_read(gpib);
  303. printf("%d %.8f\n",(int)(mycmd + j), iactual);
  304. }
  305. mycmd += cmd_inc;
  306. }
  307. // return to zero
  308. buf[0] = '0';
  309. if (safewrite(zoom, buf, 1) != 1)
  310. errx(1, "write failed");
  311. if (fdgets(buf, 128, zoom, 1000) == NULL)
  312. errx(1, "read timeout");
  313. safecleanup:
  314. return;
  315. fail:
  316. info("Failed (code %d)\n", r);
  317. goto safecleanup;
  318. }
  319. void hold_ota(int zoom, int gpib, int ota_cmd)
  320. {
  321. double iactual;
  322. double tx;
  323. int i;
  324. int r = 0;
  325. char buf[128];
  326. char zcmd[128];
  327. info("Initializing Zoom NILM\n");
  328. if (zoom_init(zoom) < 0) goto fail;
  329. info("Initializing GPIB\n");
  330. if (gpib_init(gpib) < 0) goto fail;
  331. info("Initializing Keithley 2002 Multimeter\n");
  332. if (gpib_addr(gpib, 23) < 0) goto fail;
  333. if (keithley2002_init2(gpib) < 0) goto fail;
  334. if (isnan(keithley2002_read(gpib))) goto fail;
  335. buf[0] = '0';
  336. if (safewrite(zoom, buf, 1) != 1)
  337. errx(1, "write failed");
  338. if (fdgets(buf, 128, zoom, 1000) == NULL)
  339. errx(1, "read timeout");
  340. drain(zoom);
  341. if(ota_cmd > 65535 || ota_cmd < 0)
  342. errx(1, "ota command out-of-range");
  343. if(sprintf(zcmd,"v%.4x",(ota_cmd)) < 5)
  344. errx(1, "fail hex conversion");
  345. if (safewrite(zoom, zcmd, 5) != 5)
  346. errx(1, "write failed");
  347. if (fdgets(buf, 128, zoom, 1000) == NULL)
  348. errx(1, "read timeout");
  349. usleep(100);
  350. info("Holding OTA\n");
  351. for (i = 0; i <= 500 && !g_quit; i++){
  352. iactual = keithley2002_read2(gpib, &tx);
  353. printf("%.12f %.12f\n", tx, iactual);
  354. }
  355. // return to zero
  356. buf[0] = '0';
  357. if (safewrite(zoom, buf, 1) != 1)
  358. errx(1, "write failed");
  359. if (fdgets(buf, 128, zoom, 1000) == NULL)
  360. errx(1, "read timeout");
  361. safecleanup:
  362. return;
  363. fail:
  364. info("Failed (code %d)\n", r);
  365. goto safecleanup;
  366. }