光束分析仪BP209-IR/M的动态库TLBP2_32.dll得通信调用
By
admin
at 2021-04-13 • 1人收藏 • 1256人看过
最近用到这个设备, 这里写下调用的时候遇到的问题和解决方法.
这里先贴出来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 , 这样会简单很多. 还有结构体数组也是可以直接赋值的. 具体可以看下面的代码.
程序修改后如下:
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,str&,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,struct)" ) 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,struct&,struct&,double&,float&,pointer)" ) TLBP2_error_message = dll.api("TLBP2_error_message","int(ADDR,int,string&)" ) var buff = raw.buffer(256*10); var ret,serialstr = TLBP2_get_connected_devices(0,buff,0); 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) ret = TLBP2_set_bandwidths(handle,{double a[4]={125.0,125.0,125.0,125.0}}); 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 = { struct data[4]={ { WORD slit_sample_count; float slit_dark_level; float slit_samples_intensities[7500]; float slit_samples_positions[7500]; WORD encoder_increments; } } }; var calculation_result = { struct data[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; } } }; var ret,slit_data,calculation_result,power,powerWindowSaturation = TLBP2_get_slit_scan_data(handle,slit_data,calculation_result,10,0,null); if(ret==0){ console.log("TLBP2_get_slit_scan_data",ret,power,powerWindowSaturation); console.log("Peak Position Slit 1:",calculation_result.data[1].peakPosition) console.log("Centroid Position Slit 1:",string.format("%.2f", calculation_result.data[1].centroidPosition)) console.log("Peak Position Slit 2:",calculation_result.data[2].peakPosition) console.log("Centroid Position Slit 2:",string.format("%.2f", calculation_result.data[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))) } } }另外, 温习下struct的相关知识.