#include // ***************************************************************************************** // // Module HP3458 // This module contains I/O functions for the HP3458 multimeter. // // Zachary Wolf & Seva // 8/3/07 // static char module_name[] = {"HP3458"}; //#define HP3458_BINARY // ***************************************************************************************** // To avoid compiling errors when using local copy of repository // locate local copy of repository.h file and change all pathes there // to your local copies location. Do not forget change location of repository.h // file in the project #include "repository.h" #include DELAY //adds most commonly used functions #include #include #include #include #include "hp3458.h" //public parameters declaration - software #include "hp3458_private.h"//private parameters declaration - hardware // ***************************************************************************************** // PRIVATE FUNCTIONS int hp3458_open_dev(int gpib_board_addr, int gpib_dev_addr); void hp3458_close_dev(int dev_ID); int hp3458_out(int dev_ID, char* buf); int hp3458_in(int dev_ID, char* buf); int hp3458_bin(int dev_ID); int hp3458_in_buf(int dev_ID, char* in_buf); int hp3458_serial_poll(int dev_ID, int* spoll); int hp3458_check_dev_open(int dev_ID); int hp3458_get_errors(int dev_ID); double GetDintValue(int idx, double scale); // ***************************************************************************************** // PRIVATE DEVICE TABLE // // This table allows several devices of the same type to be // used in the system. // dev_addr, contains the GPIB addresses of opened devices // dev_descr, contains the device descriptors of opened devices // dev_count, contains the number of devices open of this type static int dev_addr[HP3458_MAX_NUM_DEV + 1] = {-1}; static int dev_descr[HP3458_MAX_NUM_DEV + 1] = {-1}; static int dev_count = 0; // ***************************************************************************************** // PRIVATE GLOBAL VARIABLES // cmd, buffer for GPIB I/O strings // msg, buffer for messages to Standard I/O typedef union tag_CHAR_ULONG_BUFFER { DWORD dw[HP3458_MAX_IN_BUF_4]; char in_buf[HP3458_MAX_IN_BUF]; } CHAR_ULONG_BUFFER; static CHAR_ULONG_BUFFER inBuf; #define HP3458_MAX_CMD 128 //temporary buffer static double v_temp[HP3458_MAX_NUM_SAMPLES]; //private variable, use setBreak public function to terminate readings static int m_break = TRUE; // ***************************************************************************************** // ------------------------------------------------------------------------------------------ // ***************************************************************************************** // // ***************************************************************************************** // --- hp3458.c::hp3458_init --- //!\brief Opens the device, queries for ID, and initializes the device to a known state. //!\param int //!\param int //!\param int* //!\retval BOOL //!\author Seva // ***************************************************************************************** BOOL hp3458_init(int gpib_board_addr, int gpib_dev_addr, int* ID) { int dev_ID = 0; int err; char buf[HP3458_MAX_CMD]; message(""); message("Initializing the HP3458..."); // Check input parameters if (gpib_board_addr < 0 || gpib_board_addr > 10) { Fmt(buf, "%s 30) { Fmt(buf, "%s HP3458_MAX_NUM_DEV) { Fmt(buf, "%s%f", voltage); if (err != 1) { stop_error_msg(module_name,"Problem getting HP3458 voltage"); } #else hp3458_out(dev_ID, "OFORMAT DINT"); hp3458_out(dev_ID, "ISCALE?"); hp3458_in(dev_ID, buf); vScale = atof(buf); // Trigger the measurement hp3458_out(dev_ID, "TRIG SGL"); // Get the reading hp3458_bin(dev_ID); *voltage = GetDintValue(0,vScale); #endif } // // ***************************************************************************************** // --- hp3458.c::hp3458_get_frequency --- // //!\brief Gets the frequency of the voltage applied to the HP3458. //!\param int //!\param double* //!\retval void //!\author Seva // ***************************************************************************************** void hp3458_get_frequency(int dev_ID, double* frequency) { int dev_open = 0; int err = 0; char buf[HP3458_MAX_CMD] = {'\0'}; // Check input parameters if (dev_ID < 1 || dev_ID > HP3458_MAX_NUM_DEV) { Fmt(buf, "%s%f", frequency); if (err != 1) { stop_error_msg(module_name,"Problem getting HP3458 frequency"); } } // // ***************************************************************************************** // --- hp3458.c::hp3458_get_resistance --- //!\brief Measures the resistance of the device attached //!\param int //!\param double* //!\retval void //!\author Seva // ***************************************************************************************** void hp3458_get_resistance(int dev_ID, double* resistance) { int dev_open = 0; int err = 0; char buf[HP3458_MAX_CMD] = {'\0'}; // Check input parameters if (dev_ID < 1 || dev_ID > HP3458_MAX_NUM_DEV) { Fmt(buf, "%s%f", resistance); if (err != 1) { stop_error_msg(module_name,"Problem getting HP3458 resistance"); } // Put the DVM back in a high impedance state hp3458_out(dev_ID, "PRESET"); } // // ***************************************************************************************** // --- hp3458.c::hp3458_get_temperature --- // //!\brief Measures the temperature of an HP thermistor attached to the HP3458 //!\param int //!\param double* //!\retval void //!\author Seva // ***************************************************************************************** void hp3458_get_temperature(int dev_ID, double* temperature) { int dev_open = 0; int err = 0; char buf[HP3458_MAX_CMD] = {'\0'}; // Check input parameters if (dev_ID < 1 || dev_ID > HP3458_MAX_NUM_DEV) { Fmt(buf, "%s%f", temperature); if (err != 1) { stop_error_msg(module_name,"Problem getting HP3458 temperature"); } // Put the DVM back in a high impedance state hp3458_out(dev_ID, "PRESET"); } // // ***************************************************************************************** // --- hp3458.c::hp3458_setup_timed_voltage_samples --- // //!\brief Sets up voltmeter to sample the voltages //!\param int //!\param double //!\param double //!\param int //!\param double //!\retval void //!\author Seva // ***************************************************************************************** void hp3458_setup_timed_voltage_samples(int dev_ID, double v_range, double num_plc, int num_samples, double delta_t) { int dev_open; int err; char buf[HP3458_MAX_CMD]; // Check input parameters if (dev_ID < 1 || dev_ID > HP3458_MAX_NUM_DEV) { Fmt(buf, "%s HP3458_MAX_NUM_SAMPLES) { Fmt(buf, "%s 10) { Fmt(buf, "%s HP3458_MAX_NUM_DEV) { Fmt(buf, "%s HP3458_MAX_NUM_SAMPLES) { Fmt(buf, "%s 100) { Fmt(buf, "%s HP3458_MAX_NUM_DEV) { Fmt(buf, "%s HP3458_MAX_NUM_DEV) { Fmt(buf, "%s HP3458_MAX_NUM_SAMPLES) { Fmt(buf, "%s%i", &mcount); if (mcount != num_samples) { stop_error_msg(module_name,"Problem getting HP3458 voltages"); return; } // Put all the readings in the HP3458 output buffer Fmt(buf, "%s%*f[x]", num_samples, v_temp); if (err != 1) { stop_error_msg(module_name,"Problem getting HP3458 voltages"); } // Using RMEM, the order is last in first out, reverse the order for (i = 0; i < num_samples; i++) { voltages[i] = v_temp[num_samples - 1 - i]; if (voltages[i] == -1000.) stop_error_msg(module_name,"Problem getting HP3458 voltages"); } } // // ***************************************************************************************** // --- HP3458.c::hp3458_waitfor_timed_voltage_samples --- // //!\brief Waits for time samples to be collected //!\param int //!\retval none //!\author Seva // ***************************************************************************************** void hp3458_waitfor_timed_voltage_samples(int dev_ID) { int dev_open = 0; int err = 0; int spoll = 0; int mcount = 0; int i = 0; char buf[HP3458_MAX_CMD] = {'\0'}; // Check input parameters if (dev_ID < 1 || dev_ID > HP3458_MAX_NUM_DEV) { Fmt(buf, "%s HP3458_MAX_NUM_DEV) { Fmt(buf, "%s HP3458_MAX_NUM_SAMPLES) { Fmt(buf, "%s 1.) { Fmt(buf, "%s%i", &mcount); if (mcount != num_samples) { stop_error_msg(module_name,"Problem getting HP3458 voltages"); return; } // Put all the readings in the HP3458 output buffer Fmt(buf, "%s%*f[x]", num_samples, v_temp); if (err != 1) { stop_error_msg(module_name,"Problem getting HP3458 voltages"); return; } // Using RMEM, the order is last in first out, reverse the order for (i = 0; i < num_samples; i++) { voltages[i] = v_temp[num_samples - 1 - i]; if (voltages[i] == -1000.) stop_error_msg(module_name,"Problem getting HP3458 voltages"); } } // // ***************************************************************************************** // --- hp3458.c::hp3458_get_triggered_voltage_samples --- // //!\brief Generates samples, waiting for data, and read them //!\param int //!\param double //!\param double //!\param int //!\param double[] //!\retval void //!\author Seva // ***************************************************************************************** void hp3458_get_triggered_voltage_samples(int dev_ID, double v_range, double num_plc, int num_samples, double voltages[]) { int dev_open = 0; int err = 0; int spoll = 0; int mcount = 0; int i; char buf[HP3458_MAX_CMD] = {'\0'}; // Check input parameters if (dev_ID < 1 || dev_ID > HP3458_MAX_NUM_DEV) { Fmt(buf, "%s HP3458_MAX_NUM_SAMPLES) { Fmt(buf, "%s%i", &mcount); if (mcount != num_samples) { stop_error_msg(module_name,"Problem getting HP3458 voltages: mcount!=num_samples"); return; } // Put the readings in the HP3458 output buffer Fmt(buf, "%s%*f[x]", num_samples, v_temp); if (err != 1) { stop_error_msg(module_name,"Problem getting HP3458 voltages"); } // Using RMEM, the order is last in first out, reverse the order for (i = 0; i < num_samples; i++) { voltages[i] = v_temp[num_samples - 1 - i]; if (voltages[i] == -1000.) stop_error_msg(module_name,"Problem getting HP3458 voltages"); } } // // ***************************************************************************************** // --- hp3458.c::hp3458_setup_triggered_voltage_samples --- // //!\brief Setup device for externally triggered voltage samples //!\param int //!\param double //!\param double //!\param int //!\retval void //!\author Seva // ***************************************************************************************** void hp3458_setup_triggered_voltage_samples(int dev_ID, double v_range, double num_plc, int num_samples) { int dev_open = 0; int err = 0; char buf[HP3458_MAX_CMD] = {'\0'}; // Check input parameters if (dev_ID < 1 || dev_ID > HP3458_MAX_NUM_DEV) { Fmt(buf, "%s HP3458_MAX_NUM_SAMPLES) { Fmt(buf, "%s HP3458_MAX_NUM_DEV) { Fmt(buf, "%s HP3458_MAX_NUM_SAMPLES) { Fmt(buf, "%s 100) { Fmt(buf, "%s 1000) { Fmt(buf, "%s HP3458_MAX_NUM_DEV) { Fmt(buf, "%s HP3458_MAX_NUM_SAMPLES) { Fmt(buf, "%s HP3458_MAX_NUM_DEV) { Fmt(buf, "%s HP3458_MAX_NUM_DEV) { Fmt(buf, "%s HP3458_MAX_NUM_SAMPLES) { Fmt(buf, "%s%i", &mcount); if (mcount != num_samples) stop_error_msg(module_name,"Problem getting HP3458 voltages"); // Put all the readings in the HP3458 output buffer Fmt(buf, "%s%*f[x]", num_samples, v_temp); if (err != 1) { stop_error_msg(module_name,"Problem getting HP3458 voltages"); } // Using RMEM, the order is last in first out, reverse the order for (i = 0; i < num_samples; i++) { voltages[i] = v_temp[num_samples - 1 - i]; if (voltages[i] == -1000.) stop_error_msg(module_name,"Problem getting HP3458 voltages"); } return 0; } // // ***************************************************************************************** // --- hp3458.c::hp3458_collect_triggered_voltages --- // //!\brief Collects the triggered voltage samples //!\param int //!\param int //!\param double[] //!\retval void //!\author Seva // ***************************************************************************************** void hp3458_collect_triggered_voltages(int dev_ID, int num_samples, double voltages[]) { int dev_open = 0; int err = 0; int spoll = 0; int mcount = 0; long i = 0; float res =0.; int it=0; char t[4]= {0,0,0,0}; char buf[HP3458_MAX_CMD] = {'\0'}; // Check input parameters if (dev_ID < 1 || dev_ID > HP3458_MAX_NUM_DEV) { Fmt(buf, "%s HP3458_MAX_NUM_SAMPLES) { Fmt(buf, "%s%i", &mcount); if (mcount != num_samples) stop_error_msg(module_name,"Problem getting HP3458 voltages"); // Put the readings in the HP3458 output buffer Fmt(buf, "%s%*f[x]", num_samples, v_temp); // if (err != 1) // { // hp3458_error("Problem getting HP3458 voltages"); // } // Using RMEM, the order is last in first out, reverse the order for (i = 0; i < num_samples; i++) { t[0] = inBuf.in_buf[i*4]; t[1] = inBuf.in_buf[i*4+1]; t[2] = inBuf.in_buf[i*4+2]; t[3] = inBuf.in_buf[i*4+3]; //reverse order inBuf.in_buf[i*4] = t[3]; inBuf.in_buf[i*4+1] = t[2]; inBuf.in_buf[i*4+2] = t[1]; inBuf.in_buf[i*4+3] = t[0]; //reverse bytes order in words /* inBuf.in_buf[i*4] = t[1]; inBuf.in_buf[i*4+1] = t[0]; inBuf.in_buf[i*4+2] = t[3]; inBuf.in_buf[i*4+3] = t[2];*/ //reverse bytes order in reverse words /* inBuf.in_buf[i*4] = t[2]; inBuf.in_buf[i*4+1] = t[3]; inBuf.in_buf[i*4+2] = t[0]; inBuf.in_buf[i*4+3] = t[1];*/ res = inBuf.dw[i]; it = t[0]; it = t[1]; it = t[2]; it = t[3]; voltages[i] = inBuf.dw[i];//v_temp[num_samples - 1 - i]; if (voltages[i] == -1000.) stop_error_msg(module_name,"Problem getting HP3458 voltages"); } } // // ***************************************************************************************** // --- hp3458.c::hp3458_exit --- // //!\brief Leaves the HP3458 in a desired state and closes the device. //!\retval void //!\author Seva // ***************************************************************************************** void hp3458_exit(int dev_ID) { int dev_open = 0; char buf[HP3458_MAX_CMD] = {'\0'}; m_break = TRUE; // Check input parameters if (dev_ID < 1 || dev_ID > HP3458_MAX_NUM_DEV) { Fmt(buf, "%s 10) { Fmt(buf, "%s 30) { Fmt(buf, "%s%s[t-]", buf); return 0; } // // ***************************************************************************************** // --- hp3458.c::hp3458_bin --- // //!\brief Reads a binary buffer of data from the device //!\param int //!\param char[] //!\retval int //!\author Seva // ***************************************************************************************** int hp3458_bin(int dev_ID) { int err = 0; char buf[HP3458_MAX_CMD]; // Read the message err = ibrd(dev_descr[dev_ID], &inBuf.dw[0], 4); // Check for errors if (err & 0x8000) { Fmt(buf, "%s%s[t-]", buf); return 0; } // // ***************************************************************************************** // --- hp3458.c::hp3458_serial_poll --- // //!\brief A serial poll of the device. A value of 16 indicates the HP3458 is ready for //\a command. A value of 32 indicates an error. //!\param int //!\param int* //!\retval int //!\author Seva // ***************************************************************************************** int hp3458_serial_poll(int dev_ID, int* spoll) { int err = 0; char spoll_char = 0; char buf[HP3458_MAX_CMD]; // Perform the serial poll err = ibrsp(dev_descr[dev_ID], &spoll_char); // Check for errors if (err & 0x8000) { Fmt(buf, "%s%i", spoll); return 0; } // // ***************************************************************************************** // --- hp3458.c::hp3458_check_dev_open --- // //!\brief Checks whether device is open. If it is opened, a 1 is returned, 0 otherwise. //!\param int //!\retval int //!\author Seva // ***************************************************************************************** int hp3458_check_dev_open(int dev_ID) { // See if the board descriptor has a positive value if (dev_descr[dev_ID] > 0) { return 1; // Open } else { return 0; // Not open } } // // ***************************************************************************************** // --- hp3458.c::hp3458_get_errors --- //!\brief Get device errors //!\param int //!\retval int //!\author Seva // ***************************************************************************************** int hp3458_get_errors(int dev_ID) { int status = 0; char buf[HP3458_MAX_CMD]= {'\0'}; // char error_descr[HP3458_MAX_CMD]= {'\0'}; // Get the HP3458 error status hp3458_out(dev_ID, "ERRSTR?"); hp3458_in(dev_ID, buf); // Extract the status value Scan (buf, "%s>%i[w1]", &status); //, error_descr // Alert the operator if there is an error if (status != 0) { stop_error_msg(module_name,buf); return -1; } return 0; } // // ***************************************************************************************** // --- Hp3458.c::GetDintValue --- // //!\brief Converts binary DINT output to double and applies scale //!\param int - index //!\param double - scale //!\retval double //!\author Seva // ***************************************************************************************** double GetDintValue(int idx, double scale) { DWORD dw = 0; char t[4]; long res = 0; double retVal = 0.; idx*=4; t[0] = inBuf.in_buf[idx]; t[1] = inBuf.in_buf[idx+1]; t[2] = inBuf.in_buf[idx+2]; t[3] = inBuf.in_buf[idx+3]; //reverse order inBuf.in_buf[idx] = t[3]; inBuf.in_buf[idx+1] = t[2]; inBuf.in_buf[idx+2] = t[1]; inBuf.in_buf[idx+3] = t[0]; dw = inBuf.dw[idx]; if(dw&(0x80000000)) { res = -((long)(0x80000000-(dw&0x7fffffff))); } else { res = (long)(dw&0xfffffff); } retVal = ((double)(res)*scale); return retVal; } // // ***************************************************************************************** // --- hp3458.c::hp3458_is_dev_open --- // //!\brief Checks whether device is open using address //!\param int //!\retval int //!\author Seva // ***************************************************************************************** int hp3458_is_dev_open(int dev_address) { int i = 0; for (i = 1; i <= HP3458_MAX_NUM_DEV; i++) { if (dev_addr[i] == dev_address) { return 1; } } return 0; } // // ***************************************************************************************** // --- hp3458.c::hp_3458_setBreak --- // //!\brief Set break parameter //!\param int //!\retval none //!\author Seva // ***************************************************************************************** void hp3458_setBreak(int set) { m_break = set; } // // ***************************************************************************************** // --- hp3458.c::hp_3458_GetMaxSamplesNumber --- // //!\brief Get maximum samples number //!\param none //!\retval int //!\author Seva // ***************************************************************************************** int hp_3458_GetMaxSamplesNumber(void) { return HP3458_MAX_NUM_SAMPLES; } // // ***************************************************************************************** // --- hp3458.c::hp3458_set_voltmeter --- // //!\brief Set range and voltage averaging time //!\param int //!\param double //!\param double //!\retval void //!\author Seva // ***************************************************************************************** void hp3458_set_voltmeter(int dev_ID, double v_range, double num_plc) { int dev_open = -1; int err = 0; int spoll = 0; int i; char buf[HP3458_MAX_CMD]; // Check input parameters if (dev_ID < 1 || dev_ID > HP3458_MAX_NUM_DEV) { Fmt(buf, "%s