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.
 
 
 
 

439 lines
9.3 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 startup_zero(int zoom);
  18. void calibrate(int zoom, int gpib);
  19. void sweep_ota(int zoom, int gpib, int ota_sweep_count);
  20. void hold_ota(int zoom, int gpib, int ota_cmd);
  21. void hold_ota2(int zoom, int gpib, int ota_cmd);
  22. #define info(x...) fprintf(stderr,x)
  23. int g_quit = 0;
  24. void handle_sig(int sig) { g_quit = 1; }
  25. int main(int argc, char *argv[])
  26. {
  27. // char *zoomdev=strdup("/dev/serial/by-id/usb-FTDI_FT232R_USB_UART_A6007wag-if00-port0");
  28. char *zoomdev=strdup("/dev/serial/by-id/usb-FTDI_FT232R_USB_UART_A6007wc5-if00-port0");
  29. char *gpibdev=strdup("/dev/serial/by-id/usb-Prologix_Prologix_GPIB-USB_Controller_PXQQY20G-if00-port0");
  30. int getopt_index;
  31. int zoom, gpib;
  32. int do_zero = 0;
  33. int ota_opt = 0;
  34. int ota_sweep_count = 64;
  35. int ota_cmd = 32768;
  36. int tmp;
  37. char *end;
  38. static struct option long_opts[] = {
  39. { "zoom-device", required_argument, NULL, 'z' },
  40. { "gpib-device", required_argument, NULL, 'g' },
  41. { "startup-zero", no_argument, NULL, 's' },
  42. { "ota-sweep", required_argument, NULL, 'o' },
  43. { "ota-hold", required_argument, NULL, 'l' },
  44. { "help", no_argument, NULL, 'h' },
  45. { 0, 0, 0, 0}
  46. };
  47. int help=0;
  48. char c;
  49. while ((c = getopt_long(argc, argv, "z:g:so:l:h?",
  50. long_opts, &getopt_index)) != -1) {
  51. switch(c)
  52. {
  53. case 'z':
  54. free(zoomdev);
  55. zoomdev = strdup(optarg);
  56. break;
  57. case 'g':
  58. free(gpibdev);
  59. gpibdev = strdup(optarg);
  60. break;
  61. case 's':
  62. do_zero = 1;
  63. break;
  64. case 'o':
  65. ota_opt = 1;
  66. tmp = strtoul(optarg, &end, 0);
  67. if (*end) {
  68. fprintf(stderr, "bad number %s\n", optarg);
  69. help = 1;
  70. } else {
  71. ota_sweep_count = tmp;
  72. }
  73. break;
  74. case 'l':
  75. ota_opt = 2;
  76. tmp = strtoul(optarg, &end, 0);
  77. if (*end) {
  78. fprintf(stderr, "bad number %s\n", optarg);
  79. help = 1;
  80. } else {
  81. ota_cmd = tmp;
  82. }
  83. break;
  84. case 'h':
  85. case '?':
  86. default:
  87. help = 1;
  88. break;
  89. }
  90. }
  91. if (help) {
  92. fprintf(stderr, "Zoom Nilm Calibration Tool\n");
  93. fprintf(stderr, "usage: %s [options]\n\n", *argv);
  94. fprintf(stderr, " -z, --zoom-device %-14s zoom NILM serial port\n", "/dev/xxx" /*zoomdev*/);
  95. fprintf(stderr, " -g, --gpib-device %-14s GPIB serial port\n", "/dev/xxx" /*gpibdev*/);
  96. fprintf(stderr, " -s, --startup-zero assist startup by writing '0' to zoom NILM\n");
  97. fprintf(stderr, " -o, --ota-sweep %-14d sweep OTA\n", ota_sweep_count);
  98. fprintf(stderr, " -l, --ota-hold %-14d hold OTA constant\n", ota_cmd);
  99. fprintf(stderr, " -h, --help this help\n");
  100. return 1;
  101. }
  102. signal(SIGINT, handle_sig);
  103. if ((zoom = serial_open(zoomdev, 115200)) == -1)
  104. err(1, "failed to open zoom device %s", zoomdev);
  105. if (do_zero) {
  106. startup_zero(zoom);
  107. close(zoom);
  108. return 0;
  109. }
  110. if ((gpib = serial_open(gpibdev, 9600)) == -1)
  111. err(1, "failed to open gpib device %s", gpibdev);
  112. signal(SIGINT, handle_sig);
  113. switch (ota_opt) {
  114. case 1:
  115. sweep_ota(zoom, gpib, ota_sweep_count);
  116. break;
  117. case 2:
  118. hold_ota2(zoom, gpib, ota_cmd);
  119. break;
  120. default:
  121. calibrate(zoom, gpib);
  122. break;
  123. }
  124. close(zoom);
  125. close(gpib);
  126. return 0;
  127. }
  128. void calibrate(int zoom, int gpib)
  129. {
  130. double idesired, iactual;
  131. int i;
  132. int zero;
  133. int r = 0;
  134. int dac[ZOOM_SWEEP_COUNT];
  135. int adc[ZOOM_SWEEP_COUNT];
  136. info("Initializing Zoom NILM\n");
  137. if (zoom_init(zoom) < 0) goto fail;
  138. info("Zeroing\n");
  139. if (zoom_zero_start(zoom) < 0) goto fail;
  140. info("Initializing GPIB\n");
  141. if (gpib_init(gpib) < 0) goto fail;
  142. info("Initializing Keithley\n");
  143. if (gpib_addr(gpib, 24) < 0) goto fail;
  144. if (keithley_init(gpib) < 0) goto fail;
  145. if (keithley_current(gpib, 0) < 0) goto fail;
  146. if (isnan(keithley_read(gpib))) goto fail;
  147. info("Stop zeroing\n");
  148. if (zoom_zero_stop(zoom) < 0) goto fail;
  149. info("Sweeping\n");
  150. for (idesired = -1.0; idesired <= 1.0 && !g_quit; idesired += 0.02) {
  151. info("Zeroing\n");
  152. if (zoom_zero_start(zoom) < 0) goto fail;
  153. info("Setting current: %.8f\n", idesired);
  154. keithley_current(gpib, idesired);
  155. usleep(100000);
  156. iactual = keithley_read(gpib);
  157. info("Actual current: %.8f\n", iactual);
  158. info("Stop zeroing\n");
  159. if ((zero = zoom_zero_stop(zoom)) < 0) goto fail;
  160. info("DAC zero point = %d\n", zero);
  161. info("Sweeping...\n");
  162. if ((r = zoom_sweep(zoom, dac, adc)) < 0) goto fail;
  163. info("Done\n");
  164. for (i = 0; i < ZOOM_SWEEP_COUNT; i++) {
  165. printf("%.8f %d %d\n", iactual, dac[i], adc[i]);
  166. }
  167. }
  168. safecleanup:
  169. zoom_zero_start(zoom);
  170. keithley_off(gpib);
  171. usleep(50000);
  172. zoom_zero_stop(zoom);
  173. return;
  174. fail:
  175. info("Failed (code %d)\n", r);
  176. goto safecleanup;
  177. }
  178. void startup_zero(int zoom)
  179. {
  180. char buf[128];
  181. if (zoom_init(zoom) < 0)
  182. errx(1, "init failed");
  183. while (!g_quit) {
  184. buf[0] = '0';
  185. if (safewrite(zoom, buf, 1) != 1)
  186. errx(1, "write failed");
  187. if (fdgets(buf, 128, zoom, 1000) == NULL)
  188. errx(1, "read timeout");
  189. chomp(buf);
  190. printf("%s\n", buf);
  191. }
  192. }
  193. void sweep_ota(int zoom, int gpib, int ota_sweep_count)
  194. {
  195. double iactual;
  196. int i,j;
  197. int r = 0;
  198. char buf[128];
  199. char zcmd[128];
  200. int mycmd = 0;
  201. int cmd_inc = 4096;
  202. info("Initializing Zoom NILM\n");
  203. if (zoom_init(zoom) < 0) goto fail;
  204. info("Initializing GPIB\n");
  205. if (gpib_init(gpib) < 0) goto fail;
  206. info("Initializing Keithley 2002 Multimeter\n");
  207. if (gpib_addr(gpib, 23) < 0) goto fail;
  208. if (keithley2002_init(gpib) < 0) goto fail;
  209. if (isnan(keithley2002_read(gpib))) goto fail;
  210. buf[0] = '0';
  211. if (safewrite(zoom, buf, 1) != 1)
  212. errx(1, "write failed");
  213. if (fdgets(buf, 128, zoom, 1000) == NULL)
  214. errx(1, "read timeout");
  215. drain(zoom);
  216. info("Sweeping OTA\n");
  217. for (i = 0; i <= 16 && !g_quit; i++){
  218. for(j = -2; j <= 2; j++){
  219. if(mycmd+j > 65535 || mycmd+j < 0)
  220. continue;
  221. if(sprintf(zcmd,"v%.4x",(mycmd +j)) < 5)
  222. errx(1, "fail hex conversion");
  223. if (safewrite(zoom, zcmd, 5) != 5)
  224. errx(1, "write failed");
  225. if (fdgets(buf, 128, zoom, 1000) == NULL)
  226. errx(1, "read timeout");
  227. usleep(100);
  228. iactual = keithley2002_read(gpib);
  229. printf("%d %.8f\n",(int)(mycmd + j), iactual);
  230. }
  231. mycmd += cmd_inc;
  232. }
  233. // return to zero
  234. buf[0] = '0';
  235. if (safewrite(zoom, buf, 1) != 1)
  236. errx(1, "write failed");
  237. if (fdgets(buf, 128, zoom, 1000) == NULL)
  238. errx(1, "read timeout");
  239. safecleanup:
  240. return;
  241. fail:
  242. info("Failed (code %d)\n", r);
  243. goto safecleanup;
  244. }
  245. void hold_ota(int zoom, int gpib, int ota_cmd)
  246. {
  247. double iactual;
  248. double tx;
  249. int i;
  250. int r = 0;
  251. char buf[128];
  252. char zcmd[128];
  253. info("Initializing Zoom NILM\n");
  254. if (zoom_init(zoom) < 0) goto fail;
  255. info("Initializing GPIB\n");
  256. if (gpib_init(gpib) < 0) goto fail;
  257. info("Initializing Keithley 2002 Multimeter\n");
  258. if (gpib_addr(gpib, 23) < 0) goto fail;
  259. if (keithley2002_init2(gpib) < 0) goto fail;
  260. if (isnan(keithley2002_read(gpib))) goto fail;
  261. buf[0] = '0';
  262. if (safewrite(zoom, buf, 1) != 1)
  263. errx(1, "write failed");
  264. if (fdgets(buf, 128, zoom, 1000) == NULL)
  265. errx(1, "read timeout");
  266. drain(zoom);
  267. if(ota_cmd > 65535 || ota_cmd < 0)
  268. errx(1, "ota command out-of-range");
  269. if(sprintf(zcmd,"v%.4x",(ota_cmd)) < 5)
  270. errx(1, "fail hex conversion");
  271. if (safewrite(zoom, zcmd, 5) != 5)
  272. errx(1, "write failed");
  273. if (fdgets(buf, 128, zoom, 1000) == NULL)
  274. errx(1, "read timeout");
  275. usleep(100);
  276. info("Holding OTA\n");
  277. for (i = 0; i <= 500 && !g_quit; i++){
  278. iactual = keithley2002_read2(gpib, &tx);
  279. printf("%.8f %.8f\n", tx, iactual);
  280. }
  281. // return to zero
  282. buf[0] = '0';
  283. if (safewrite(zoom, buf, 1) != 1)
  284. errx(1, "write failed");
  285. if (fdgets(buf, 128, zoom, 1000) == NULL)
  286. errx(1, "read timeout");
  287. safecleanup:
  288. return;
  289. fail:
  290. info("Failed (code %d)\n", r);
  291. goto safecleanup;
  292. }
  293. void hold_ota2(int zoom, int gpib, int ota_cmd)
  294. {
  295. int i;
  296. int r = 0;
  297. char buf[128];
  298. char zcmd[128];
  299. int dac1, dac2, adc1, adc2;
  300. info("Initializing Zoom NILM\n");
  301. if (zoom_init(zoom) < 0) goto fail;
  302. //info("Initializing GPIB\n");
  303. //if (gpib_init(gpib) < 0) goto fail;
  304. //info("Initializing Keithley 2002 Multimeter\n");
  305. //if (gpib_addr(gpib, 23) < 0) goto fail;
  306. //if (keithley2002_init2(gpib) < 0) goto fail;
  307. //if (isnan(keithley2002_read(gpib))) goto fail;
  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. drain(zoom);
  314. if(ota_cmd > 65535 || ota_cmd < 0)
  315. errx(1, "ota command out-of-range");
  316. if(sprintf(zcmd,"v%.4x",(ota_cmd)) < 5)
  317. errx(1, "fail hex conversion");
  318. if (safewrite(zoom, zcmd, 5) != 5)
  319. errx(1, "write failed");
  320. if (fdgets(buf, 128, zoom, 1000) == NULL)
  321. errx(1, "read timeout");
  322. usleep(100);
  323. zcmd[0] = ' ';
  324. info("Holding OTA\n");
  325. for (i = 0; i <= 1000 && !g_quit; i++){
  326. if(safewrite(zoom,zcmd,1) != 1)
  327. errx(1, "write failed");
  328. if (fdgets(buf, 128, zoom, 1000) == NULL)
  329. errx(1, "read timeout");
  330. if (sscanf(buf,"%x %d %x %d", &dac1, &dac2, &adc1, &adc2) != 4)
  331. errx(1, "read error");
  332. printf("%d %d\n", dac2, adc2);
  333. }
  334. // return to zero
  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. safecleanup:
  341. return;
  342. fail:
  343. info("Failed (code %d)\n", r);
  344. goto safecleanup;
  345. }