![]() |
CETONI SDK
20220623
The software libraries for integration of all CETONI devices.
|
This pump library defines a common pump control interface for a range of different pump types such as e.g. syringe pumps, dilutors, peristaltic pumps, or diaphragm pumps.
In general a pump consists of an actuator (like a linear drive for a syringe pump, a servo drive for a peristaltic pump or a simple DC/EC drive for a diaphragm pump) and a container for the transport of the fluid (like a syringe for a syringe pump/dilutor, a tube for a peristaltic pump or a pump head for the diaphragm pump). With some pumps like syringe pumps and peristaltic pumps the container is exchangeable by the application engineer or even by the user of the laboratory device. That means a user may mount different kind of syringes on a syringe pump or may use different tube sizes on a peristaltic pump. With other pumps (i.e. diaphragm pumps) the container and the actuator are fixed to each other and build up one single unit. The pump parameters (e.g. volume, flow or pressure) may be limited by the actuator and/or by the container.
On a syringe pump the flow is limited by the speed of the actuator (the velocity of the linear drive) and the volume is limited by the length/maximum position of the linear drive. On a peristaltic pump or diaphragm pump the volume is not limited by the actuator but the maximum flow is limited by the actuator speed - the maximum rotation speed of the peristaltic pump drive or the speed of the DC/EC diaphragm pump drive.
Container limits are only important for devices where it is possible to change the container. On every change of the container the calculation of the flow and volume values changes and therefore the parameters maximum volume and maximum flow may also change. That means each container has its own container limits. The maximum volume of a syringe pump is limited by the stroke of the syringe piston and the inner syringe diameter. The maximum flow is limited by the inner diameter of the syringe. The tube dimensions do not limit the maximum volume of a peristaltic pump but the maximum flow is limited by the inner diameter of the tube.
The way how you include the library functions in your own windows program, depends on the compiler and on the programming language you use. In order to access the pump API, you have to include the library labbCAN_Pump_API.dll to your programming environment. You have to copy this file to the working directory of your system or to the application directory that contains your application EXE file. Use the calling convention LCP_CALL for this library. This convention is managing how the parameters are put on the stack and who is responsible to clean the stack after the function execution.
The interface of the library, constant definitions and declarations of the library functions, is defined in the header file interface/labbCAN_Pump_API.h
To work with a pump, you need a valid device handle. A device handle is simply an opaque pointer to the internal device object created by the labbCAN environment. So the first thing you need do to is obtaining a valid device handle.
You can get a valid pump handle with the functions LCP_LookupPumpByName() or LCP_GetPumpHandle():
If you have valid device handle, you can start to bring your devices into a properly enabled and initialized state. To do this, you need to:
Each pump drive tracks the actual position value (volume value) by an internal position counter. If a positioning sensing system needs to get initialized depends on the type of used position sensor. Newer pumps, such as the Nemesys 4 pumps Nemesys S and Nemesys M have absolute encoders. These encoders keep their position value even when the pump is switched off. For such devices an initialization of the position sensing system is not required.
Other pumps, such as the older Nemesys Low Presssure Pumps or the Nemesys XL pumps use incremental encoders. If these pumps are switched off, the actual value of the position counter gets lost and is initialized to zero at next start. So right after power on, you don't know anything about the actual position of the pump drive units. For pumps like peristaltic pumps this does not matter but for pumps like syringe pumps this is very important because the position defines the actual fill level. For such devices an initialization of the position sensing system is required.
To find out, if an initialization is required, simply call the function LCP_IsPositionSensingInitialized(). This function always returns 1 for devices with an absolute encoder. For other devices, the returned value is 0 if the position value has not been initialized yet.
To properly initialize the internal position counter you either need to execute a reference move via LCP_SyringePumpCalibrate() or you need to restore a previously saved position counter value via LCP_RestoreDrivePosCnt(). Because a safe reference move is possible only if there is now syringe mounted on the device, the recommended way is using LCP_RestoreDrivePosCnt(). That means, right before you shut down your system, you need to query the actual position counter value of each pump via LCP_GetDrivePosCnt(). Then you need to store this value into a file. The next time you start up your devices, you load the saved position values, and write it back into the devices vial LCP_RestoreDrivePosCnt().
The newer Nemesys 4 devices (Nemesys S and Nemesys M) have internal force monitoring. The execution of dosing commands is only possible if the force monitoring is active. Force monitoring can be enabled / disabled via the function LCP_EnableForceMonitoring().
The following example code snippet shows a valid valid pump initialization procedure:
See the Pump API Initialisation module and the Pump Configuration module for a detailed reference of all pump initialization and configuration functions.
For almost all dosing tasks the functions from the Pump Control module and from the Pump Status module are required. Using the pump API you can choose from a number of different dosing modes:
With the status functions you can always query the actual state of the pumps you are working with:
The following example code snippet shows how to empty a syringe completely and then aspirate a certain volume with a certain flow rate.
See the Pump Control module and the Pump Status module for a detailed reference of all pump dosing and status functions.
The newer Nemesys 4 pumps, such as Nemesys S and Nemesys M, have an internal force sensor for force monitoring and safety stop in case of too high forces (pressures). To find out if a pump supports force monitoring you can use the function LCP_HasForceMonitoring(). Only if this function returns 1 the force monitoring functions are supported. Each pump has an internal hardware specific maximum force. To find out the maximum force, simply call LCP_GetMaxDeviceForce(). If the force of the device raises above this maximum force, the pump drive is stopped immediately.
It is possible to reduce the force limit below the maximum device force by setting a custom force limit if this is required by your application. You can do this by calling the function LCP_WriteForceLimit().
If you would like to know the current force limit, simply call LCP_GetForceLimit(). The force limit defines the threshold for triggering the safety stop. If a safety stop is triggered, the pump drive is stopped and the safety stop input of the pump is set. To find out, if you are in a force overload situation, that means if the safety stop is active, you can read the state of the safety stop input via LCP_IsForceSafetyStopActive(). If this function returns 1 then you know, that the pump has been stopped because of an force overload.
If the safety stop is active, it is no longer possible to carry out any dosing with the pump. To resolve this force overload situation, you need to reduce the force below the force limit threshold. There are different ways to reduce the pressure:
Pulling the syringe plunger is not possible as long as the safety stop input is active. To reduce the pressure by pulling the syringe plunger, you first need to disable the force monitoring by calling LCP_EnableForceMonitoring() function. This will clear the safety stop input.
If force monitoring is disabled, you can pull the syringe plunger by executing a flow command with a negative flow rate (aspirating). The following example shows how to do this:
Now the syringe plunger will be pulled slowly out of the syringe and the pressure (force) will decrease. If the force falls below the force limit, then the safety stop input will be set and the pump will be stopped. To detect this event, you just need to monitor the safety stop input via LCP_IsForceSafetyStopActive().
Now you can enable force monitoring again using LCP_EnableForceMonitoring() and the force overload situation is resolved.
If you would like to monitor or log the force sensor value, you can read the current force using the function LCP_ReadForceSensor(). This will return the current force value in the SI unit returned by LCP_GetForceUnit().
See the Force Monitoring module for a detailed description and reference of all force monitoring functions.
A disadvantage of syringe pumps is that the maximum dosable volume is limited by the syringe. If the syringe is empty, the syringe must be refilled. During the refill cycle the dosing is interrupted. To solve this problem and enable uninterrupted, continuous dosing, the SDK offers Continuous Flow functionality.
To generate a continuous flow, two syringe pumps are connected by software to form a virtual continuous flow pump. The continuous flow algorithm then controls the alternating filling and emptying of the syringe, thus creating a continuous flow. The creation of the virtual continuous flow pump can be done during runtime via library functions or by declaring the continuous flow pump in the device configuration file.
The CETONI SDK requires a device configuration (a set of XML files) to control the supported devices. So the first step is to create a device configuration in the QmixElements software with at least 2 neMESYS syringe pumps. The device configuration folder now contains several XML files. Open the file nemesys.xml with an editor thats supports syntax highlighting (such as Notepad++).
Now scroll to the end of the <Plugin><labbCAN><DeviceList>
section to insert a new device declaration. The following example shows the declaration of a continuous flow pump at the end of the <DeviceList>
section:
The following things are declared in the example:
ContiFlowPump_1
is givenLcl::CContiFlowPump
for a continuous flow pumpneMESYS_Low_Pressure_1_Pump
is assigned as the first pump channel. The syringe pump with the given name must exist in the device list aboveneMESYS_Low_Pressure_1_Valve
is assigned to the first syringe pump channel. For the valve the switching positions are configured for aspirating, dispensing and closed state. A value of -1 indicates that this position is not used and will not be switched.In the following lines the second pump and the valve for the second pump are declared.
If you now load this device configuration into the CETONI SDK, then you can easily access the continues flow pump from source code:
As an alternative to creating the pump via the configuration file, the pump can also be created in source code at runtime. The first step is to obtain the device handles for all devices that should be combined into a continuous flow pump. Any error checking code has been removed to keep the example simple.
If you have all required device handles, you can start to create the pump device:
First the continuoues flow pump is created by assigning the two syringe pumps. The device handle is returned in the ContiFlowPump
variable. Then the first valve for the first pump channel is configured and the the first valve for the second pump channel. After these steps, the continuous flow pump has the same configuration like the pump created via the device configuration file above.
If you have a valid continuous flow pump handle, you can start to parameterize the continuous flow. This is the same procedure like you know if from the continuous flow wizard in the QmixElements software. At the moment, the continus flow pump supports only cross flow switching. This means, the cross flow algorithm provides a soft transition and a constant flow rate when switching from one dosing unit to the other. This mode is most suitable if your application uses a low system pressure and you don’t have pressure sensors.
The first thing you need to configure is the switching mode for the continuous flow. At the moment only the cross flow is supported but pressure controlled switching will come soon.
Then you need to configure the maximum refill flow rate that is allowed in your application. If you would like to know the maximum possible refill flow, then you can query it like this:
Then you can limit the maximum flow rate like this:
The next parameter that you can configure is the cross flow duration. This is the time to cross-fade the flows of both syringe pumps. The smaller this value, the steeper the flow rate curve and the less time is required for the cross-flow operation to be completed. A value of 1 second is a good initial default value. If you do not want to cross fade, then use a value of 0.
An optional parameter that you can configure is the overlap duration. This is the period of time by which the flow curves of both pumps overlap. It is a simple way of compensating for pressure drops during switching, because the second pump starts earlier to pressurize. The larger the value, the longer both pumps keep dosing simultaneously
If you have configured all parameters, you can no query the maximum continuous flow rate. Because of the times for switching, cross flow and overlap, the maximum flow rate of the continuous flow pump is lower than the maximum flow rate of the single syringe pumps.
To start the continuous flow, the pump needs to be initialized properly. This means that at least one of the two syringe pumps should contain enough liquid for dosing so that the other pump can be filled during dosing.
The first step is to clear all potential errors of the pump. Then you need to bring the pump into enable state - that means, both syringe pumps should be enabled. If the positioning system of both syringe pumps has not been initialized, then you need to excute a reference move via LCP_SyringePumpCalibrate function.
The last step will start the initialization procedure that will fill one syringe with the configured refill flow rate. See capi_nemesys_test.cpp for more details.
If you have properly configured and initialized your continuous flow pump, you can use it like any other pump. That means, you can use the normal pump control and pump status functions.
See the labbCAN Pump API module for a detailed reference of the pump library application programming interface