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.
 
 
 
 

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