How to Control your NE-1000 Syringe Pump with Python?

How to Control your NE-1000 Syringe Pump with Python?

In a world of laboratory automation where precision and control are paramount, syringe pumps serve as excellent tools for delivering precise volumes of liquid with accuracy and reproducibility. Among these pumps, the NE-1000 stands out for its robust performance and versatility. 

In this blog post, we detail the RS-232 communication control of the NE-1000 syringe pump, explore its capabilities and provide insights into setting up communication and interfacing with Python with step-by-step instructions to streamline the process. Whether you’re a seasoned researcher or a newbie with pump control, this blog post equips you with the knowledge and tools to take control of your NE-1000 pump.

TABLE OF CONTENTS

Why Choose the NE-1000 Syringe Pump?

The NE-1000 syringe pump from New Era Pump Systems is prized for its reliability and flexibility. It offers a wide range of flow rates (from 0.73 μL/hr with a 1 mL syringe to 2120 mL/hr with a 60 mL syringe) and precise volume delivery, making it ideal for various applications such as drug dosing and calibrated injections. With its compact design and user-friendly interface, the NE-1000 simplifies experimental setups while ensuring consistent and accurate results.

It is fully programmable standalone or via any computer or device with an RS-232  communication port. It has a built-in pump network driver with a pump network supporting up to 100 pumps and other devices. It is also characterized by its non-volatile memory of all operating parameters and pumping program allowing complex pumping applications and interactions with external devices.

What is a Pumping Program?

A Pumping Program dictates the sequence of actions performed by the pump, including setting pumping rates, volumes, directions, and executing pauses or conditional statements. These previously defined sequence of functions ensure precise and automatic pump operation, with and without user intervention.

A pumping program can be entered directly from the pump’s keypad, or uploaded from a computer using dedicated software: PumpTerm, a pump terminal emulator that facilitates communication with any pump equipped with a PC interface by uploading programs and commands from a file or SyringePumpPro that serves as a control software for pumps and allows automatic monitoring of all pump parameters.

Additionally, a pumping program generator spreadsheet is available to assist in developing pumping programs and in creating and organizing pumping sequences, that can be stored in a text file and uploaded to the pump for execution 📄.

An image of a NE-1000 syringe pump controlled by a PC using the pumping program generator. The image has a white background.

While PumpTerm and SyringePumpPro are valuable tools for controlling syringe pumps, they are not the only options available. One can use programming platforms like Python that has robust libraries for serial communication enabling precise control and automation of the NE-1000 pump.

Before we explore how Python can be utilized for precise control of the NE-1000 syringe pump providing examples and insights into its application, we will briefly detail the RS-232 command set used to communicate with the NE-1000. If you’re already familiar with the RS-232 communication protocol, feel free to jump directly to the Python code snippets.

What do you Need to Communicate with the NE-1000 Pump?

To communicate with the NE-1000 syringe pump using python, you will need a few key components:

  • An NE-1000 syringe pump with a syringe of your choice,
  • An RS-232 cable  allowing for serial communication and enabling data transfer between the syringe pump and the computer,
  • A Serial Port: The computer must have an available serial port or a USB-to-serial adapter for connecting to the RS-232 cable,
  • A Python Environment with the PySerial package that encapsulates access to the serial port,
  • A basic understanding of the RS-232 command set detailed in the pump’s user manual.

How to Set Up the Communication Port?

Before you can start sending commands to the NE-1000 pump via Python, it’s essential to configure the communication port. Follow these steps to establish a connection 🔧:

  • Connect the RS-232 cable to the serial port on the rear of the NE-1000 syringe pump and the corresponding port on the computer.
  • Turn on the pump.
  • Ensure that the serial port settings match the specifications of your syringe pump:
    • 1 start bit
    • 8 data bits
    • Parity: none
    • 1 stop bit
    • a baud rate of 19200 bits/s
  • Identify the serial port name assigned to the connection on your computer (e.g., COM4 for Windows or /dev/ttyUSB0 for Linux). You can typically find this information in the device manager or by using terminal coammands.
  • A triangle icon (on the top left of the pump screen) indicates successful communication, persisting until power-off or entering ‘Setup Configuration’.
  • Test the connection by sending a simple command, such as querying the pump status.

What is the RS-232 Command Set?

