Skip to content
Snippets Groups Projects
Commit 4df8bb20 authored by alexey's avatar alexey
Browse files

Add Run time dll function loading

Signed-off-by: default avataralexey <Alexey.V.Krasnoperov@gmail.com>
parent d34d3b3d
No related branches found
No related tags found
No related merge requests found
#include "kpzdevice.h"
#include <Thorlabs.MotionControl.KCube.Piezo.h>
KPZ101Device::KPZ101Device(const QString &sn):ThorlabsDevice(sn,QStringLiteral("KPZ101Device"))
{
timer.setSingleShot(true);
timer.setInterval(pollingInterval());
connect(&timer,&QTimer::timeout,this,&KPZ101Device::timeout);
}
KPZ101Device::KPZ101Device(const QString &sn):PZDevice(sn,QStringLiteral("KPZ101Device")){}
bool KPZ101Device::isConnected()
{
......
......@@ -3,35 +3,26 @@
#include "thorlabsdevice.h"
class KPZ101Device: public ThorlabsDevice
class KPZ101Device: public PZDevice
{
Q_OBJECT
Q_OBJECT
friend ThorlabsDevice;
protected:
float outputVoltage = 0;
QTimer timer;
const double maxOutputVoltage = 75;
KPZ101Device(const QString &sn);
bool Open();
void Close();
bool Open() override;
void Close() override;
public:
~KPZ101Device() override
{
Close();
}
bool isConnected() override;
double getOutputVoltage()
{
return isOpen ? outputVoltage : 0;
}
bool setOutputVoltage(double v);
bool setOutputVoltage(double v) override;
bool setEnabled(bool enable) override;
bool setOutputTRIG1Level(bool on);
enum {DeviceID = 29};
protected slots:
void timeout();
signals:
void voltageChanged(double v);
void timeout() override;
};
......
#include "tpzdevice.h"
#include <Thorlabs.MotionControl.TCube.Piezo.h>
TPZ001Device::TPZ001Device(const QString &sn):PZDevice(sn,QStringLiteral("TPZ001Device")){}
bool TPZ001Device::isConnected()
{
return true;
bool rv = PCC_CheckConnection(serial);
if( ! rv )
writeError("Disconnected");
return rv;
}
bool TPZ001Device::Open()
{
if( ! check(PCC_Open(serial),"Cannot open") )
return false;
if( ! isConnected() )
return false;
isOpen = true;
if( ! check(PCC_SetPositionControlMode(serial,PZ_ControlModeTypes::PZ_OpenLoop),"PCC_SetPositionControlMode") )
return false;
if( ! check(PCC_SetVoltageSource(serial,PZ_InputSourceFlags::PZ_SoftwareOnly),"PCC_SetVoltageSource") )
return false;
if( ! check(PCC_SetMaxOutputVoltage(serial,short(10*maxOutputVoltage)),"PCC_SetMaxOutputVoltage") )
return false;
if( ! setEnabled(false) )
return false;
timer.start();
writeInfo("Successfully open");
// if( ! PCC_StartPolling(serial, pollingInterval()) )
// return false;
return true;
}
void TPZ001Device::Close()
{
if( ! isOpen )
return;
setOutputVoltage(0);
setEnabled(false);
// PCC_StopPolling(serial);
PCC_Close(serial);
emit voltageChanged(0);
isOpen = false;
writeInfo("Close");
}
void TPZ001Device::timeout()
{
if( isOpen )
{
outputVoltage = maxOutputVoltage*double(PCC_GetOutputVoltage(serial))/32767.;
emit voltageChanged(outputVoltage);
timer.start();
}
}
bool TPZ001Device::setOutputVoltage(double v)
{
v = qMin(v,maxOutputVoltage);
qDebug() << "TPZ001Device::setOutputVoltage" << v;
return check(PCC_SetOutputVoltage(serial,short(32767.*v/maxOutputVoltage)),"PCC_SetOutputVoltage");
}
bool TPZ001Device::setEnabled(bool enable)
{
return enable ? check(PCC_Enable(serial),"PCC_Enable") : check(PCC_Disable(serial),"PCC_Disable");
}
#ifndef TPZDEVICE_H
#define TPZDEVICE_H
#include "thorlabsdevice.h"
class TPZ001Device: public PZDevice
{
Q_OBJECT
friend ThorlabsDevice;
protected:
TPZ001Device(const QString &sn);
bool Open() override;
void Close() override;
public:
~TPZ001Device() override
{
Close();
}
bool isConnected() override;
bool setOutputVoltage(double v) override;
bool setEnabled(bool enable) override;
enum {DeviceID = 81};
protected slots:
void timeout() override;
};
#endif // TPZDEVICE_H
QT += core gui charts
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
CONFIG += c++11
#DEFINES += THORLABS_SIMULATION
DEFINES += THORLABS_SIMULATION
THORLABS_PATH = "C:\Program Files\Thorlabs\Kinesis"
......@@ -30,7 +31,6 @@ SOURCES += \
internallaserwidget.cpp \
jogwidget.cpp \
kimdevice.cpp \
kpzdevice.cpp \
kstdevice.cpp \
logwidget.cpp \
main.cpp \
......@@ -38,6 +38,7 @@ SOURCES += \
pliwidget.cpp \
programsettings.cpp \
programsettingsdialog.cpp \
pzdevice.cpp \
qledlabel.cpp \
slidercontrol.cpp \
thorlabsdevicemanager.cpp \
......@@ -53,7 +54,6 @@ HEADERS += \
internallaserwidget.h \
jogwidget.h \
kimdevice.h \
kpzdevice.h \
kstdevice.h \
logwidget.h \
mainwindow.h \
......@@ -62,6 +62,7 @@ HEADERS += \
positionersettings.h \
programsettings.h \
programsettingsdialog.h \
pzdevice.h \
qledlabel.h \
qpopupslider.h \
slidercontrol.h \
......@@ -82,20 +83,22 @@ TRANSLATIONS += \
INCLUDEPATH += $${THORLABS_PATH}
LIBS += -L$${THORLABS_PATH}
LIBS += -lThorlabs.MotionControl.KCube.Piezo
LIBS += -lThorlabs.MotionControl.TCube.LaserDiode
LIBS += -lThorlabs.MotionControl.TCube.InertialMotor
LIBS += -lThorlabs.MotionControl.KCube.InertialMotor
LIBS += -lThorlabs.MotionControl.KCube.StepperMotor
LIBS += -lThorlabs.MotionControl.TCube.StepperMotor
LIBS += -lThorlabs.MotionControl.KCube.StepperMotor
LIBS += -lThorlabs.MotionControl.TCube.LaserDiode
THORLABS_DLLS = $${THORLABS_PATH}/Thorlabs.MotionControl.TCube.Piezo.dll \
$${THORLABS_PATH}/Thorlabs.MotionControl.TCube.InertialMotor.dll \
$${THORLABS_PATH}/Thorlabs.MotionControl.TCube.StepperMotor.dll \
$${THORLABS_PATH}/Thorlabs.MotionControl.TCube.LaserDiode.dll \
$${THORLABS_PATH}/Thorlabs.MotionControl.KCube.Piezo.dll \
$${THORLABS_PATH}/Thorlabs.MotionControl.KCube.InertialMotor.dll \
$${THORLABS_PATH}/Thorlabs.MotionControl.KCube.StepperMotor.dll \
$${THORLABS_PATH}/Thorlabs.MotionControl.DeviceManager.dll
THORLABS_DLLS = $${THORLABS_PATH}/Thorlabs.MotionControl.KCube.Piezo.dll \
$${THORLABS_PATH}/Thorlabs.MotionControl.TCube.LaserDiode.dll \
$${THORLABS_PATH}/Thorlabs.MotionControl.TCube.InertialMotor.dll \
$${THORLABS_PATH}/Thorlabs.MotionControl.KCube.InertialMotor.dll \
$${THORLABS_PATH}/Thorlabs.MotionControl.KCube.StepperMotor.dll \
$${THORLABS_PATH}/Thorlabs.MotionControl.TCube.StepperMotor.dll \
$${THORLABS_PATH}/Thorlabs.MotionControl.DeviceManager.dll
RC_FILE = tunepli.rc
......@@ -192,7 +195,6 @@ copyPluginsToDestdir(styles)
build_pass:for(ifile, THORLABS_DLLS) {
copyToDestdir($$ifile)
}
#
copyToDestdir($$PWD/Icons/icons8-adjust-64.ico)
......@@ -18,7 +18,7 @@
#include "thorlabsdevice.h"
#include "thorlabsdevicemanager.h"
#include "calibrationvoltageview.h"
#include "kpzdevice.h"
#include "pzdevice.h"
CalibrationWidget::CalibrationWidget(QWidget *parent):QGroupBox(parent)
......@@ -115,7 +115,7 @@ CalibrationWidget::CalibrationWidget(QWidget *parent):QGroupBox(parent)
runControlButton->setFixedSize(runControlButton->sizeHint());
runControlButton->setCheckable(true);
setTips(runControlButton,tr("Start"));
connect(runControlButton,&QPushButton::clicked,this,&CalibrationWidget::runControlSlot);
connect(runControlButton,&QPushButton::toggled,this,&CalibrationWidget::runControlSlot);
hl->addWidget(runControlButton);
//
readSettings();
......@@ -294,7 +294,7 @@ void CalibrationWidget::controlTimerTimeout()
void CalibrationWidget::runControlSlot(bool checked)
{
settingsGroup->setEnabled(!checked);
settingsGroup->setEnabled(!checked && isChecked());
if( checked )
{
currentCycle = 0;
......@@ -322,13 +322,13 @@ void CalibrationWidget::runControlSlot(bool checked)
void CalibrationWidget::laserControlSlot(bool checked)
{
QString msg = tr("Laser is ") + (checked ? QStringLiteral("ON") : QStringLiteral("OFF"));
if( control != nullptr )
{
QString msg = tr("Laser is ") + (checked ? QStringLiteral("ON") : QStringLiteral("OFF"));
control->setOutputTRIG1Level(checked);
control->writeMessage(QtInfoMsg,msg);
setTips(calibLaserBox, msg);
}
setTips(calibLaserBox, msg);
}
void CalibrationWidget::checkedSlot(bool checked)
......@@ -337,35 +337,35 @@ void CalibrationWidget::checkedSlot(bool checked)
if( checked )
{
ThorlabsDeviceManager::CheckDeviceConnection();
auto devs = ProgramSettings::findThorlabsDevs(parentWidget()->objectName(),KPZ101Device::DeviceID);
if( devs.isEmpty() )
auto devs = ProgramSettings::findThorlabsDevs(parentWidget()->objectName(),PZDevice::KPZ101);
devs.append(ProgramSettings::findThorlabsDevs(parentWidget()->objectName(),PZDevice::TPZ001));
if( devs.isEmpty() )
{
QMessageBox::warning(this,tr("No KPZ devices found"),
tr("No KPZ devices found! Check program configuration first!"));
QMessageBox::warning(this,tr("No PZ devices found"),
tr("No PZ devices found! Check program configuration first!"));
setChecked(false);
setWaitCursor(false);
return;
}
if( devs.size() > 1 )
{
QMessageBox::warning(this,tr("Multiple KPZ devices"),
tr("Multiple KPZ devices found! Check program configuration first!"));
QMessageBox::warning(this,tr("Multiple PZ devices"),
tr("Multiple PZ devices found! Check program configuration first!"));
setChecked(false);
setWaitCursor(false);
return;
}
control = ThorlabsDevice::Create<KPZ101Device>(devs.front());
control = ThorlabsDevice::Create<PZDevice>(devs.front());
if( control == nullptr)
{
QMessageBox::warning(this,tr("Open KPZ device"),
tr("Cannot open KPZ device with S/N %1!\nThe device is busy or disconnected!").arg(devs.front()));
QMessageBox::warning(this,tr("Open PZ device"),
tr("Cannot open PZ device with S/N %1!\nThe device is busy or disconnected!").arg(devs.front()));
setChecked(false);
setWaitCursor(false);
return;
}
connect(control,&KPZ101Device::voltageChanged,this,[=](double v){outputVoltage->display(QString::number(v,'f',1));});
connect(control,&KPZ101Device::voltageChanged,calibrationVoltageView,&CalibrationVoltageView::appendVoltage);
connect(control,&PZDevice::voltageChanged,this,[=](double v){outputVoltage->display(QString::number(v,'f',1));});
connect(control,&PZDevice::voltageChanged,calibrationVoltageView,&CalibrationVoltageView::appendVoltage);
laserControlSlot(calibLaserBox->isChecked());
}
else
......@@ -375,5 +375,6 @@ void CalibrationWidget::checkedSlot(bool checked)
delete control;
control = nullptr;
}
settingsGroup->setEnabled(checked);
setWaitCursor(false);
}
......@@ -14,6 +14,7 @@ class QCheckBox;
class KPZ101Device;
class QLCDNumber;
class CalibrationVoltageView;
class PZDevice;
class CalibrationWidget: public QGroupBox
{
......@@ -23,7 +24,7 @@ protected:
QTimer controlTimer;
QElapsedTimer elapsedTimer;
QLCDNumber *outputVoltage = nullptr;
KPZ101Device *control = nullptr;
PZDevice *control = nullptr;
//
CalibrationVoltageView *calibrationVoltageView = nullptr;
//
......
chcp 65001
"C:\Qt\Tools\QtCreator\bin\jom\jom.exe" %*
\ No newline at end of file
......@@ -16,7 +16,7 @@ protected:
InternalLaserWidget *internalLaserWidget = nullptr;
public:
PLIWidget(const QString & name, QWidget *parent = nullptr);
~PLIWidget();
~PLIWidget() override;
protected Q_SLOTS:
void calibrationWidgetClicked(bool checked);
void internalLaserWidgetClicked(bool checked);
......
#include "pzdevice.h"
#include "thorlabsdevicemanager.h"
// #include <Thorlabs.MotionControl.KCube.Piezo.h>
PZDevice::PZDevice(const QString & sn):ThorlabsDevice(sn,QStringLiteral("PZDevice"))
{
timer.setSingleShot(true);
timer.setInterval(pollingInterval());
connect(&timer,&QTimer::timeout,this,&PZDevice::timeout);
}
bool PZDevice::isConnected()
{
FunctionBool PCC_CheckConnection = nullptr;
if( LoadFunction<FunctionBool>("PCC_CheckConnection",PCC_CheckConnection) && PCC_CheckConnection(serial) )
return true;
writeError("Disconnected");
return false;
}
bool PZDevice::LoadFunctions()
{
if( ThorlabsDeviceManager::checkId(serial,KPZ101) )
dllLib.setFileName(QStringLiteral("Thorlabs.MotionControl.KCube.Piezo"));
else if( ThorlabsDeviceManager::checkId(serial,TPZ001) )
dllLib.setFileName(QStringLiteral("Thorlabs.MotionControl.TCube.Piezo"));
else
{
writeError("PZ dll undefined");
return false;
}
//
if( ! dllLib.load() )
{
writeError(QStringLiteral("Cannot load PZ dll library %1").arg(dllLib.fileName()));
return false;
}
//
if( ! LoadFunction<FunctionShort>("PCC_Open",PCC_Open) )
return false;
if( ! LoadFunction<FunctionVoid>("PCC_Close",PCC_Close) )
return false;
if( ! LoadFunction<FunctionShort>("PCC_Enable",PCC_Enable) )
return false;
if( ! LoadFunction<FunctionShort>("PCC_Disable",PCC_Disable) )
return false;
if( ! LoadFunction<FunctionShort>("PCC_GetOutputVoltage",PCC_GetOutputVoltage) )
return false;
if( ! LoadFunction<FunctionWriteShort>("PCC_SetOutputVoltage",PCC_SetOutputVoltage) )
return false;
if( ! LoadFunction<FunctionWriteShort>("PCC_SetMaxOutputVoltage",PCC_SetMaxOutputVoltage) )
return false;
if( ! LoadFunction<FunctionWriteInt>("PCC_SetPositionControlMode",PCC_SetPositionControlMode) )
return false;
return LoadFunction<FunctionWriteInt>("PCC_SetVoltageSource",PCC_SetVoltageSource);
}
bool PZDevice::Open()
{
if( ! LoadFunctions() )
return false;
if( ! check(PCC_Open(serial),"Cannot open") )
return false;
if( ! isConnected() )
return false;
isOpen = true;
FunctionWriteInt PCC_SetPositionControlMode = nullptr;
if( ! LoadFunction<FunctionWriteInt>("PCC_SetPositionControlMode",PCC_SetPositionControlMode) || ! check(PCC_SetPositionControlMode(serial,PZ_ControlModeTypes::PZ_OpenLoop),"PCC_SetPositionControlMode") )
return false;
FunctionWriteInt PCC_SetVoltageSource = nullptr;
if( ! LoadFunction<FunctionWriteInt>("PCC_SetVoltageSource",PCC_SetVoltageSource) || ! check(PCC_SetVoltageSource(serial,PZ_InputSourceFlags::PZ_SoftwareOnly),"PCC_SetVoltageSource") )
return false;
FunctionWriteShort PCC_SetMaxOutputVoltage = nullptr;
if( ! LoadFunction<FunctionWriteShort>("PCC_SetMaxOutputVoltage",PCC_SetMaxOutputVoltage) || !check(PCC_SetMaxOutputVoltage(serial,short(10*maxOutputVoltage)),"PCC_SetMaxOutputVoltage") )
return false;
if( ! setEnabled(false) )
return false;
timer.start();
writeInfo("Successfully open");
return true;
}
void PZDevice::Close()
{
if( ! isOpen )
return;
setOutputVoltage(0);
setEnabled(false);
PCC_Close(serial);
emit voltageChanged(0);
isOpen = false;
writeInfo("Close");
}
void PZDevice::timeout()
{
if( isOpen )
{
outputVoltage = maxOutputVoltage*double(PCC_GetOutputVoltage(serial))/32767.;
emit voltageChanged(outputVoltage);
timer.start();
}
}
bool PZDevice::setOutputVoltage(double v)
{
v = qMin(v,maxOutputVoltage);
qDebug() << "PZDevice::setOutputVoltage" << v;
return check(PCC_SetOutputVoltage(serial,short(32767.*v/maxOutputVoltage)),"PCC_SetOutputVoltage");
}
bool PZDevice::setEnabled(bool enable)
{
return enable ? check(PCC_Enable(serial),"PCC_Enable") : check(PCC_Disable(serial),"PCC_Disable");
}
bool PZDevice::setOutputTRIG1Level(bool on)
{
return (PCC_SetDigitalOutputs != nullptr) ? check(PCC_SetDigitalOutputs(serial,on?1:0),"PCC_SetDigitalOutputs") : true;
}
#ifndef PZDEVICE_H
#define PZDEVICE_H
#include "thorlabsdevice.h"
class PZDevice: public ThorlabsDevice
{
Q_OBJECT
protected:
//
FunctionShort PCC_Open = nullptr;
FunctionVoid PCC_Close = nullptr;
FunctionShort PCC_Enable = nullptr;
FunctionShort PCC_Disable = nullptr;
FunctionShort PCC_GetOutputVoltage = nullptr;
FunctionWriteShort PCC_SetOutputVoltage = nullptr;
FunctionWriteShort PCC_SetMaxOutputVoltage = nullptr;
FunctionWriteByte PCC_SetDigitalOutputs = nullptr;
FunctionWriteInt PCC_SetPositionControlMode = nullptr;
FunctionWriteInt PCC_SetVoltageSource = nullptr;
double outputVoltage = 0;
QTimer timer;
const double maxOutputVoltage = 75;
void Close();
//
bool LoadFunctions();
//
public:
PZDevice(const QString & sn);
~PZDevice() override
{
Close();
}
bool Open();
enum {KPZ101 = 29, TPZ001 = 81};
bool isConnected() override;
bool setEnabled(bool enable) override;
double getOutputVoltage()
{
return isOpen ? outputVoltage : 0;
}
bool setOutputVoltage(double v);
bool setOutputTRIG1Level(bool on);
protected slots:
void timeout();
signals:
void voltageChanged(double v);
};
#endif // PZDEVICE_H
......@@ -5,6 +5,9 @@
#include <QObject>
#include <QTimer>
#include <QDebug>
#include <QLibrary>
#include <QMessageBox>
#include <QApplication>
class ThorlabsDevice: public QObject
{
......@@ -17,12 +20,41 @@ protected:
static int interval = 200;
return interval;
}
//
QLibrary dllLib;
typedef void (*FunctionVoid)(const char *serialNo);
typedef bool (*FunctionBool)(const char *serialNo);
typedef short (*FunctionShort)(const char *serialNo);
typedef short (*FunctionWriteShort)(const char *serialNo,short);
typedef short (*FunctionWriteInt)(const char *serialNo,int);
typedef short (*FunctionWriteByte)(const char *serialNo,unsigned char);
//
template<typename T>
bool LoadFunction(const char *name, T & t)
{
t = reinterpret_cast<T>(dllLib.resolve(name));
if( t != nullptr )
return true;
QMessageBox::warning(QApplication::activeWindow(),tr("Error"),QStringLiteral("Cannot resolve symbol \"%1\"\nin \"%2\"!")
.arg(name).arg(dllLib.fileName()));
return false;
}
//
// template<typename T>
// T LoadFunction(const char *name)
// {
// T t = reinterpret_cast<T>(dllLib.resolve(name));
// if( t == nullptr )
// QMessageBox::warning(QApplication::activeWindow(),tr("Error"),QStringLiteral("Cannot resolve symbol \"%1\"\nin \"%2\"!")
// .arg(name).arg(dllLib.fileName()));
// return t;
// }
public:
ThorlabsDevice(const QString & sn, const QString & deviceName):serial(sn.toLocal8Bit())
{
setObjectName(QStringLiteral("%1 with S/N: %2").arg(deviceName,sn));
}
virtual ~ThorlabsDevice() = default;
virtual ~ThorlabsDevice() override = default;
virtual bool isConnected() = 0;
//
template<typename T>
......@@ -52,6 +84,10 @@ public:
qCritical() << str;
}
//
void writeError(const QString & error)
{
qCritical() << QStringLiteral("%1: %2").arg(objectName(),error);
}
void writeError(const char *error)
{
qCritical() << QStringLiteral("%1: %2").arg(objectName(),error);
......@@ -94,4 +130,5 @@ public:
virtual bool StopImmediate() = 0;
};
#endif // THORLABSDEVICE_H
......@@ -35,6 +35,7 @@ const ThorlabsDeviceManager::DeviceIDMap & ThorlabsDeviceManager::deviceID()
{65,QStringLiteral("TCube Inertial Motor")},
{86,QStringLiteral("TCube LaserSource")},
{64,QStringLiteral("TCube LaserDiode")},
{81,QStringLiteral("TCube Piezo")},
{82,QStringLiteral("TCube NanoTrak")},
{89,QStringLiteral("TCube Quad")},
{85,QStringLiteral("TCube Solenoid")},
......@@ -45,7 +46,6 @@ const ThorlabsDeviceManager::DeviceIDMap & ThorlabsDeviceManager::deviceID()
return map;
}
const ThorlabsDeviceManager::DeviceInfoMap & ThorlabsDeviceManager::findConnectedDevice()
{
deviceInfoMap.clear();
......
......@@ -5,7 +5,7 @@
class TST101Device: public ThorlabsPositioner
{
Q_OBJECT
Q_OBJECT
friend ThorlabsDevice;
protected:
TST101Device(const QString &sn):ThorlabsPositioner(sn,QStringLiteral("TST101Device")){}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment