neMESYS pump C-API test The following sample source code shows the implementation of the neMESYS C-API test. The test uses almost all Pump Library functions and shows how to use them. It further shows how to get a valve device handle from neMESYS pump device and how to control neMESYS valves via Valve Library.
#include <chrono>
#include <vector>
#include <usl/core/Thread.h>
#include <usl/core/PollingTimer.h>
#include <usl/math/uslmath.h>
#include <log4cplus/logger.h>
#include <diag/diag.h>
using namespace Usl;
#define BOOST_TEST_MODULE capi_nemesys_test
#include <boost/test/unit_test.hpp>
long Result;
BOOST_AUTO_TEST_CASE(testCapiOpen)
{
Result =
LCB_Open(
"config/testconfig_qmixsdk", 0);
}
BOOST_AUTO_TEST_CASE(testDeviceNameLookup)
{
std::string PumpName = "neMESYS_Low_Pressure_1_Pump";
BOOST_CHECK_NE(hNemesys1, 0);
int IndexOfPump = -1;
BOOST_CHECK_GT(Result, 0);
long PumpCount = Result;
for (int i = 0; i < PumpCount; ++i)
{
char NameBuf[128];
std::string Name(NameBuf);
if (PumpName == Name)
{
IndexOfPump = i;
BOOST_CHECK_EQUAL(hNemesys1, hPump);
}
BOOST_TEST_MESSAGE("Name of pump " << i << ": " << Name);
}
BOOST_CHECK_GT(IndexOfPump, -1);
}
BOOST_AUTO_TEST_CASE(testBusStart)
{
Result =
LCB_Log(
"C-API Log Test Message");
}
BOOST_AUTO_TEST_CASE(testPumpEnable)
{
BOOST_CHECK_GT(Result, -1);
if (Result)
{
}
CThread::sleep(500);
BOOST_CHECK_GT(Result, 0);
}
BOOST_AUTO_TEST_CASE(testApirate)
{
}
bool waitCalibrationFinished(
dev_hdl hPump, uint32_t TimeoutSeconds)
{
CPollingTimer Timer(TimeoutSeconds * 1000);
do
{
CThread::sleep(100);
}
while ((0 == Result) && !Timer.isExpired());
return (Result > 0);
}
bool waitDosageFinished(
dev_hdl hPump, uint32_t TimeoutSeconds)
{
CPollingTimer Timer(TimeoutSeconds * 1000);
CPollingTimer MessageTimer(500);
do
{
CThread::sleep(100);
if (MessageTimer.isExpired())
{
double FillLevel;
BOOST_TEST_MESSAGE("Fill level: " << FillLevel);
MessageTimer.restart();
}
}
while ((1 == Result) && !Timer.isExpired());
return (Result == 0);
}
BOOST_AUTO_TEST_CASE(testCalibration)
{
CThread::sleep(200);
bool CalibrationFinished = waitCalibrationFinished(hNemesys1, 30);
BOOST_CHECK(CalibrationFinished);
}
BOOST_AUTO_TEST_CASE(testSyringeConfig)
{
double InnerDiameterSet = 1;
double PistonStrokeSet = 60;
BOOST_TEST_MESSAGE("Set syringe inner diameter: " << InnerDiameterSet
<< ", piston stroke: " << PistonStrokeSet);
double InnerDiameterGet;
double PistonStrokeGet;
BOOST_TEST_MESSAGE("Get syringe inner diameter: " << InnerDiameterGet
<< ", piston stroke: " << PistonStrokeGet);
BOOST_CHECK_EQUAL(InnerDiameterSet, InnerDiameterGet);
BOOST_CHECK_EQUAL(PistonStrokeSet, PistonStrokeGet);
}
BOOST_AUTO_TEST_CASE(testSiUnits)
{
double MaxMillilitres;
double MaxLitres;
BOOST_CHECK(Usl::approximatelyEqual(MaxMillilitres, MaxLitres * 1000));
BOOST_TEST_MESSAGE("MaxMillilitres:" << MaxMillilitres << " MaxLitres: "
<< MaxLitres);
double MaxMillilitresPerSecond;
double MaxMillilitresPerMinute;
BOOST_CHECK_EQUAL(MaxMillilitresPerSecond * 60, MaxMillilitresPerMinute);
BOOST_TEST_MESSAGE("MaxMillilitresPerSecond:" << MaxMillilitresPerSecond
<< " MaxMillilitresPerMinute: " << MaxMillilitresPerMinute);
double MaxLitresPerMinute;
BOOST_CHECK(Usl::approximatelyEqual(MaxMillilitresPerMinute, MaxLitresPerMinute * 1000));
BOOST_TEST_MESSAGE("MaxMillilitresPerMinute: " << MaxMillilitresPerMinute
<< "MaxLitresPerMinute: " << MaxLitresPerMinute);
}
BOOST_AUTO_TEST_CASE(testAspirate)
{
double MaxVolume;
double MaxFlow;
MaxVolume /= 2;
bool PumpingFinished = waitDosageFinished(hNemesys1, 30);
BOOST_CHECK(PumpingFinished);
}
BOOST_AUTO_TEST_CASE(testDispense)
{
double MaxVolume;
double MaxFlow;
MaxVolume /= 10;
MaxFlow /= 2;
bool PumpingFinished = waitDosageFinished(hNemesys1, 20);
BOOST_CHECK(PumpingFinished);
}
BOOST_AUTO_TEST_CASE(testPumpVolume)
{
double MaxVolume;
double MaxFlow;
MaxVolume /= 10;
bool PumpingFinished = waitDosageFinished(hNemesys1, 10);
BOOST_CHECK(PumpingFinished);
PumpingFinished = waitDosageFinished(hNemesys1, 10);
BOOST_CHECK(PumpingFinished);
}
BOOST_AUTO_TEST_CASE(testGenerateFlow)
{
double MaxFlow;
CThread::sleep(1000);
double FlowIs;
BOOST_CHECK_CLOSE(MaxFlow, FlowIs, 0.01);
bool PumpingFinished = waitDosageFinished(hNemesys1, 30);
BOOST_CHECK(PumpingFinished);
}
BOOST_AUTO_TEST_CASE(testSetSyringeLevel)
{
double MaxFlow;
double MaxVolume;
MaxFlow /= 2;
MaxVolume /= 2;
bool PumpingFinished = waitDosageFinished(hNemesys1, 30);
BOOST_CHECK(PumpingFinished);
double FillLevelIs;
BOOST_CHECK_CLOSE(MaxVolume, FillLevelIs, 0.01);
PumpingFinished = waitDosageFinished(hNemesys1, 30);
BOOST_CHECK(PumpingFinished);
BOOST_CHECK_CLOSE(0, FillLevelIs, 0.01);
}
BOOST_AUTO_TEST_CASE(testValve)
{
BOOST_CHECK_GE(HasValve, 0);
if (!HasValve)
{
BOOST_TEST_MESSAGE("no valve installed");
return;
}
BOOST_CHECK_GT(hValve1, 0);
BOOST_CHECK_GT(NumberOfValvePositions, 0);
BOOST_TEST_MESSAGE("Valve positions: " << NumberOfValvePositions);
for (int i = 0; i < NumberOfValvePositions; ++i)
{
CThread::sleep(200);
BOOST_CHECK_EQUAL(Result, i);
}
}
BOOST_AUTO_TEST_CASE(stressTestManyInstructions)
{
double MaxVolume;
double MaxFlow;
bool PumpingFinished = waitDosageFinished(hNemesys1, 30);
BOOST_CHECK(PumpingFinished);
const double Pi = atan(1) * 4;
double T_ms = 20000;
double t_ms = 0;
double t_sample_ms = 100;
double Flow = 0;
std::vector<double> TimeValues;
std::chrono::time_point<std::chrono::system_clock> StartVelocityProfile,
FinishVelocityProfile, StartMove, StopMove;
StartVelocityProfile = std::chrono::system_clock::now();
for(t_ms = 0; t_ms <= T_ms / 2; t_ms += t_sample_ms)
{
Flow = MaxFlow / 2 * sin(t_ms * 2 * Pi / T_ms);
StartMove = std::chrono::system_clock::now();
StopMove = std::chrono::system_clock::now();
std::chrono::duration<double> elapsed_seconds = StopMove - StartMove;
TimeValues.push_back(elapsed_seconds.count());
{
break;
}
CThread::sleep(t_sample_ms);
}
FinishVelocityProfile = std::chrono::system_clock::now();
int i = 0;
for(double Duration : TimeValues)
{
BOOST_TEST_MESSAGE("Duration Move " << i << ": " << Duration << "s");
i++;
}
std::chrono::duration<double> elapsed_seconds = FinishVelocityProfile-StartVelocityProfile;
BOOST_TEST_MESSAGE("Elapsed time: " << elapsed_seconds.count() << "s.");
}
bool waitAxisTargetReached(
dev_hdl hAxis, uint32_t TimeoutSeconds)
{
CPollingTimer Timer(TimeoutSeconds * 1000);
do
{
CThread::sleep(100);
}
while ((0 == Result) && !Timer.isExpired());
return (Result > 0);
}
BOOST_AUTO_TEST_CASE(testNemesysAxisPositioning)
{
BOOST_CHECK_GT(hNemesys1Axis, 0);
double MaxVelocity;
double MinPosition;
BOOST_TEST_MESSAGE("Min Position: " << MinPosition);
Result =
LCA_MoveToPos(hNemesys1Axis, MinPosition, MaxVelocity, 0);
bool Result = waitAxisTargetReached(hNemesys1Axis, 30);
BOOST_CHECK_EQUAL(Result, true);
double MaxPositon;
Result =
LCA_MoveToPos(hNemesys1Axis, MaxPositon, MaxVelocity, 0);
Result = waitAxisTargetReached(hNemesys1Axis, 30);
BOOST_CHECK_EQUAL(Result, true);
}
BOOST_AUTO_TEST_CASE(testCapiClose)
{
}