光束分析仪BP209-IR/M的动态库TLBP2_32.dll得通信调用
By
admin
at 2021-04-13 • 1人收藏 • 1158人看过
最近用到这个设备, 这里写下调用的时候遇到的问题和解决方法.
这里先贴出来C语言的调用示例
//============================================================================== // // Title: CSample // Purpose: A short description of the command-line tool. // // Created on: 16.05.2013 at 14:01:49 by tempinstall. // Copyright: . All Rights Reserved. // //============================================================================== //============================================================================== // Include files #include <ansi_c.h> #include "TLBP2.h" //============================================================================== // Constants #define MAX_INSTRUMENTS 10 // max. 10 instruments in selection list #define BP2_BUFFER_SIZE 256 // General buffer size #define BP2_TIMEOUT_MAX 60000 #define BP2_MAX_SLIT_COUNT 4 //============================================================================== // Types //============================================================================== // Static global variables ViSession m_handle; ViUInt16 m_wavelength_min; ViUInt16 m_wavelength_max; ViReal64 m_wavelength; BP2_SLIT_DATA m_slitData[7500]; BP2_CALCULATIONS m_calculationResults[256]; ViReal64 m_power; ViUInt8 m_slitUsed[BP2_MAX_SLIT_COUNT]; ViUInt8 m_slitLength[BP2_MAX_SLIT_COUNT]; ViUInt8 m_slitWidth[BP2_MAX_SLIT_COUNT]; ViUInt8 m_slitOrientation[BP2_MAX_SLIT_COUNT]; BP2_SLIT_DATA slit_data[4]; ///< BP2_MAX_SLIT_COUNT = 4 BP2_CALCULATIONS calculation_result[4]; //ViReal64 power; ViReal32 powerSaturation; ViReal64 power_intensities[7500]; //============================================================================== // Static functions // prints the error message from an error code static void print_error_msg(ViStatus errorCode) { char messageBuffer[256]; // Get error string TLBP2_error_message(m_handle, errorCode, messageBuffer); if((errorCode & _VI_ERROR) == 0) // just a scan warning, no error printf("Beam Profiler Warning: %s\n", messageBuffer); else // errors { printf("Beam Profiler Error: %s\n", messageBuffer); // close instrument after an error has occured if (m_handle > 0) TLBP2_close(m_handle); } } //============================================================================== // Global variables //============================================================================== // Global functions int main (int argc, char *argv[]) { BP2_DEVICE* resStr = VI_NULL; ViUInt8 gain_buffer[5]; ViReal64 bw_buffer[4]; ViUInt8 loopCnt; ViUInt16 device_status = 0; ViUInt16 sampleCount; ViReal64 resolution; ViUInt16 min_wavelength; ViUInt16 max_wavelength; m_handle = 0; // get the number of connected devices ViUInt32 deviceCount = 0; ViStatus res = TLBP2_get_connected_devices(VI_NULL, VI_NULL, &deviceCount); if (res != VI_SUCCESS) { print_error_msg(res); return 0; } if (deviceCount == 0) { printf("No device connected\n"); return 0; } // interrupt the program to attach to this process for debugging the driver #ifdef _DEBUG printf("Press <Enter> to start the application\n"); getchar(); #endif // initialize the buffer for the resource strings resStr = malloc(sizeof(BP2_DEVICE)*deviceCount); // get the reource strings of the connected devices res = TLBP2_get_connected_devices(VI_NULL, resStr, &deviceCount); if (res != VI_SUCCESS) { print_error_msg(res); free(resStr); return 0; } // connect with the first device res = TLBP2_init(resStr[0].resourceString, VI_TRUE, VI_FALSE, &m_handle); // release the buffer for the resource strings free(resStr); // abort if an error during the initialization occurred if ((res & _VI_ERROR) == _VI_ERROR) { print_error_msg(res); return 0; } // rotate with 10 hz res = TLBP2_set_drum_speed_ex(m_handle, 10.0, &sampleCount, &resolution); if ((res & _VI_ERROR) > 0) { print_error_msg(res); return 0; } // set the manual gain gain_buffer[0] = 12; gain_buffer[1] = 12; gain_buffer[2] = 12; gain_buffer[3] = 12; gain_buffer[4] = 12; res = TLBP2_set_gains(m_handle, gain_buffer, gain_buffer[4]); if ((res & _VI_ERROR) > 0) { print_error_msg(res); return 0; } // set the automatic gain res = TLBP2_set_auto_gain(m_handle, VI_TRUE); if ((res & _VI_ERROR) > 0) { print_error_msg(res); return 0; } // set the bandwidth to 125 ( as the Thorlabs Beam Application) bw_buffer[0] = 125.0; bw_buffer[1] = 125.0; bw_buffer[2] = 125.0; bw_buffer[3] = 125.0; res = TLBP2_set_bandwidths(m_handle, bw_buffer); if ((res & _VI_ERROR) > 0) { print_error_msg(res); return 0; } // request the wavelength range and set the wavelength res = TLBP2_get_wavelength_range(m_handle, &min_wavelength, &max_wavelength); if ((res & _VI_ERROR) > 0) { print_error_msg(res); return 0; } res = TLBP2_set_wavelength(m_handle, min_wavelength + (max_wavelength - min_wavelength) /2); if ((res & _VI_ERROR) > 0) { print_error_msg(res); return 0; } // set the position correction res = TLBP2_set_position_correction(m_handle, VI_ON); if ((res & _VI_ERROR) > 0) { print_error_msg(res); return 0; } // get a measurement for(loopCnt = 0; loopCnt < 10; loopCnt++) { device_status = 0; res = VI_SUCCESS; while(res == VI_SUCCESS && (device_status & BP2_STATUS_SCAN_AVAILABLE) == 0) { res = TLBP2_get_device_status(m_handle, &device_status); } if (res == VI_SUCCESS) { BP2_SLIT_DATA slit_data[4]; ///< BP2_MAX_SLIT_COUNT = 4 BP2_CALCULATIONS calculation_result[4]; ViReal64 power; ViReal32 powerSaturation; ViReal64 power_intensities[7500]; // get the calculation res = TLBP2_get_slit_scan_data(m_handle, slit_data, calculation_result, &power, &powerSaturation, power_intensities); if (res == VI_SUCCESS) { printf("Power: %.2f\n", power); printf("Power Saturation: %.2f\n", powerSaturation); printf("Peak Position Slit 1: %.2f\n", calculation_result[0].peakPosition); printf("Centroid Position Slit 1: %.2f\n", calculation_result[0].centroidPosition); printf("Peak Position Slit 2: %.2f\n", calculation_result[1].peakPosition); printf("Centroid Position Slit 2: %.2f\n", calculation_result[1].centroidPosition); // get the gains res = TLBP2_get_gains(m_handle, gain_buffer, &gain_buffer[4]); if (res == VI_SUCCESS) { printf("Gain 1: %d\n", gain_buffer[0]); printf("Gain 2: %d\n", gain_buffer[1]); printf("Gain 3: %d\n", gain_buffer[2]); printf("Gain 4: %d\n", gain_buffer[3]); printf("Gain Power: %d\n", gain_buffer[4]); } } else printf("The scan returned the error: %x\n", res); } else printf("The device status returned the error: %d\n", res); } // release the device TLBP2_close(m_handle); return 0; }
从以上代码看出来, 里面要用到两个主要的结构体和结构体数组.
那么翻译成aardio,应该这样描述:
import win.ui; /*DSG{{*/ mainForm = win.form(text="aardio工程";right=694;bottom=419) mainForm.add( button={cls="button";text="Button";left=234;top=243;right=496;bottom=324;z=1} ) /*}}*/ import console console.open() var dll = ..raw.loadDll("\res\TLBP2_32.dll","beamLib"); TLBP2_get_connected_devices = dll.api("TLBP2_get_connected_devices","int(int,pointer,int&)" ); TLBP2_init = dll.api("TLBP2_init","int(string,bool,bool,ADDR&)" ); TLBP2_close = dll.api("TLBP2_close","int(ADDR)" ); TLBP2_set_drum_speed_ex = dll.api("TLBP2_set_drum_speed_ex","int(ADDR,double,WORD&,double&)" ); TLBP2_set_auto_gain = dll.api("TLBP2_set_auto_gain","int(ADDR,bool)" ) TLBP2_set_bandwidths = dll.api("TLBP2_set_bandwidths","int(ADDR,pointer)" ) TLBP2_get_wavelength_range = dll.api("TLBP2_get_wavelength_range","int(ADDR,WORD&,WORD&)" ) TLBP2_set_wavelength = dll.api("TLBP2_set_wavelength","int(ADDR,double)" ) TLBP2_set_position_correction = dll.api("TLBP2_set_position_correction","int(ADDR,bool)" ) TLBP2_get_device_status = dll.api("TLBP2_get_device_status","int(ADDR,WORD&)" ) TLBP2_get_slit_scan_data = dll.api("TLBP2_get_slit_scan_data","int(ADDR,pointer,pointer,double&,float&,pointer)" ) TLBP2_error_message = dll.api("TLBP2_error_message","int(ADDR,int,string&)" ) var buff = raw.buffer(256*10,'\0'); var ret = TLBP2_get_connected_devices(0,buff,0); var serialstr = raw.str(buff); console.log("TLBP2_get_connected_devices",ret,serialstr) ret,handle = TLBP2_init(serialstr,true,false,0); console.log("TLBP2_init",ret,handle) ret,sampleCount,resolution = TLBP2_set_drum_speed_ex(handle,10.0,0,0); console.log("TLBP2_set_drum_speed_ex",ret,sampleCount,resolution) ret = TLBP2_set_auto_gain(handle,true); console.log("TLBP2_set_auto_gain",ret) bandwidths = raw.buffer({double a[4]={125.0,125.0,125.0,125.0}}); ret = TLBP2_set_bandwidths(handle,bandwidths); console.log("TLBP2_set_bandwidths",ret) ret,min_wavelength,max_wavelength = TLBP2_get_wavelength_range(handle,0,0); console.log("TLBP2_get_wavelength_range",ret,min_wavelength,max_wavelength) ret = TLBP2_set_wavelength(handle,1550/*min_wavelength+(max_wavelength-min_wavelength)/2*/); console.log("TLBP2_set_wavelength",ret) ret = TLBP2_set_position_correction(handle,true); console.log("TLBP2_set_position_correction",ret) mainForm.button.oncommand = function(id,event){ var res = 0; var device_status = 0; while( (res==0) and ((device_status&0x0001)==0) ){ res,device_status = TLBP2_get_device_status(handle,0); } if(res==0){ var slit_data_len = raw.sizeof({ WORD slit_sample_count; float slit_dark_level; float slit_samples_intensities[7500]; float slit_samples_positions[7500]; WORD encoder_increments; }); var calculation_result_len = raw.sizeof({ WORD isValid; WORD peakIndex; float peakPosition; float peakIntensity; WORD centroidIndex; float centroidPosition; float beamWidthClip; float gaussianFitAmplitude; float gaussianFitCentroid; float gaussianFitDiameter; float gaussianFitPercentage; float gaussianFitCurve[7500]; float besselFitPercentage; float besselFitCurve[7500]; float sigma; float calcAreaLeftBorder; float calcAreaRightBorder; }); var pslitData = raw.buffer(slit_data_len*4); var pcalculation_result = raw.buffer(calculation_result_len*4); var ret,power,powerWindowSaturation = TLBP2_get_slit_scan_data(handle,pslitData,pcalculation_result,10,0,null); if(ret==0){ console.log("TLBP2_get_slit_scan_data",ret,power,powerWindowSaturation); var retdata = raw.convertArray(pcalculation_result,4,{ WORD isValid; WORD peakIndex; float peakPosition; float peakIntensity; WORD centroidIndex; float centroidPosition; float beamWidthClip; float gaussianFitAmplitude; float gaussianFitCentroid; float gaussianFitDiameter; float gaussianFitPercentage; float gaussianFitCurve[7500]; float besselFitPercentage; float besselFitCurve[7500]; float sigma; float calcAreaLeftBorder; float calcAreaRightBorder; }); console.log("Peak Position Slit 1:",retdata[1].peakPosition) console.log("Centroid Position Slit 1:",string.format("%.2f", retdata[1].centroidPosition)) console.log("Peak Position Slit 2:",retdata[2].peakPosition) console.log("Centroid Position Slit 2:",string.format("%.2f", retdata[2].centroidPosition)) //console.log("Centroid Position Slit 3:",string.format("%.2f", retdata[3].centroidPosition)) //console.log("Centroid Position Slit 4:",string.format("%.2f", retdata[4].centroidPosition)) }else { console.log(ret,string.format("%X", ret)) console.log(TLBP2_error_message(handle,ret,raw.buffer(256))) } } } mainForm.onClose = function(hwnd,message,wParam,lParam){ var ret = TLBP2_close(handle); console.log("TLBP2_close",ret) } mainForm.show(); return win.loopMessage();
以上, 主要看结构体那部分
首先C结构体第一个参数里面的viBoolean追踪过去其实是unsigned short, 在aardio中应该转换为WORD, 我之前按照字面意思转换为bool就是错误的.
这里先用sizeof()来求出此结构体的大小, 然后*4得出需要的buff大小, 然后执行了dll函数之后, 得到了数据还需要转换为结构体数组, 这里用到了raw.convertArray() , 一次转换为了定长的结构体数组.
1 个回复 | 最后更新于 2021-04-15
登录后方可回帖
经过jacenHe老大的指点, 我上面把结构体用法复杂化了, dll声明的时候可以直接用struct , 这样会简单很多. 还有结构体数组也是可以直接赋值的. 具体可以看下面的代码.
程序修改后如下:
另外, 温习下struct的相关知识.