En el ámbito de la automatización de laboratorios, donde la precisión y el control son fundamentales, las bombas de jeringa constituyen herramientas excelentes para dosificar volúmenes precisos de líquido con exactitud y reproducibilidad. Entre estas bombas, labomba de jeringa NE-1000destacapor su rendimiento robusto y su versatilidad.
En esta entrada del blog, detallamos el control de la comunicación «RS-232 » de la bomba de jeringa NE-1000, exploramos sus capacidades y ofrecemos información sobre cómo configurar la comunicación y la interfaz con Python, con instrucciones paso a paso para agilizar el proceso. Tanto si eres un investigador experimentado como si eres un principiante en el control de bombas, esta entrada del blog te proporcionará los conocimientos y las herramientas necesarios para tomar el control de tu bomba NE-1000.
ÍNDICE
¿Por qué elegir la bomba de jeringa NE-1000?
La bomba de jeringa NE-1000de New Era Pump Systems es muy apreciada por su fiabilidad y flexibilidad. Ofrece un amplio rango de caudales (desde 0,73 μL/h con una jeringa de 1 mL hasta 2120 mL/h con una jeringa de 60 mL) y un suministro de volumen preciso, lo que la hace ideal para diversas aplicaciones, como la dosificación de fármacos e inyecciones calibradas. Gracias a su diseño compacto y a su interfaz intuitiva, la NE-1000 simplifica la configuración de los experimentos al tiempo que garantiza resultados consistentes y precisos.
Es totalmente programable de forma autónoma o a través de cualquier ordenador o dispositivo que cuente con un puerto de comunicación « RS-232 ». Incorpora un controlador de red de bombas integrado, con una red capaz de gestionar hasta 100 bombas y otros dispositivos. También destaca por su memoria no volátil, que almacena todos los parámetros de funcionamiento y el programa de bombeo, lo que permite aplicaciones de bombeo complejas e interacciones con dispositivos externos.
¿Qué es un programa de extracción de leche?
Un programa de bombeo determina la secuencia de acciones que realiza la bomba, lo que incluye la configuración de las velocidades de bombeo, los volúmenes y las direcciones, así como la ejecución de pausas o instrucciones condicionales. Esta secuencia de funciones, definida previamente, garantiza un funcionamiento preciso y automático de la bomba, tanto con intervención del usuario como sin ella.
Un programa de bombeo puede introducirse directamente desde el teclado de la bomba o cargarse desde un ordenador mediante un software específico: PumpTerm,un emulador de terminal de bomba que facilita la comunicación con cualquier bomba equipada con una interfaz para PC mediante la carga de programas y comandos desde un archivo; oSyringePumpPro,que actúa como software de control para bombas y permite la supervisión automática de todos los parámetros de la bomba.
Además, hay disponible una hoja de cálculo generadora de programas de bombeo que sirve de ayuda para desarrollar programas de bombeo y para crear y organizar secuencias de bombeo, las cuales pueden guardarse en un archivo de texto y cargarse en la bomba para su ejecución📄.
Aunque PumpTerm y SyringePumpPro son herramientas muy útiles para controlar las bombas de jeringa, no son las únicas opciones disponibles. Se pueden utilizar plataformas de programación como Python, que cuenta con bibliotecas sólidas para la comunicación en serie que permiten un control preciso y la automatización de la bomba NE-1000.
Antes de analizar cómo se puede utilizar Python para controlar con precisión la bomba de jeringa NE-1000, con ejemplos y explicaciones sobre su aplicación, detallaremos brevemente el conjunto de comandos RS-232 que se utiliza para comunicarse con la NE-1000. Si ya estás familiarizado con el protocolo de comunicación RS-232 , no dudes en pasar directamente a los fragmentos de código de Python.
¿Qué se necesita para comunicarse con la bomba NE-1000?
Para comunicarte con la bomba de jeringa NE-1000 mediante Python, necesitarás algunos componentes clave:
- Una bomba de jeringa NE-1000 con una jeringa de su elección,
- Un cable «RS-232 »que permite la comunicación en serie y facilita la transferencia de datos entre la bomba de jeringa y el ordenador,
- Un puerto serie: El ordenador debe disponer de un puerto serie libre o de un adaptador de « USB » a serie para conectarse al cable « RS-232 »,
- Un entorno de Python con el paquete PySerial, que encapsula el acceso al puerto serie,
- Conocimientos básicos sobre el conjunto de comandos «RS-232 », tal y como se detalla en el manual de usuario de la bomba.
¿Cómo configurar el puerto de comunicación?
Antes de poder empezar a enviar comandos a la bomba NE-1000 a través de Python, es imprescindible configurar el puerto de comunicación. Sigue estos pasos para establecer una conexión🔧:
- Conecta el cable « RS-232 » al puerto serie situado en la parte trasera de la bomba de jeringa NE-1000 y al puerto correspondiente del ordenador.
- Encienda la bomba.
- Asegúrese de que la configuración del puerto serie coincida con las especificaciones de su bomba de jeringa:
- 1 bit de inicio
- 8 bits de datos
- Paridad: ninguna
- 1 bit de parada
- una velocidad de transmisión de 19 200 bits/s
- Identifique el nombre del puerto serie asignado a la conexión en su ordenador (por ejemplo, COM4 en Windows o /dev/ttyUSB0 en Linux). Por lo general, puede encontrar esta información en el administrador de dispositivos o mediante comandos de terminal.
- Un icono con forma de triángulo (en la parte superior izquierda de la pantalla de la bomba) indica que la comunicación se ha establecido correctamente; permanecerá visible hasta que se apague el dispositivo o se acceda a «Configuración».
- Pruebe la conexión enviando un comando simple, como consultar el estado de la bomba.
¿Qué es el conjunto de comandos « RS-232 »?
La bomba de jeringa NE-1000 se comunica a través de un RS-232 , que almacena los cambios en los datos en una memoria no volátil, salvo los ajustes de la velocidad de bombeo durante el funcionamiento. Cada fase del programa incluye la velocidad de bombeo, el volumen a dispensar y la dirección de bombeo, que se pueden seleccionar mediante el comando «PHN».
El conjunto de comandos « RS-232 » utilizado para controlar la bomba NE-1000 se resume en la tabla siguiente. Los comandossin parámetros sirven como consultas que devuelven los datos solicitados.Las respuestas suelen reflejar los parámetros del comando. Los comandos de configuración que se ejecutan correctamente generan una respuesta de estado, mientras que los que fallan generan un mensaje de error.
| Comando | Definición |
|---|---|
| DIA [float] | Diámetro interior de la jeringa |
| PHN [datos de fase] | Número de fase del programa |
| FUN [función de fase] | Función de fase del programa |
| RAT | Función «RATE» de bombeo |
| RAT [número flotante | unidades de tipo de interés] | Caudal de bombeo |
| VOL [número flotante | unidades de volumen] | Volumen a dispensar |
| DIR [INF \ WDR] | Sentido de bombeo |
| INC | Función de tasa de incremento, «INCR» |
| DEC | Función de tasa de disminución, «DECR» |
| JMP [datos de fase] | Saltar a la función de fase del programa, «JP:nn» |
| LPS | Iniciar bucle, «LP:ST» |
| LOP [datos cuantitativos] | Repetir el bucle anterior «nn» veces, «LP:nn» |
| LPE | Fin del bucle, «LP:EN» |
| PAS [datos numéricos] | Detener el bombeo durante «nn» segundos, «PS:nn» |
| BEP | Un pitido corto, «BEEP» |
| CLD [INF \ WDR] | Volumen neto dispensado |
| REINICIAR | Restablecer la bomba y borrar la memoria del programa |
| CORRER | Iniciar el programa de bombeo |
| STP | Detener la bomba, «STOP» |
Las unidades de caudal son «UM» para µL/min, «MM» para mL/min, «UH» para µL/h y «MH» para mL/h. Las unidades de volumen son «UL» para µL y «ML» para mL. Estas se establecen en función del ajuste actual del diámetro de la jeringa.
Al enviar el comando «RUN» a la bomba, el programa de bombeo se reanuda en el punto en el que se detuvo, en caso de que se hubiera pausado. De lo contrario, el programa de bombeo comienza desde la fase 1. Al ejecutar el comando «RUN #», el programa se inicia desde la fase especificada («#» es el número de la fase «PHN»).
Cuando se envía el comando «STP» a la bomba, si el programa de bombeo está en marcha, este se pondrá en pausa y la bomba se detendrá. Si el programa de bombeo ya está en pausa, el comando «STP» cancelará la pausa y restablecerá el programa de bombeo a la fase 1.Para obtener más detalles sobre el conjunto de comandos de la bomba de jeringa « RS-232 », consulte la documentaciónde la bomba de jeringa NE-1000 .
Una vez configurado el puerto de comunicación y con unos conocimientos básicos sobre el conjunto de comandos « RS-232 », ya estás listo para empezar a desarrollar scripts en Python para controlar la bomba de jeringa NE-1000🕹️.
💡 Funcionalidades mejoradas en el firmware estándar del NE-1000:
- La actualización de funciones avanzadas del firmware X, con una rampa lineal/degradada para obtener degradados suaves y funciones de programación adicionales.
- Las funciones avanzadas y la ampliación de memoria del firmware X2, que incluyen todas las funciones de la versión del firmware X, además de un aumento de la memoria del programa de bombeo de 41 a 340 fases.
¿Cómo programar la bomba de jeringa NE-1000 con Python?
A continuación se presentarán fragmentos de código en Python que muestran cómo abrir el puerto serie, escribir y enviar cadenas de comandos de control a la bomba, así como cómo programar un programa de bombeo en el NE-1000.
Analizaremos fragmentos de código que muestran cómo realizar tareas habituales, como la infusión de líquidos, la configuración de las velocidades de bombeo y la ejecución de secuencias de bombeo complejas. Estos ejemplos te permitirán comprender de forma práctica el control de la bomba de jeringa NE-1000 mediante Python.
Reproducción de las funciones de SyringePumpPro y PumpTerm
En esta primera parte, utilizaremos Python para reproducir la funcionalidad que ofrecen SyringePumpPro y PumpTerm: cargar un programa de bombeo desde un ordenador (o escribirlo directamente en la bomba). En este apartado se explicará cómo un script de Python emula eficazmente las capacidades de estas herramientas de software, lo que permite el control y la automatización de la bomba de jeringa NE-1000.
Utilizaremos la biblioteca«serial»de Python para establecer la comunicación con la bomba de jeringa NE-1000 a través de una conexión por puerto serie. En primer lugar, importamos el módulo«serial», que proporciona herramientas para la comunicación serie. A continuación, se utiliza la función«serial.Serial»para inicializar la conexión del puerto serie, especificando parámetros como el nombre del puerto («COM2»), la velocidad de transmisión (19 200) y ajustes de comunicación como la paridad, el tamaño de byte y los bits de parada.
A continuación se muestran y se explican los fragmentos de código en Python👇.
Cómo cargar un archivo PPL desde un ordenador a la bomba
'''
------------------------------------------------
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()
La función«send_command»se ha definido para agilizar el proceso de envío de comandos a la bomba (con la opción adicional de leer su respuesta). Dentro de esta función, los comandos se envían a la bomba como cadenas codificadas, seguidas de una breve pausa mediante«time.sleep()» para dar tiempo a que la bomba procese el comando.
Además, se incluye una función«read_ppl_file»para leer el contenido de un archivo del lenguaje de programación de bombas (PPL), que contiene secuencias de comandos que debe ejecutar la bomba. Se especifica la ruta de acceso al archivo PPL y su contenido se lee mediante la función«read_ppl_file».
La bomba se reinicia mediante el comando«RESET», lo que garantiza un arranque limpio antes de ejecutar la secuencia de comandos contenida en el archivo PPL. El contenido del PPL se divide en líneas, y cada línea se envía como un comando a la bomba mediante la función«send_command».Por último, se envía el comando«RUN»para iniciar el proceso de bombeo.
Una vez ejecutados todos los comandos, la conexión del puerto serie se puede cerrar mediante«ser.close()», lo que garantiza una gestión adecuada de los recursos.
Cómo programar un programa de bombeo en la bomba
El código anterior muestra un método simplificado para controlar la bomba de jeringa NE-1000 mediante Python. Sin embargo, es posible que no se tenga acceso a la hoja de cálculo generadora del programa de bombeo o que, simplemente, se prefiera escribir el programa de bombeo directamente en el script de Python para realizar modificaciones directas y visuales en el programa antes de enviarlo a la bomba. Este método ofrece mayor flexibilidad e inmediatez a la hora de programar las acciones de la bomba. El siguiente fragmento de código ilustra este método, que permite a los usuarios definir el programa de bombeo directamente en el script de Python, lo que facilita ajustes en tiempo real de los parámetros y las secuencias.
'''
-------------------------------------
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()
En este documento, definimos un «Pumping_Program» directamente dentro del script de Python. El programa (que se detalla en los «Ejemplos de programas de bombeo » que aparecen a continuación 👇) contiene una secuencia de comandos, organizados en líneas individuales. Cada línea se envía como un comando a la bomba mediante la función«send_command».
Una vez enviado el programa completo de bombeo a la bomba, se emite el comando«RUN»para iniciar el proceso de bombeo.
Ejemplos de programas de extracción de leche
A continuación se presentan tres ejemplos de programas de bombeo diseñados para la bomba de jeringa NE-1000, cada uno de ellos adaptado a unos requisitos experimentales específicos.
Ejemplo 1: Administración y extracción de líquidos
En este ejemplo, la bomba de jeringa NE-1000 administra un líquido a un caudal y un volumen determinados, hace una pausa de 10 segundos, extrae un volumen diferente a un caudal distinto y, a continuación, se detiene. Las distintas fases del programa de bombeo se resumen en la tabla siguiente y el programa correspondiente se muestra en el fragmento de código.
| Fase | Función | Valor | Tarifa | Volumen | Dirección |
|---|---|---|---|---|---|
| 1 | RAT | - | 500 ml/h | 2,0 ml | Infusionar |
| 2 | PAS | 10 | - | - | - |
| 3 | RAT | - | 200 ml/h | 1,0 ml | Retirar |
| 4 | STP | - | - | - | - |
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
Ejemplo 2: Dosificaciones repetidas con retroceso
Este programa de bombeo dosifica 2,0 ml de un líquido con un intervalo de pausa de 20 segundos entre cada dosificación (un total de 4 dosificaciones). Tras cada dosificación, se retira un pequeño volumen de 0,25 ml para evitar goteos. Además, se emite un pitido 3 segundos antes de que finalice cada pausa para indicar que la siguiente dosificación está a punto de realizarse. A partir de la segunda dosificación, se añaden 0,25 ml al volumen dosificado para compensar el volumen aspirado de la dosificación anterior.
Las diferentes fases del programa de bombeo se resumen en la tabla siguiente y el programa correspondiente se muestra en el fragmento de código.
| Fase | Función | Valor | Tarifa | Volumen | Dirección |
|---|---|---|---|---|---|
| 1 | RAT | - | 500 ml/h | 2,0 ml | Infusionar |
| 2 | RAT | - | 500 ml/h | 0,25 ml | Retirar |
| 3 | LPS | - | - | - | - |
| 4 | PAS | 17 | - | - | - |
| 5 | BEP | - | - | - | - |
| 6 | PAS | 3 | - | - | - |
| 7 | RAT | - | 500 ml/h | 2,25 ml | Infusionar |
| 8 | RAT | - | 500 ml/h | 0,25 ml | Retirar |
| 9 | LOP | 3 | - | - | - |
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
Ejemplo 3: Aumento gradual del caudal
Este programa de bombeo aumenta y disminuye continuamente el caudal, pasando de un valor inicial de 300 ml/h a 400 ml/h en incrementos de 20 ml/h cada vez que se dispensa un volumen de 0,5 ml. Una vez alcanzado el caudal máximo, este se reduce en incrementos similares, tras cada dispensación de 0,5 ml, hasta llegar a 200 ml/h. Por último, el caudal vuelve a incrementarse hasta el valor inicial y el ciclo se repite.
Las diferentes fases del programa de bombeo se resumen en la tabla siguiente y el programa correspondiente se muestra en el fragmento de código.
| Fase | Función | Valor | Tarifa | Volumen | Dirección |
|---|---|---|---|---|---|
| 1 | RAT | - | 300 ml/h | 0,5 ml | Infusionar |
| 2 | LPS | - | - | - | - |
| 3 | INC | - | 20 ml/h | 0,5 ml | Infusionar |
| 4 | LOP | 5 | - | - | - |
| 5 | LPS | - | - | - | - |
| 6 | DEC | - | 20 ml/h | 0,5 ml | Infusionar |
| 7 | LOP | 10 | - | - | - |
| 8 | LPS | - | - | - | - |
| 9 | INC | - | 20 ml/h | 0,5 ml | Infusionar |
| 10 | LOP | 5 | - | - | - |
| 11 | JMP | 2 | - | - | - |
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
Biblioteca de Python personalizada para el control de la bomba de jeringa NE
En esta segunda parte, se presenta otra forma eficaz de controlar la bomba de jeringa NE-1000 mediante Python. Se ha desarrollado una biblioteca de Python personalizada que ofrece funciones fáciles de usar para configurar parámetros, ejecutar acciones y gestionar la comunicación.
A continuación, presentaremos la biblioteca personalizada que se utiliza para controlar la bomba de jeringa NE-1000 y explicaremos sus limitaciones. Analizaremos en profundidad tres ejemplos diferentes de programas de bombeo (los ejemplos 1, 2 y 3 que acabamos de presentar), mostrando cómo se pueden utilizar estas funciones para ejecutar secuencias de bombeo precisas.
'''
-----------------------------------------------------------------------
NE-1000 Syringe Pump Control Library Using RS232 Communication Protocol
-----------------------------------------------------------------------
'''
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
# 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
# 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
#-----------------------------------------------------------------------------------------#
# The three functions below (set_rate, set_volume and set_direction) are only defined to be used within the run_RATE_function defined afterwards
#-----------------------------------------------------------------------------------------#
# 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)
#-----------------------------------------------------------------------------------------#
# 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
# Calculate pumping duration based on rate and volume units:
if rate_units == "MH" and units == "ML":
pumping_duration = volume * 3600 / rate # mL/hr and mL
elif rate_units == "UH" and units == "UL":
pumping_duration = volume * 3600 / rate # µL/hr and µL
elif rate_units == "MH" and units == "UL":
pumping_duration = volume * 3.6 / rate # mL/hr and µL
elif rate_units == "UH" and units == "ML":
pumping_duration = volume * 3.6 * 10**6 / rate # µL/hr and mL
elif rate_units == "MM" and units == "ML":
pumping_duration = volume * 60 / rate # mL/min and mL
elif rate_units == "UM" and units == "UL":
pumping_duration = volume * 60 / rate # µL/min and µL
elif rate_units == "MM" and units == "UL":
pumping_duration = volume * 0.06 / rate # mL/min and µL
elif rate_units == "UM" and units == "ML":
pumping_duration = volume * 6 * 10**4 / rate # µL/min and mL
else:
raise ValueError("Unsupported units combination: rate_units={}, units={}".format(rate_units, units))
time.sleep(pumping_duration) # Delay to ensure the pump dispenses the required volume at the given pumping rate
self.stop_pump() # Stop the 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 #####
Esta biblioteca personalizada permite controlar la bomba de jeringa NE-1000. Establece la comunicación con la bomba a través de un puerto serie y permite a los usuarios configurar parámetros como el diámetro de la jeringa, la velocidad de bombeo, el volumen y la dirección. Los usuarios pueden iniciar acciones de la bomba, como ponerla en marcha, detenerla y reiniciarla. Además, se define una función «RATE» utilizando un conjunto de funciones ya definidas. A través de esta biblioteca, los usuarios pueden crear secuencias de bombeo precisas directamente desde su entorno Python, tal y como se demostrará en los tres ejemplos siguientes.
Ejemplo 1: Administración y extracción de líquidos
En este ejemplo, la bomba de jeringa NE-1000 administra un líquido a un caudal y un volumen determinados, hace una pausa de 10 segundos, extrae un volumen diferente a un caudal distinto y, a continuación, se detiene. ¡SÍ, tienes razón! Este ejemplo se ha presentado justo arriba y ilustra cómo la biblioteca permite ejecutar la misma secuencia de bombeo descrita anteriormente.
#--------------------------------------------------------------------------------------------#
# 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
Este fragmento de código en Python muestra cómo utilizar la biblioteca personalizada para controlar la bomba de jeringa NE-1000 con el fin de ejecutar una secuencia de bombeo específica. En primer lugar, la bomba se inicializa con el puerto COM especificado y, a continuación, se reinicia para garantizar que se utilicen los parámetros predeterminados. El diámetro de la jeringa se configura en consecuencia.
La secuencia de bombeo consta de tres pasos principales:
- La bomba administra 4,0 ml de líquido a un caudal de 500 ml/h.
- Tras una pausa de 10 segundos, la bomba extrae 2,0 ml de líquido a un caudal de 200 ml/h.
- Por fin, la bomba se ha detenido.
Cada paso de la secuencia se ejecuta mediante el método«run_RATE_function» de la clase«NewEraSyringePump», especificando la velocidad de bombeo, el volumen, las unidades y la dirección. Una vez finalizada la secuencia de bombeo, se elimina la instancia de la bomba y se cierra el puerto de comunicación serie.
Este código ofrece un ejemplo sencillo de cómo se puede utilizar la biblioteca personalizada para controlar la bomba de jeringa NE-1000 y ejecutar secuencias de bombeo precisas. A continuación se ofrecen dos ejemplos más.
Ejemplo 2: Dosificaciones repetidas con retroceso
Este programa de bombeo dosifica 2,0 ml de un líquido con un intervalo de pausa de 20 segundos entre cada dosificación (un total de 4 dosificaciones). Tras cada dosificación, se extrae un pequeño volumen de 0,25 ml para evitar goteos. Además, se emite un pitido 3 segundos antes de que finalice cada pausa para indicar que la siguiente dosificación está a punto de realizarse. A partir de la segunda dosificación, se añaden 0,25 ml al volumen dosificado para compensar el volumen aspirado de la dosificación anterior. El programa correspondiente se muestra en el fragmento de código que figura a continuación.
#--------------------------------------------------------------------------------------------#
# 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
Ejemplo 3: Aumento gradual del caudal
Este programa de bombeo aumenta y disminuye continuamente el caudal, pasando de un valor inicial de 300 ml/h a 400 ml/h en incrementos de 20 ml/h cada vez que se dispensa un volumen de 0,5 ml. Una vez alcanzado el caudal máximo, este se reduce en incrementos similares, tras cada dispensación de 0,5 ml, hasta llegar a 200 ml/h. Por último, el caudal vuelve a incrementarse hasta el valor inicial y el ciclo se repite. El programa correspondiente se muestra en el fragmento de código que figura a continuación.
#--------------------------------------------------------------------------------------------#
# 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:
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
Aunque la biblioteca personalizada de Python constituye una herramienta valiosa para controlar la bomba de jeringa NE-1000, es fundamental tener en cuenta la limitación inherente que supone el retraso en la comunicación v RS-232 . Este retraso se debe al proceso que sigue la bomba para recibir y ejecutar los comandos, lo que da lugar a un intervalo muy breve entre comandos consecutivos.
Este retraso, aunque sea mínimo, puede dar lugar a ligeras discrepancias en los volúmenes dispensados, lo cual resulta especialmente notable cuando se requieren cambios rápidos de caudal dentro de un programa de bombeo, ya que, durante dichos cambios, el funcionamiento de la bomba debe detenerse para enviar un nuevo caudal, tal y como se estipula en la documentación de la bomba. En ella se especifica que el nuevo caudal solo se almacena en la memoria no volátil si el programa de bombeo no está en funcionamiento 🚧. Esto puede, en algunos casos, interrumpir el flujo del fluido y afectar a la precisión del experimento.
A pesar de los intentos por mitigar este problema mediante una secuenciación estratégica de los comandos y retrasos temporales, el problema persiste, lo que afecta a la capacidad de la bomba para mantener un funcionamiento continuo y preciso, especialmente en experimentos microfluídicos en los que el tiempo es un factor crítico. De cara al futuro, abordar este problema de retraso sigue siendo una prioridad para garantizar un rendimiento óptimo de la bomba y resultados experimentales precisos.
Conclusión
En esta entrada del blog, hemos analizado los conceptos básicos del control de comunicación « RS-232 » de la bomba de jeringa NE-1000 mediante Python, abarcando desde la configuración del puerto de comunicación hasta la programación de secuencias de bombeo personalizadas. Esperamos que esta entrada sirva de guía útil para los investigadores e ingenieros que deseen utilizar Python para controlar de forma remota sus bombas de jeringa New Era mediante el conjunto de comandos « RS-232 ».
¡Manténgase atento para más información, tutoriales y aplicaciones prácticas en nuestras futuras publicaciones! Hasta entonces, ¡feliz bombeo y programación 💻!
📧 Si tiene alguna pregunta o comentario, no dude en contactarnos en support@darwin-microfluidics.com.