The NE-1000 syringe pump communicates through RS-232 storing data changes in non-volatile memory, excluding pumping rate adjustments during operation. Each program phase encompasses pumping rate, volume to dispense and pumping direction selectable using the ‘PHN’ command. 

The RS-232 Command Set used to control the NE-1000 pump is summarized in the table below. Commands without parameters serve as queries returning requested data. Responses typically mirror command parameters. Successful setting commands prompt a status response while unsuccessful ones generate an error message. 

CommandDefinition
DIA [float]Syringe inside diameter
PHN [phase data]Program phase number
FUN [phase function]Program phase function
RATPumping 'RATE' function
RAT [float | rate units]Pumping rate
VOL [float | volume units]Volume to be dispensed
DIR [INF \ WDR]Pumping direction
INCIncrement rate function, 'INCR'
DECDecrement rate function, 'DECR'
JMP [phase data]Jump to program phase function, 'JP:nn'
LPSStart loop, 'LP:ST'
LOP [count data]Loop to previous loop start 'nn' times, 'LP:nn'
LPEEnd loop, 'LP:EN'
PAS [number data]Pause pumping for 'nn' seconds, 'PS:nn'
BEPSound short beep, 'BEEP'
CLD [INF \ WDR]Clear volume dispensed
RESETReset pump and clear program memory
RUNStart the pumping program
STPStop pump, 'STOP'

The rate units are ‘UM’ for µL/min, ‘MM’ for mL/min, ‘UH’ for µL/hr and ‘MH’ for mL/hr. The volume units are ‘UL’ for µL and ‘ML’ for mL. These are set according to the current syringe diameter setting.

When sending the ‘RUN’ command to the pump, the Pumping Program resumes at the point where it was stopped, in the case it was paused. Otherwise, the Pumping Program starts from Phase 1. While executing the ‘RUN #’ command, the program initiates from the specified phase (# is the phase ‘PHN’ number).

When the ‘STP’ command is sent to the pump, if the Pumping Program is operating, this latter will be paused and the pump will be stopped. If the Pumping Program is already paused, the ‘STP’ command will cancel the pause and reset the Pumping Program to Phase 1. For more details about the RS-232 command set, kindly check the NE-1000 syringe pump’s documentation.

With the communication port configured and having basic understanding of the RS-232 command set, you’re ready to start developing Python scripts to control the NE-1000 syringe pump 🕹️.

💡 Upgraded features to the standard NE-1000 firmware:

  • The X Firmware Advanced Features Upgrade with a Linear/Gradient ramping for smooth gradients and additional programming functions.
  • The X2 Firmware Advanced Features and Memory Upgrade including all of the features of the X firmware version with an increase of the pumping program memory from 41 to 340 phases.

How to Control NE-1000 Pump Using Python?

Python code snippets showing how to open the serial port, write and send control command strings to the pump and write a pumping program to the NE-1000 will be presented below.

We’ll walk through code snippets that demonstrate how to perform common tasks such as infusing liquids, setting pumping rates, and executing complex pumping sequences. These examples will provide a hands-on understanding of Python-based control of the NE-1000 syringe pump.

Replicating SyringePumpPro and PumpTerm Functionality

In this first part, we will use Python to replicate the functionality offered by SyringePumpPro and PumpTerm: uploading a Pumping Program from a computer (or writing it directly to the pump). This subsection will elucidate how a Python script effectively emulates the capabilities of these software tools, enabling the control and automation of the NE-1000 syringe pump.

We will use the Python “serial” library to establish communication with the NE-1000 syringe pump via a serial port connection. First, we import the “serial” module, which provides tools for serial communication. The “serial.Serial” function is then employed to initialize the serial port connection, specifying parameters such as port name (‘COM2’), baud rate (19200), and communication settings like parity, byte size, and stop bits.

The Python code snippets are presented and detailed below👇. 

Uploading a PPL File from a Computer to the Pump

				
					### UPLOADING A PPL FILE FROM A COMPUTER TO THE PUMP 
import serial # serial library to establish communication with the pump
import time

# Open the serial port
ser = serial.Serial('COM2', 19200, parity=serial.PARITY_NONE, bytesize=8, stopbits=1, timeout=None, xonxoff=0, rtscts=0) # make sure to modify the port name 'COM2' with the corresponding port on your computer

