/* ************************************************************** */ /* * Module VTSCAN * This module contains functions to make integrated voltage * measurements from a moving wire. The wire is moved continuously * and the measurements are triggered by an encoder. * * Zachary Wolf * 3/13/00 */ /* ************************************************************** */ /* INCLUDES */ #include #include #include #include #include #include "vtscan.h" #include "vtscanui.h" #include "mc4.h" #include "k7011.h" #include "pdi5025.h" /* ************************************************************** */ /* PRIVATE PARAMETERS */ static char log_file[100]; static struct vtscan_param_struct vtscan_param; /* ************************************************************** */ /* PRIVATE GLOBAL VARIABLES */ static int mc4_ID; static int k7011_ID; static int pdi5025_ID; static char msg[80]; /* ************************************************************** */ /* PRIVATE FUNCTIONS */ int vtscan_check_param(void); void vtscan_error(char* message); void vtscan_message(char* message); void vtscan_log_meas(void); void vtscan_log_vt(double x_start, double dx, int num_samp, double x[], double vt[]); /* ************************************************************** */ /* PUBLIC FUNCTIONS */ /* ************************************************************** */ /* * vtscan_init * This function is used to initialize the integrated voltage * measurement system. * * Zachary Wolf * 3/13/00 */ void vtscan_init(char log_file_in[], struct vtscan_param_struct vtscan_par) { /* Declare variables */ int err; char buf[80]; /* Save parameters for future use */ strcpy(log_file, log_file_in); vtscan_param = vtscan_par; /* Check all parameter values to find any problems */ err = vtscan_check_param(); if (err != 0) { vtscan_error("Problem with parameter values"); return; } /* Initialize the required hardware */ if (vtscan_param.config == VTSCAN_MC4_PDI5025) { mc4_init(vtscan_param.board_addr, vtscan_param.mc4_addr, &mc4_ID); pdi5025_init(vtscan_param.board_addr, vtscan_param.pdi5025_addr, &pdi5025_ID); pdi5025_set_linear_encoder_trigger(pdi5025_ID, 0); } else if (vtscan_param.config == VTSCAN_MC4_K7011_PDI5025) { mc4_init(vtscan_param.board_addr, vtscan_param.mc4_addr, &mc4_ID); k7011_init(vtscan_param.board_addr, vtscan_param.k7011_addr, &k7011_ID); pdi5025_init(vtscan_param.board_addr, vtscan_param.pdi5025_addr, &pdi5025_ID); pdi5025_set_linear_encoder_trigger(pdi5025_ID, 0); } else { vtscan_error("Unknown integrated voltage system configuration"); return; } /* Set the zero position of the wire */ vtscan_set_zero_pos(); /* Done */ return; } /* ************************************************************** */ /* * vtscan_close_mux_chan * This function is used to select a multiplexer channel * to route the signal to the integrator. * * Input: * mux_chan, multiplexer channel (0 to open all channels) * * Zachary Wolf * 9/1/00 */ void vtscan_close_mux_chan(int mux_chan) { /* Declare variables */ int err; /* Check the configuration, exit if a multiplexer is not being used */ if (vtscan_param.config != VTSCAN_MC4_K7011_PDI5025) { //vtscan_error("vtscan_close_mux_chan: wrong configuration"); return; } /* Check the input parameters */ if (mux_chan < 0 || mux_chan > 40) { vtscan_error("vtscan_close_mux_chan: unknown channel"); return; } /* Open all multiplexer channels so two channels can not be simultaneously closed */ k7011_open_all(k7011_ID); /* Close the desired channel */ if (mux_chan > 0) k7011_close_card_chan(k7011_ID, 1, mux_chan); /* Done */ return; } /* ************************************************************** */ /* * vtscan_set_gain * This function is used to set the gain of the Metrolab integrator. * * Input: * gain, integrator gain, 1, 2, 5, 10, 20, 50, 100, 200, 500, 1000 * * Zachary Wolf * 8/24/99 */ void vtscan_set_gain(int gain) { /* Check the configuration */ if (vtscan_param.config != VTSCAN_MC4_PDI5025 && vtscan_param.config != VTSCAN_MC4_K7011_PDI5025) { vtscan_error("vtscan_set_gain: wrong configuration"); return; } /* Check input parameters */ if (gain != 1 && gain != 2 && gain != 5 && gain != 10 && gain != 20 && gain != 50 && gain != 100 && gain != 200 && gain != 500 && gain != 1000) { Fmt(msg, "%s 1.) { vtscan_error("vtscan_get_vt: x_start has improper value"); return; } if (fabs(dx) < 1.e-6 || fabs(dx) > 1.) { vtscan_error("vtscan_get_vt: dx has improper value"); return; } if (num_samp < 1 || num_samp > 5000) { vtscan_error("vtscan_get_vt: num_samp has improper value"); return; } /* Check the configuration */ if (vtscan_param.config != VTSCAN_MC4_PDI5025 && vtscan_param.config != VTSCAN_MC4_K7011_PDI5025) { vtscan_error("vtscan_get_vt: unknown configuration"); return; } /* Check all module level parameter values */ err = vtscan_check_param(); if (err != 0) { vtscan_error("Problem with parameter values"); return; } /* Compute sampling parameters */ dist_btwn_samples = fabs(dx) / num_samp; enc_num_pulse_btwn_samp = (int)(dist_btwn_samples / vtscan_param.dist_btwn_enc_pulse); if (fmod(dist_btwn_samples, vtscan_param.dist_btwn_enc_pulse) >= .5) enc_num_pulse_btwn_samp++; if (enc_num_pulse_btwn_samp == 0) enc_num_pulse_btwn_samp = 1; if (dx >= 0) sign = 1.; else sign = -1.; if (VTSCAN_REL_ENC_DIR == 1) { if (dx >= 0) dir = '+'; else dir = '-'; enc_start_pulse = sign * enc_num_pulse_btwn_samp; } else if (VTSCAN_REL_ENC_DIR == -1) { if (dx >= 0) dir = '-'; else dir = '+'; enc_start_pulse = -sign * enc_num_pulse_btwn_samp; } else vtscan_error("Improper VTSCAN_REL_ENC_DIR"); /* Move to the starting point */ mc4_abs_2_stage_move(mc4_ID, vtscan_param.mc4_axis1, vtscan_param.mc4_axis2, vtscan_param.wire_acc, vtscan_param.wire_vel, x_start); /* Begin sampling */ if (vtscan_param.config == VTSCAN_MC4_PDI5025 || vtscan_param.config == VTSCAN_MC4_K7011_PDI5025) { pdi5025_get_VT_linear_encoder_start(pdi5025_ID, vtscan_param.pdi5025_channel, vtscan_param.pdi5025_gain, dir, enc_start_pulse, enc_num_pulse_btwn_samp, num_samp); } /* Move the wire a little past dx so all triggers are received */ if (dx >= 0.) dist = dx + .002; else dist = dx - .002; mc4_rel_2_stage_move(mc4_ID, vtscan_param.mc4_axis1, vtscan_param.mc4_axis2, vtscan_param.wire_acc, vtscan_param.wire_vel, dist); /* Get the samples */ if (vtscan_param.config == VTSCAN_MC4_PDI5025 || vtscan_param.config == VTSCAN_MC4_K7011_PDI5025) { pdi5025_get_VT_linear_encoder_finish(pdi5025_ID, num_samp, vt); } /* Calculate the x positions of the samples */ x[0] = x_start; for (i = 1; i <= num_samp; i++) x[i] = x[0] + sign * i * enc_num_pulse_btwn_samp * vtscan_param.dist_btwn_enc_pulse; /* Log the measurement */ vtscan_log_vt(x_start, dx, num_samp, x, vt); /* Done */ return; } /* ************************************************************** */ /* * vtscan_move_wire_abs * This function is used by higher level functions to move the * wire to a desired position. * * Input: * x_pos, nominal position to move the wire to (m) * * Zachary Wolf * 12/13/99 */ void vtscan_move_wire_abs(double x_pos) { /* Declare variables */ int err; /* Check the configuration */ if (vtscan_param.config != VTSCAN_MC4_PDI5025 && vtscan_param.config != VTSCAN_MC4_K7011_PDI5025) { vtscan_error("vtscan_get_vt: unknown configuration"); return; } /* Check all parameter values */ err = vtscan_check_param(); if (err != 0) { vtscan_error("Problem with parameter values"); return; } /* Move to the desired position */ mc4_abs_2_stage_move(mc4_ID, vtscan_param.mc4_axis1, vtscan_param.mc4_axis2, vtscan_param.wire_acc, vtscan_param.wire_vel, x_pos); /* Done */ return; } /* ************************************************************** */ /* * vtscan_set_zero_pos * This function has the user move the wire to the zero position * and then it zeros the stages. * * Zachary Wolf * 2/7/00 */ void vtscan_set_zero_pos(void) { /* Declare variables */ int err; char buf[80]; /* Check the configuration */ if (vtscan_param.config != VTSCAN_MC4_PDI5025 && vtscan_param.config != VTSCAN_MC4_K7011_PDI5025) { vtscan_error("vtscan_set_zero_pos: unknown configuration"); return; } /* Check all parameter values */ err = vtscan_check_param(); if (err != 0) { vtscan_error("Problem with parameter values"); return; } /* Have the user move the wire to the zero position by hand */ printf("\nPlease move the stages to the zero position.\n"); printf("The position readout and display will be zeroed.\n"); printf("Press ENTER to continue."); Beep(); fgets(buf, 80, stdin); /* Zero the stages */ if (vtscan_param.config == VTSCAN_MC4_PDI5025 || vtscan_param.config == VTSCAN_MC4_K7011_PDI5025) { mc4_zero(mc4_ID); } /* Done */ return; } /* ************************************************************** */ /* * vtscan_zero_pos * This function zeros the stages. * * Zachary Wolf * 4/18/01 */ void vtscan_zero_pos(void) { /* Declare variables */ int err; /* Check the configuration */ if (vtscan_param.config != VTSCAN_MC4_PDI5025 && vtscan_param.config != VTSCAN_MC4_K7011_PDI5025) { vtscan_error("vtscan_zero_pos: unknown configuration"); return; } /* Check all parameter values */ err = vtscan_check_param(); if (err != 0) { vtscan_error("Problem with parameter values"); return; } /* Zero the stages */ if (vtscan_param.config == VTSCAN_MC4_PDI5025 || vtscan_param.config == VTSCAN_MC4_K7011_PDI5025) { mc4_zero(mc4_ID); } /* Done */ return; } /* ************************************************************** */ /* * vtscan_protect * This function is used to protect the integrated voltage system * from overvoltages due to ramping a magnet, etc. * * Zachary Wolf * 8/24/99 */ void vtscan_protect(void) { /* Set the integrator gain to 1 */ if (vtscan_param.config == VTSCAN_MC4_PDI5025 || vtscan_param.config == VTSCAN_MC4_K7011_PDI5025) pdi5025_set_gain(pdi5025_ID, vtscan_param.pdi5025_channel, 1); /* If using a multiplexer, open all channels */ if (vtscan_param.config == VTSCAN_MC4_K7011_PDI5025) k7011_open_all(k7011_ID); /* Done */ return; } /* ************************************************************** */ /* * vtscan_exit * This function is used to exit the integrated voltage * measurement system. * * Zachary Wolf * 11/9/99 */ void vtscan_exit(void) { /* Set the integrator gain to 1, open all multiplexer channels */ vtscan_protect(); /* Exit the hardware */ if (vtscan_param.config == VTSCAN_MC4_PDI5025) { mc4_exit(mc4_ID); pdi5025_exit(pdi5025_ID); } else if (vtscan_param.config == VTSCAN_MC4_K7011_PDI5025) { mc4_exit(mc4_ID); k7011_exit(k7011_ID); pdi5025_exit(pdi5025_ID); } else { vtscan_error("Unknown integrated voltage system configuration"); return; } /* Done */ return; } /* ************************************************************** */ /* INTERNAL FUNCTIONS */ /* ************************************************************** */ /* * vtscan_error * This function handles errors for the VTSCAN module. * * Input: * message, string to display in standard I/O * * Zachary Wolf * 10/11/98 */ void vtscan_error(char* message) { /* Declare variables */ char buf[80]; /* Notify the operator of the error */ printf("\nVTSCAN ERROR: %s\n", message); Beep(); Delay(.5); Beep(); /* Terminate the program if the operator desires */ printf("Press ENTER to continue.\nPress any key then ENTER to terminate program.\n"); fgets(buf, 80, stdin); if (buf[0] == '\n') return; else exit(0); } /* ************************************************************** */ /* * vtscan_message * This function handles messages for the IMAG module. * * Input: * message, string to display in standard I/O * * Zachary Wolf * 10/12/98 */ void vtscan_message(char* message) { /* Print the message */ printf("%s\n", message); /* Done */ return; } /* ************************************************************** */ /* * vtscan_check_param * This function checks that all required parameters have been assigned * appropriate values. * * Output: * err, 0 = no error, non-zero = error * * Zachary Wolf * 8/11/98 */ int vtscan_check_param() { /* log_file */ if (CompareStrings(log_file, 0, "", 0, 0) == 0) { vtscan_error("Log file not defined."); return -1; } /* vtscan_param.board_addr */ if (vtscan_param.board_addr < 0 || vtscan_param.board_addr > 10) { Fmt(msg, "%s 30) { Fmt(msg, "%s 30) { Fmt(msg, "%s 1000) { Fmt(msg, "%s .01) { Fmt(msg, "%s .05) { Fmt(msg, "%s .05) { Fmt(msg, "%s