/* ************************************************************** */ /* * Module VTWIRE * This module contains functions to make integrated voltage * measurements from a moving wire. * * Zachary Wolf * 8/16/98 */ /* ************************************************************** */ /* INCLUDES */ #include #include #include #include #include #include "vtwire.h" #include "vtwireui.h" #include "mc4.h" #include "pdi5025.h" #include "hp3458.h" /* ************************************************************** */ /* PRIVATE PARAMETERS */ static char log_file[100]; static struct vtwire_param_struct vtwire_param; /* ************************************************************** */ /* PRIVATE GLOBAL VARIABLES */ static int mc4_ID; static int pdi5025_ID; static int hp3458_ID; static char msg[80]; /* ************************************************************** */ /* PRIVATE FUNCTIONS */ int vtwire_check_param(void); void vtwire_error(char* message); void vtwire_message(char* message); void vtwire_offset_correction(double delta_t_samp, int num_samp, double v_samp[], double vt_samp[]); void vtwire_log_meas(void); void vtwire_log_vt(double x0, double dx, double vt); void vtwire_log_vt_ave(double x0, double dx, double vt_ave, double vt_rms); void vtwire_log_offset_correction(double v_offset_ini, double v_offset_fin); /* ************************************************************** */ /* PUBLIC FUNCTIONS */ /* ************************************************************** */ /* * vtwire_init * This function is used to initialize the integrated voltage * measurement system. * * Zachary Wolf * 8/16/99 */ void vtwire_init(char log_file_in[], struct vtwire_param_struct vtwire_par) { /* Declare variables */ int err; /* Save parameters for future use */ strcpy(log_file, log_file_in); vtwire_param = vtwire_par; /* Check all parameter values to find any problems */ err = vtwire_check_param(); if (err != 0) { vtwire_error("Problem with parameter values"); return; } /* Initialize the required hardware */ if (vtwire_param.config == VTWIRE_MC4_PDI5025) { mc4_init(vtwire_param.board_addr, vtwire_param.mc4_addr, &mc4_ID); pdi5025_init(vtwire_param.board_addr, vtwire_param.pdi5025_addr, &pdi5025_ID); } else if (vtwire_param.config == VTWIRE_MC4_HP3458) { mc4_init(vtwire_param.board_addr, vtwire_param.mc4_addr, &mc4_ID); hp3458_init(vtwire_param.board_addr, vtwire_param.hp3458_addr, &hp3458_ID); } else { vtwire_error("Unknown integrated voltage system configuration"); return; } /* Have the operator set the zero position of the wire */ vtwire_set_zero_pos(); /* Done */ return; } /* ************************************************************** */ /* * vtwire_get_vt * This function measures the integrated voltage from a wire as it * is moved. The integrator gain or voltmeter range must already be set. * * Input: * x0, nominal center position about which the wire moves (m) * dx, nominal distance the wire moves, sign gives the direction (m) * * Output: * vt, the integrated voltage from the wire (Vs) * * Zachary Wolf * 8/17/99 */ void vtwire_get_vt(double x0, double dx, double* vt) { /* Declare variables */ int err; double samp_time; int num_samp; double delta_t_samp; double vt_samp[VTWIRE_MAX_NUM_SAMP + 1] = {0}; double v_samp[VTWIRE_MAX_NUM_SAMP + 1] = {0}; int i; int num_ave; double sum; /* Check the configuration */ if (vtwire_param.config != VTWIRE_MC4_PDI5025 && vtwire_param.config != VTWIRE_MC4_HP3458) { vtwire_error("vtwire_get_vt: unknown configuration"); return; } /* Check all parameter values */ err = vtwire_check_param(); if (err != 0) { vtwire_error("Problem with parameter values"); return; } /* Compute sampling parameters */ /* Sample every 2 power line cycles, leave time for the HP3458 to store the samples */ samp_time = vtwire_param.t_samp_before + (fabs(dx) / vtwire_param.wire_vel) + vtwire_param.t_samp_after; num_samp = (samp_time * 30) - 1; if (num_samp > VTWIRE_MAX_NUM_SAMP) { printf("vtwire_get_vt: the number of samples is too large, will set to maximum value\n"); num_samp = VTWIRE_MAX_NUM_SAMP; } delta_t_samp = samp_time / (double)num_samp; /* Move to the starting point */ mc4_abs_2_stage_move(mc4_ID, vtwire_param.mc4_axis1, vtwire_param.mc4_axis2, vtwire_param.wire_acc, vtwire_param.wire_vel, x0 - (dx / 2.)); /* Begin sampling */ if (vtwire_param.config == VTWIRE_MC4_PDI5025) { pdi5025_get_VT_timer_start(pdi5025_ID, vtwire_param.pdi5025_channel, vtwire_param.pdi5025_gain, delta_t_samp, num_samp); } if (vtwire_param.config == VTWIRE_MC4_HP3458) { hp3458_setup_timed_voltage_samples(hp3458_ID, vtwire_param.hp3458_range, 2., num_samp, delta_t_samp); /* Integrate over 2 power line cycles, must agree with sampling parameter calculations above */ hp3458_trigger_timed_voltage_samples(hp3458_ID); } /* Wait before moving the wire */ Delay(vtwire_param.t_samp_before); /* Move the wire */ mc4_rel_2_stage_move_time_critical(mc4_ID, vtwire_param.mc4_axis1, vtwire_param.mc4_axis2, vtwire_param.wire_acc, vtwire_param.wire_vel, dx); /* Wait after moving the wire */ Delay(vtwire_param.t_samp_after); /* Get the samples */ if (vtwire_param.config == VTWIRE_MC4_PDI5025) { pdi5025_get_VT_timer_finish(pdi5025_ID, num_samp, vt_samp); /* vt[0] = 0, vt[1 to num_samp] are samples */ } if (vtwire_param.config == VTWIRE_MC4_HP3458) { hp3458_collect_timed_voltage_samples(hp3458_ID, num_samp, v_samp); /* v[0 to num_samp - 1] are samples */ } /* When using an integrator, compute voltage samples */ /* v[0 to n-1], vt[0 to n], throw out vt[n] so use vt[0 to n-1] */ if (vtwire_param.config == VTWIRE_MC4_PDI5025) { for (i = 0; i < num_samp; i++) v_samp[i] = (vt_samp[i+1] - vt_samp[i]) / delta_t_samp; } /* When using a voltmeter, compute integrated voltage samples */ /* v[0 to n-1], vt[0 to n-1] */ if (vtwire_param.config == VTWIRE_MC4_HP3458) { vt_samp[0] = 0.; for (i = 1; i < num_samp; i++) vt_samp[i] = vt_samp[i-1] + 0.5 * (v_samp[i] + v_samp[i-1]) * delta_t_samp; } /* Perform an offset correction */ vtwire_offset_correction(delta_t_samp, num_samp, v_samp, vt_samp); /* Update the user interface */ if (vtwire_param.show_ui == VTWIRE_TRUE) vtwireui_update(delta_t_samp, num_samp, v_samp, vt_samp); /* Return the integrated voltage, average over the last couple readings */ num_ave = 15; sum = 0.; for (i = 1; i <= num_ave; i++) sum = sum + vt_samp[num_samp - i]; *vt = sum / (double) num_ave; /* Log the measurement */ vtwire_log_vt(x0, dx, *vt); /* Done */ return; } /* ************************************************************** */ /* * vtwire_get_vt_ave * This function measures the integrated voltage from the wire * several times and returns the average and rms variation. * * Input: * x0, center position about which the wire moves (m) * dx, distance the wire moves (m) * * Output: * vt_ave, average of the integrated voltage measurements (Vs) * vt_rms, rms variation of the integrated voltage measurements (Vs) * * Zachary Wolf * 9/2/99 */ void vtwire_get_vt_ave(double x0, double dx, double* vt_ave, double* vt_rms) { /* Declare variables */ int err; int i; double vt_pos, vt_neg; double vt_measurements[VTWIRE_MAX_NUM_MEAS]; /* Check all parameters */ err = vtwire_check_param(); if (err != 0) { vtwire_error("Problem with parameter values"); return; } /* Log the measurement */ vtwire_log_meas(); /* Loop over measurements for averaging */ for (i = 1; i <= vtwire_param.num_meas_ave; i++) { /* Get the integrated voltage for a + move */ vtwire_get_vt(x0, dx, &vt_pos); /* Get the integrated voltage for a - move */ vtwire_get_vt(x0, -dx, &vt_neg); /* Save the average of VT+ and VT- */ vt_measurements[i - 1] = (vt_pos - vt_neg) / 2.; /* End the loop over the measurements */ } /* Compute the average and rms variation of the measurements */ StdDev(vt_measurements, vtwire_param.num_meas_ave, vt_ave, vt_rms); /* Log the result */ vtwire_log_vt_ave(x0, dx, *vt_ave, *vt_rms); /* Message */ printf("\nIntegrated Voltage From The Wire:\n"); printf("X0 = %f m\n", x0); printf("Delta X = %f m\n", dx); printf("VT = %f +- %f Vs\n", *vt_ave, *vt_rms); /* Done */ return; } /* ************************************************************** */ /* * vtwire_move_wire_abs * This function is used by higher level functions to move the * wire to a desired position. * * Input: * x0, nominal position to move the wire to (m) * * Zachary Wolf * 12/13/99 */ void vtwire_move_wire_abs(double x0) { /* Declare variables */ int err; /* Check the configuration */ if (vtwire_param.config != VTWIRE_MC4_PDI5025 && vtwire_param.config != VTWIRE_MC4_HP3458) { vtwire_error("vtwire_get_vt: unknown configuration"); return; } /* Check all parameter values */ err = vtwire_check_param(); if (err != 0) { vtwire_error("Problem with parameter values"); return; } /* Move to the desired position */ mc4_abs_2_stage_move(mc4_ID, vtwire_param.mc4_axis1, vtwire_param.mc4_axis2, vtwire_param.wire_acc, vtwire_param.wire_vel, x0); /* Done */ return; } /* ************************************************************** */ /* * vtwire_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 vtwire_set_zero_pos(void) { /* Declare variables */ int err; char buf[80]; /* Check the configuration */ if (vtwire_param.config != VTWIRE_MC4_PDI5025 && vtwire_param.config != VTWIRE_MC4_HP3458) { vtwire_error("vtwire_get_vt: unknown configuration"); return; } /* Check all parameter values */ err = vtwire_check_param(); if (err != 0) { vtwire_error("Problem with parameter values"); return; } /* Have the user move the wire to the zero position by hand */ printf("\nPlease move the wire 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 (vtwire_param.config == VTWIRE_MC4_PDI5025 || vtwire_param.config == VTWIRE_MC4_HP3458) { mc4_zero(mc4_ID); } /* Done */ return; } /* ************************************************************** */ /* * vtwire_zero_pos * This function zeros the stages. * * Zachary Wolf * 4/18/01 */ void vtwire_zero_pos(void) { /* Declare variables */ int err; /* Check the configuration */ if (vtwire_param.config != VTWIRE_MC4_PDI5025 && vtwire_param.config != VTWIRE_MC4_HP3458) { vtwire_error("vtwire_get_vt: unknown configuration"); return; } /* Check all parameter values */ err = vtwire_check_param(); if (err != 0) { vtwire_error("Problem with parameter values"); return; } /* Zero the stages */ if (vtwire_param.config == VTWIRE_MC4_PDI5025 || vtwire_param.config == VTWIRE_MC4_HP3458) { mc4_zero(mc4_ID); } /* Done */ return; } /* ************************************************************** */ /* * vtwire_exit * This function is used to exit the integrated voltage * measurement system. * * Zachary Wolf * 11/9/99 */ void vtwire_exit(void) { /* Exit the hardware */ if (vtwire_param.config == VTWIRE_MC4_PDI5025) { mc4_exit(mc4_ID); pdi5025_exit(pdi5025_ID); } else if (vtwire_param.config == VTWIRE_MC4_HP3458) { mc4_exit(mc4_ID); hp3458_exit(hp3458_ID); } else { vtwire_error("Unknown integrated voltage system configuration"); return; } /* Done */ return; } /* ************************************************************** */ /* INTERNAL FUNCTIONS */ /* ************************************************************** */ /* * vtwire_error * This function handles errors for the VTWIRE module. * * Input: * message, string to display in standard I/O * * Zachary Wolf * 10/11/98 */ void vtwire_error(char* message) { /* Declare variables */ char buf[80]; /* Notify the operator of the error */ printf("\nVTWIRE 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); } /* ************************************************************** */ /* * vtwire_message * This function handles messages for the IMAG module. * * Input: * message, string to display in standard I/O * * Zachary Wolf * 10/12/98 */ void vtwire_message(char* message) { /* Print the message */ printf("%s\n", message); /* Done */ return; } /* ************************************************************** */ /* * vtwire_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 vtwire_check_param() { /* log_file */ if (CompareStrings(log_file, 0, "", 0, 0) == 0) { vtwire_error("Log file not defined."); return -1; } /* vtwire_param.board_addr */ if (vtwire_param.board_addr < 0 || vtwire_param.board_addr > 10) { Fmt(msg, "%s 30) { Fmt(msg, "%s 30) { Fmt(msg, "%s 30) { Fmt(msg, "%s 1000) { Fmt(msg, "%s 1.) { Fmt(msg, "%s 5.) { Fmt(msg, "%s 5.) { Fmt(msg, "%s .05) { Fmt(msg, "%s .05) { Fmt(msg, "%s 20) { Fmt(msg, "%s