# Define a function to send commands (with an option to read responses from the pump)
def send_command(command):
    ser.write((command + '\r\n').encode()) # send commands as encoded strings
    time.sleep(0.1)  # brief delay allowing time for the pump to process the command

# Define a function to read the content of a PPL file
def read_ppl_file(file_path):
    with open(file_path, 'r') as file:
        return file.read()

# PPL file path; make sure you modify it by writing your file path
ppl_file_path = 'C:/Users/DarwinMicrofluidics/Desktop/NE1000/Test.ppl'

# Read the content of the PPL file
ppl_content = read_ppl_file(ppl_file_path)

# Reset pump
send_command("RESET")

# Split PPL content into lines and send each line as a command
for line in ppl_content.split('\n'):
    line = line.strip()  # remove leading/trailing whitespaces
    if line:  # skip empty lines
        send_command(line) # send the command line to the pump
        
# Run the pumping program
send_command("RUN")
 
# Once the program executed, close the serial port (optional)
ser.close()

				
			

The “send_command” function is defined to streamline the process of sending commands to the pump (with an option also to read its response). Within this function, commands are sent to the pump as encoded strings, followed by a brief delay using “time.sleep()” to allow time for the pump to process the command.

Additionally, a “read_ppl_file” function is included to read the content of a Pump Programming Language (PPL) file, which contains sequences of commands to be executed by the pump. The file path to the PPL file is specified, and its content is read using the “read_ppl_file” function.

The pump is reset using the “RESET” command, ensuring a clean start before executing the sequence of commands contained in the PPL file. The PPL content is split into lines, and each line is sent as a command to the pump using the “send_command” function. Finally, the “RUN” command is sent to initiate the pumping process.

Once all commands have been executed, the serial port connection can be closed using “ser.close()”, ensuring proper cleanup of resources.

Writing a Pumping Program to the Pump

The previous code demonstrates a streamlined approach to controlling the NE-1000 syringe pump using Python. However, one may not have access to the pumping program generator spreadsheet or simply prefers writing the pumping program directly in the python script to make direct and visual modifications to the program before sending it to the pump. This approach offers greater flexibility and immediacy in programming the pump’s actions. The following code snippet illustrates this method, allowing users to define the pumping program directly within the Python script enabling real-time adjustments of parameters and sequences.

				
					### WRITING A PUMPING PROGRAM TO THE PUMP 
import serial # serial library to establish communication with the pump
import time

# Open the serial port
ser = serial.Serial('COM2', 19200, parity=serial.PARITY_NONE, bytesize=8, stopbits=1, timeout=None, xonxoff=0, rtscts=0) # make sure to modify the port name 'COM2' with the corresponding port on your computer

# Define a function to send commands (with an option to read responses from the pump)
def send_command(command):
    ser.write((command + '\r\n').encode()) # send commands as encoded strings
    time.sleep(0.1)  # brief delay allowing time for the pump to process the command

# Define your pumping program
Pumping_Program = """
DIA 26.59

PHN 1
FUN RAT
RAT 500 MH
VOL 2.0
DIR INF

PHN 2
FUN PAS 10

PHN 3
FUN RAT 
RAT 200 MH 
VOL 1.0
DIR WDR

PHN 4 
FUN STP
"""

# Reset pump
send_command("RESET")

# Split the content of the program into lines and send each line as a command
for line in Pumping_Program.split('\n'):
    line = line.strip()  # remove leading/trailing whitespaces
    if line:  # skip empty lines
        send_command(line) # send the command line to the pump
        
# Run the pumping program
send_command("RUN")
 
# Once the program executed, close the serial port (optional)
ser.close()

				
			

Herein, we define a Pumping_Program directly within the Python script. The program (detailed in the Examples of Pumping Programs below 👇) contains a sequence of commands,  organized into individual lines. Each line is sent as a command to the pump using the “send_command” function.

After sending the entire pumping program to the pump, the “RUN” command is issued to initiate the pumping process.

Examples of Pumping Programs

Below are three examples of pumping programs designed for the NE-1000 syringe pump, each tailored to specific experimental requirements.

Example 1: Infusing and Withdrawing Liquids

In this example, the NE-1000 syringe pump infuses a liquid at a specified rate and volume, pauses for 10 seconds, withdraws a different volume at a different rate and then stops. The different phases of the pumping program are summarized in the table below and the corresponding program is shown in the code snippet.

PhaseFunctionValueRateVolumeDirection
1RAT-500 mL/hr2.0 mLInfuse
2PAS10---
3RAT-200 mL/hr1.0 mLWithdraw
4STP----
				
					Example1 = """
DIA 26.59

PHN 1
FUN RAT
RAT 500 MH
VOL 2.0
DIR INF

PHN 2
FUN PAS 10

PHN 3
FUN RAT 
RAT 200 MH 
VOL 1.0
DIR WDR

PHN 4 
FUN STP
"""

# start by setting the syringe diameter
# no need to set the volume units when setting the volume in a RATE function
				
			

Example 2: Repeated Dispenses with Suck Back

This pumping program dispenses 2.0 mL of a liquid with a 20 seconds pause interval between dispenses (a total of 4 dispenses). After each dispense, a small volume of 0.25 mL is withdrawn to prevent dripping. Additionally, a beep signal is emitted 3 seconds before the end of each pause to signal the upcoming dispense. Starting from the second dispense, 0.25 mL is added to the dispensed volume to compensate for the sucked back volume of the previous dispense.

The different phases of the pumping program are summarized in the table below and the corresponding program is shown in the code snippet.

PhaseFunctionValueRateVolumeDirection
1RAT-500 mL/hr2.0 mLInfuse
2RAT-500 mL/hr0.25 mLWithdraw
3LPS----
4PAS17---
5BEP----
6PAS3---
7RAT-500 mL/hr2.25 mLInfuse
8RAT-500 mL/hr0.25 mLWithdraw
9LOP3---
				
					Example2 = """
DIA 26.59

PHN 1
FUN RAT
RAT 500 MH
VOL 2.0
DIR INF

PHN 2
FUN RAT
RAT 500 MH
VOL 0.25
DIR WDR

PHN 3
FUN LPS

PHN 4
FUN PAS 17

PHN 5
FUN BEP

PHN 6
FUN PAS 3

PHN 7
FUN RAT
RAT 500 MH
VOL 2.25
DIR INF

PHN 8
FUN RAT
RAT 500 MH
VOL 0.25
DIR WDR

PHN 9
FUN LOP 3
"""

# an initial dispense of 2 mL followed by 3 dispenses of 2.25 mL
# send_command("STP") at any moment to pause/stop the pumping program
				
			

Example 3: Flow Rate Ramping

This pumping program continuously ramps up and down the pumping rate, incrementing from an initial value of 300 mL/hr to 400 mL/hr in 20 mL/hr steps each time after dispensing a volume of 0.5 mL. After reaching the maximum rate, the pumping rate decrements in similar steps, after every 0.5 mL has been dispensed, until reaching 200 mL/hr. Finally, the rate is incremented back to the initial value, and the cycle repeats.

The different phases of the pumping program are summarized in the table below and the corresponding program is shown in the code snippet.

PhaseFunctionValueRateVolumeDirection
1RAT-300 mL/hr0.5 mLInfuse
2LPS----
3INC-20 mL/hr0.5 mLInfuse
4LOP5---
5LPS----
6DEC-20 mL/hr0.5 mLInfuse
7LOP10---
8LPS----
9INC-20 mL/hr0.5 mLInfuse
10LOP5---
11JMP2---
				
					Example3 = """
DIA 26.59

PHN 1
FUN RAT
RAT 300 MH
VOL 0.5
DIR INF

PHN 2
FUN LPS

PHN 3
FUN INC
RAT 20
VOL 0.5
DIR INF

PHN 4
FUN LOP 5

PHN 5
FUN LPS

PHN 6
FUN DEC
RAT 20
VOL 0.5
DIR INF

PHN 7
FUN LOP 10

PHN 8
FUN LPS

PHN 9
FUN INC
RAT 20
VOL 0.5
DIR INF

PHN 10
FUN LOP 5

PHN 11
FUN JMP 2
"""

# send_command("STP") at any moment to pause/stop the pumping program
# no need to set the rate units when setting the rate step in a INC and DEC functions
				
			

Custom Python Library for NE Syringe Pump Control

In this second part, a different effective way to control the NE-1000 syringe pump using Python is introduced. A custom Python library is developed where easy-to-use functions can be used to set parameters, execute actions, and manage communication.

Below, we’ll present and explain the custom library and its various functions for controlling the NE-1000 syringe pump. Following that, we’ll delve into three different pumping program examples (Examples 1, 2 and 3 just presented above), demonstrating how these functions can be utilized to execute precise pumping sequences.

				
					### Custom Library for NE-1000 syringe pump
import serial
import time

class NewEraSyringePump:

    # Open the serial port
    def __init__(self, port):
        self.ser = serial.Serial(port, 19200, parity=serial.PARITY_NONE, bytesize=8, stopbits=1, timeout=None, xonxoff=0, rtscts=0) # data format corresponding to the NE-1000
        time.sleep(0.075)  # time for the pump to initialize

    # Write a command to the syringe pump
    def send_command(self, command):
        self.ser.write(command.encode() + b'\r\n') # convert the command string into bytes, append a carriage return and line feed, and send the resulting byte sequence to the serial port
        time.sleep(0.075) # a brief delay to ensure that the pump has enough time to process the command before proceeding to the next operation

    # Set the syringe diameter
    def set_diameter(self, diameter):
        command = f"DIA {diameter}" # DIA for syringe inside diameter (float)
        self.send_command(command) # set the syringe diameter using the "send_command" function 
       
    # Set the pumping rate
    def set_rate(self, rate, r_units):
        command = f"RAT {rate} {r_units}" # RAT for pumping rate 
        # Rate units: 'MH' for mL/hr - 'MM' for mL/min - 'UH' for µL/hr - 'UM' for µL/min
        self.send_command(command)

    # Set the volume
    def set_volume(self, volume, units):
        command = f"VOL {volume} {units}" # VOL for volume 
        # Volume units: 'ML' for mL - 'UL' for µL
        self.send_command(command)

    # Set the pumping direction
    def set_direction(self, direction):
        if direction == 0: 
            command = "DIR INF" # DIR for pumping direction - INF for infuse
        elif direction == 1: 
            command = "DIR WDR" # WDR for withdraw
        elif direction == 2:  
           command = "DIR REV" # REV for reverse direction
        self.send_command(command)
    
    # Start the pump
    def start_pump(self):
        self.send_command("RUN") # RUN to run the pump

    # Stop the pump
    def stop_pump(self):
        self.send_command("STP") # STP to stop the pump
        
    # Define the "RATE" Function
    def run_RATE_function(self, rate, rate_units, volume, units, direction):
        self.set_rate(rate, rate_units) # Set the pumping rate
        self.set_volume(volume, units) # Set the pumping volume
        self.set_direction(direction) # Set the pumping direction
        self.start_pump() # Start the pumping rate function
        time.sleep(float(volume*3600/rate)) # pumping duration: a delay to ensure that the pump dispenses the required volume at the given pumping rate
        self.stop_pump()
        
    # Reset the pump
    def reset_pump(self):
        self.send_command("RESET") # RESET to reset the pump
        
    # Pump beep
    def beep(self):
        self.send_command("BEP") # BEP for the pump beep

    # Delete the pump
    def __del__(self):
        self.ser.close() # close the serial communication port
        
##### BELOW are the commands that should be executed #####

				
			
This custom library allows controlling the NE-1000 syringe pump. It establishes communication with the pump via a serial port and enables users to set parameters such as syringe diameter, pumping rate, volume, and direction. Users can initiate pump actions like starting, stopping, and resetting the pump. Additionally, a “RATE” function is defined using a set of already defined functions. Through this library, users can create precise pumping sequences directly from their Python environment, as will be demonstrated in the three following examples below.

Example 1: Infusing and Withdrawing Liquids

In this example, the NE-1000 syringe pump infuses a liquid at a specified rate and volume, pauses for 10 seconds, withdraws a different volume at a different rate and then stops. YES, you’re right ! This example was presented just above, which illustrates how the library allows executing the same pumping sequence described previously.
				
					#%% Example 1: Infuse 4.0 mL at 500 mL/hr, pause the pumping for 10s and then withdraw 2.0 mL at 200 mL/hr. Finally, stop the pump.

# Initialize the pump with the specified COM port
pump = NewEraSyringePump('COM2') # Replace 'COM2' with the actual COM port used for your connection

# Reset pump
pump.reset_pump() # Reset the pump parameters

# Set syringe diameter
pump.set_diameter(26.59) # Change this value according to the syringe you're using

### BEGIN PUMPING SEQUENCE ###

# First RATE function
pump.run_RATE_function(500, "MH", 4, "ML", 0) # Infuse 4.0 mL at 500 mL/hr

# Pause pumping
pause_time = 10 
time.sleep(float(pause_time)) # Pause the pumping for 10 seconds

# Second RATE function 
pump.run_RATE_function(200, "MH", 2, "ML", 1) # Withdraw 2.0 mL at 200 mL/hr

### END PUMPING SEQUENCE ###

# Delete pump and close the serial communication port
del pump
				
			

This Python code snippet demonstrates the use of the custom library for controlling the NE-1000 syringe pump to execute a specific pumping sequence. First, the pump is initialized with the specified COM port, and then it’s reset to ensure default parameters. The syringe diameter is set accordingly.
The pumping sequence consists of three main steps:

  • The pump infuses 4.0 mL of liquid at a rate of 500 mL/hr.
  • After a 10-second pause, the pump withdraws 2.0 mL of liquid at a rate of 200 mL/hr.
  • Finally, the pump is stopped.

Each step of the sequence is executed using the “run_RATE_function” method of the “NewEraSyringePump” class, specifying the pumping rate, volume, units, and direction. After the pumping sequence is completed, the pump instance is deleted, and the serial communication port is closed.

This code provides a straightforward example of how the custom library can be used to control the NE-1000 syringe pump and execute precise pumping sequences. Two more examples are provided below.

Example 2: Repeated Dispenses with Suck Back

This pumping program dispenses 2.0 mL of a liquid with a 20-second pause interval between dispenses (a total of 4 dispenses). After each dispense, a small volume of 0.25 mL is withdrawn to prevent dripping. Additionally, a beep signal is emitted 3 seconds before the end of each pause to signal the upcoming dispense. Starting from the second dispense, 0.25 mL is added to the dispensed volume to compensate for the sucked back volume of the previous dispense. The corresponding program is shown in the code snippet below.
				
					#%% Example 2: Dispense 2.0 mL at 500 mL/hr with a pause of 20 seconds between dispenses. In addition, after each dispense, a volume of 0.25 mL is sucked back at the same flow rate to prevent dripping. 3 seconds before the end of the pause interval, a beep is sounded to alert the operator to prepare for the next dispense. Starting with the second dispense, 0.25 mL is added to the volume dispensed to compensate for the sucked back volume of the previous dispense. 3 dispenses are executed after the initial dispense.

# Initialize the pump with the specified COM port
pump = NewEraSyringePump('COM2') # Replace 'COM2' with the actual COM port used for the connection

# Reset pump
pump.reset_pump() # Reset the pump parameters

# Set syringe diameter
pump.set_diameter(26.59) # Change this value according to the syringe you're using

### BEGIN PUMPING PROGRAM ###

dispensed_volume = 2.0  # Initial dispensed volume
nb_dispenses = 3  # Number of dispenses executed after the initial dispense
suck_back_volume = 0.25  # Volume sucked back after each dispense
pause_time = 20  # Pause time of 20 seconds

# Initial dispense and suck back
pump.run_RATE_function(500, "MH", dispense_volume, "ML", 0)  # RATE function to dispense, 0 to infuse
pump.run_RATE_function(500, "MH", suck_back_volume, "ML", 1)  # RATE function to suck back, 1 to withdraw

# Execute 3 more dispenses after the initial dispense 
for dispense_count in range(nb_dispenses):
    # Wait for the specified pause time
    time.sleep(pause_time - 3)  # Wait for 20s - 3s
    # Beep to alert the operator 3 seconds before the end of the pause 
    pump.beep() # Pump beep
    time.sleep(3)  # Wait for the remaining 3 seconds
    
    # Run the RATE function for dispensing while adding 0.25 mL to the volume dispensed to compensate for the sucked back volume of the previous dispense
    pump.run_RATE_function(500, "MH", dispense_volume + suck_back_volume, "ML", 0)
    # Run the pumping rate function for suck back
    pump.run_RATE_function(500, "MH", suck_back_volume, "ML", 1)
    
### END PUMPING PROGRAM ###

# Delete pump
del pump

				
			

Example 3: Flow Rate Ramping

This pumping program continuously ramps up and down the pumping rate, incrementing from an initial value of 300 mL/hr to 400 mL/hr in 20 mL/hr steps each time after dispensing a volume of 0.5 mL. After reaching the maximum rate, the pumping rate decrements in similar steps, after every 0.5 mL has been dispensed, until reaching 200 mL/hr. Finally, the rate is incremented back to the initial value, and the cycle repeats. The corresponding program is shown in the code snippet below.
				
					#%% Example 3: Continuously ramp up and down the pumping rate. 
# Starting at 300 mL/hr, the pumping rate will increment to 400 mL/hr in 20 mL/hr steps after every 0.5 mL has been dispensed. 
# Then the pumping rate will decrement to 200 mL/hr in 20 mL/hr steps after every 0.5 mL has been dispensed. 
# Finally, the pumping rate is incremented back to 300 mL/hr in 20 mL/hr steps after every 0.5 mL has been dispensed, then the process is repeated. 

# Initialize the pump with the specified COM port
pump = NewEraSyringePump('COM2')  # Replace 'COM2' with the actual COM port used for the connection

# Reset pump
pump.reset_pump() # Reset the pump parameters

# Set syringe diameter
pump.set_diameter(26.59) # Change this value according to the syringe you're using

### BEGIN PUMPING PROGRAM ###

# Define initial variables
current_rate     = 300 # Initial flow rate
increment        = 20 # 20 mL/hr steps
dispensed_volume = 0.5 # volume to be dispensed before each rate ramp change

# Define the boundaries
lower_boundary = 200 # the minimum flow rate
upper_boundary = 400 # the maximum flow rate

# Continuously ramp up and down the pumping rate
while True:
    # Ramp up the pumping rate
    while current_rate < upper_boundary:
        # Run pumping rate function for the defined volume and rate
        pump.run_RATE_function(current_rate, "MH", dispense_volume, "ML", 0)

        # Increment the pumping rate
        current_rate += increment

        # Check if the rate exceeds the upper boundary
        if current_rate > upper_boundary:
            current_rate = upper_boundary
    
    # Ramp down the pumping rate
    while current_rate > lower_boundary:
        # Run pumping rate function for the defined volume and rate
        pump.run_RATE_function(current_rate, "MH", dispense_volume, "ML", 0)

        # Decrement the pumping rate
        current_rate -= increment

        # Check if the rate is below the lower boundary
        if current_rate < lower_boundary:
            current_rate = lower_boundary

### END PUMPING PROGRAM ###

# Delete pump
del pump

				
			

While the custom Python library presents a valuable tool for controlling the NE-1000 syringe pump, it’s essential to acknowledge the inherent limitation posed by the time delay in RS-232 communication. This observed delay arises from the pump’s process of receiving and executing commands, resulting in a very short lag between consecutive commands.

This delay, albeit minor, can result in slight discrepancies in dispensed volumes, particularly noticeable when rapid rate changes are required within a pumping program as during rate changes, the pump operation should be stopped to send a new rate as stipulated in the pump’s documentation. It specifies that the new rate is only stored in non-volatile memory if the Pumping Program is not operating 🚧. This can, in some cases, disrupt the fluid flow and affect the accuracy of the experiment.

Despite attempts to mitigate this issue through strategic command sequencing and time delays, the challenge persists, influencing the pump’s ability to maintain continuous and precise pumping operations, especially in time-sensitive microfluidic experiments.  Moving forward, addressing this delay issue remains a priority to ensure optimal pump performance and accurate experimental outcomes.

Conclusion

In this blog post, we’ve explored the basics of the RS-232 communication control of the NE-1000 syringe pump using Python, covering everything from configuring the communication port to programming custom pumping sequences. We hope this post serves as a valuable guide for researchers and engineers seeking to employ Python to remotely control their New Era Syringe Pumps using the RS-232 command set.

Stay tuned for more insights, tutorials, and practical applications in our future posts. Until then, happy pumping and coding 💻!

📧 If you have any questions or feedback, please feel free to contact us at contact@darwin-microfluidics.com.