In un mondo in cui l'automazione di laboratorio è fondamentale e la precisione e il controllo sono di primaria importanza, le pompe a siringa rappresentano strumenti eccellenti per erogare volumi precisi di liquido con accuratezza e riproducibilità. Tra queste pompe, lapompa a siringa NE-1000si distingueper le sue prestazioni affidabili e la sua versatilità.
In questo articolo del blog illustriamo in dettaglio il controllo della comunicazione tramiteRS-232 della pompa a siringa NE-1000, ne analizziamo le funzionalità e forniamo indicazioni sulla configurazione della comunicazione e sull’interfacciamento con Python, con istruzioni passo passo per semplificare il processo. Che tu sia un ricercatore esperto o un principiante nel controllo delle pompe, questo articolo ti fornirà le conoscenze e gli strumenti necessari per gestire la tua pompa NE-1000.
SOMMARIO
Perché scegliere la pompa a siringa NE-1000?
La pompa a siringa NE-1000di New Era Pump Systems è apprezzata per la sua affidabilità e flessibilità. Offre un'ampia gamma di portate (da 0,73 μL/ora con una siringa da 1 mL a 2120 mL/ora con una siringa da 60 mL) e un'erogazione volumetrica precisa, rendendola ideale per varie applicazioni quali il dosaggio di farmaci e le iniezioni calibrate. Grazie al suo design compatto e all’interfaccia intuitiva, la NE-1000 semplifica l’allestimento degli esperimenti garantendo al contempo risultati costanti e accurati.
È completamente programmabile in modalità autonoma o tramite qualsiasi computer o dispositivo dotato di una porta di comunicazione RS-232 . Dispone di un driver di rete per pompe integrato, con una rete in grado di supportare fino a 100 pompe e altri dispositivi. Si contraddistingue inoltre per la memoria non volatile di tutti i parametri operativi e del programma di pompaggio, che consente applicazioni di pompaggio complesse e interazioni con dispositivi esterni.
Che cos’è un programma di pompaggio?
Un programma di pompaggio determina la sequenza delle azioni eseguite dalla pompa, compresa l'impostazione delle portate, dei volumi e delle direzioni di pompaggio, nonché l'esecuzione di pause o istruzioni condizionali. Queste sequenze di funzioni predefinite garantiscono un funzionamento preciso e automatico della pompa, con o senza l'intervento dell'utente.
È possibile inserire un programma di pompaggio direttamente dalla tastiera della pompa oppure caricarlo da un computer utilizzando un software dedicato: PumpTerm,un emulatore di terminale per pompe che facilita la comunicazione con qualsiasi pompa dotata di interfaccia PC, consentendo di caricare programmi e comandi da un file, oppureSyringePumpPro,che funge da software di controllo per le pompe e permette il monitoraggio automatico di tutti i parametri della pompa.
Inoltre, è disponibile un foglio di calcolo per la generazione di programmi di pompaggio, pensato per facilitare lo sviluppo di tali programmi e la creazione e l'organizzazione delle sequenze di pompaggio, che possono essere salvate in un file di testo e caricate sulla pompa per l'esecuzione📄.
Sebbene PumpTerm e SyringePumpPro siano strumenti preziosi per il controllo delle pompe a siringa, non sono le uniche opzioni disponibili. È possibile utilizzare piattaforme di programmazione come Python, che dispone di librerie affidabili per la comunicazione seriale, consentendo un controllo preciso e l’automazione della pompa NE-1000.
Prima di approfondire come Python possa essere utilizzato per il controllo preciso della pompa a siringa NE-1000, fornendo esempi e approfondimenti sulla sua applicazione, illustreremo brevemente il set di comandi RS-232 utilizzato per comunicare con la NE-1000. Se avete già familiarità con il protocollo di comunicazione RS-232 , potete passare direttamente ai frammenti di codice Python.
Cosa serve per comunicare con la pompa NE-1000?
Per comunicare con la pompa a siringa NE-1000 utilizzando Python, sono necessari alcuni componenti fondamentali:
- Una pompa a siringa NE-1000 con una siringa a scelta,
- Un cavoRS-232 che consente la comunicazione seriale e permette il trasferimento dei dati tra la pompa a siringa e il computer,
- Una porta seriale: il computer deve disporre di una porta seriale libera o di un adattatore da " USB" a seriale per il collegamento al cavo " RS-232 ",
- Un ambiente Python con il pacchetto PySerial che incapsula l'accesso alla porta seriale,
- Una conoscenza di base del set di comandi “RS-232 ”, descritto in dettaglio nel manuale d’uso della pompa.
Come configurare la porta di comunicazione?
Prima di poter iniziare a inviare comandi alla pompa NE-1000 tramite Python, è fondamentale configurare la porta di comunicazione. Segui questi passaggi per stabilire una connessione🔧:
- Collegare il cavo “ RS-232 ” alla porta seriale situata sul retro della pompa a siringa NE-1000 e alla porta corrispondente sul computer.
- Accendere la pompa.
- Assicurarsi che le impostazioni della porta seriale corrispondano alle specifiche della siringa pompa:
- 1 bit di start
- 8 bit di dati
- Parità: nessuna
- 1 bit di stop
- una velocità di trasmissione di 19.200 bit/s
- Identificare il nome della porta seriale assegnato alla connessione sul computer (ad esempio, COM4 per Windows o /dev/ttyUSB0 per Linux). In genere è possibile trovare queste informazioni in gestione dispositivi o utilizzando i comandi del terminale.
- Un'icona a forma di triangolo (in alto a sinistra nella schermata della pompa) indica che la comunicazione è avvenuta con successo e rimane visibile fino allo spegnimento o all'accesso alla sezione “Configurazione”.
- Testare la connessione inviando un comando semplice, come l'interrogazione dello stato della pompa.
Che cos’è il set di comandi “ RS-232 ”?
La pompa a siringa NE-1000 comunica tramite un RS-232 e che memorizza le modifiche dei dati in una memoria non volatile, ad eccezione delle regolazioni della portata durante il funzionamento. Ogni fase del programma comprende la portata, il volume da erogare e la direzione di pompaggio, selezionabili tramite il comando “PHN”.
Il set di comandi “ RS-232 ” utilizzato per controllare la pompa NE-1000 è riassunto nella tabella sottostante. I comandisenza parametri fungono da richieste che restituiscono i dati richiesti. Le risposte rispecchiano in genere i parametri del comando. I comandi di impostazione riusciti generano una risposta di stato, mentre quelli non riusciti generano un messaggio di errore.
| Comando | Definizione |
|---|---|
| DIA [float] | Diametro interno della siringa |
| PHN [dati di fase] | Numero della fase del programma |
| FUN [funzione di fase] | Funzione della fase del programma |
| RAT | Funzione "RATE" di pompaggio |
| RAT [valore in virgola mobile | unità di misura del tasso] | Portata |
| VOL [float | unità di volume] | Volume da erogare |
| DIR [INF \ WDR] | Direzione di pompaggio |
| INC | Funzione di incremento, 'INCR' |
| DEC | Funzione del tasso di decremento, "DECR" |
| JMP [dati di fase] | Vai alla funzione di fase del programma, "JP:nn" |
| LPS | Avvia ciclo, 'LP:ST' |
| LOP [dati numerici] | Ripeti il ciclo precedente 'nn' volte, 'LP:nn' |
| LPE | Fine ciclo, 'LP:EN' |
| PAS [dati numerici] | Sospendi il pompaggio per 'nn' secondi, 'PS:nn' |
| BEP | Breve segnale acustico, "BEEP" |
| CLD [INF \ WDR] | Volume netto erogato |
| RESET | Ripristina la pompa e cancella la memoria del programma |
| CORRI | Avvia il programma di pompaggio |
| STP | Arresta la pompa, "STOP" |
Le unità di misura della portata sono “UM” per µL/min, “MM” per mL/min, “UH” per µL/ora e “MH” per mL/ora. Le unità di misura del volume sono “UL” per µL e “ML” per mL. Queste vengono impostate in base al diametro della siringa attualmente selezionato.
Quando si invia il comando “RUN” alla pompa, il programma di pompaggio riprende dal punto in cui era stato interrotto, nel caso in cui fosse stato messo in pausa. In caso contrario, il programma di pompaggio parte dalla Fase 1. Durante l’esecuzione del comando “RUN #”, il programma parte dalla fase specificata (# corrisponde al numero della fase “PHN”).
Quando viene inviato il comando “STP” alla pompa, se il programma di pompaggio è in esecuzione, quest’ultimo verrà messo in pausa e la pompa verrà arrestata. Se il programma di pompaggio è già in pausa, il comando “STP” annullerà la pausa e ripristinerà il programma di pompaggio alla Fase 1.Per ulteriori dettagli sulla serie di comandi “ RS-232 ”, si prega di consultare la documentazionedella pompa a siringa NE-1000 .
Una volta configurata la porta di comunicazione e acquisita una conoscenza di base del set di comandi “ RS-232 ”, sei pronto per iniziare a sviluppare script in Python per controllare la pompa a siringa NE-1000🕹️.
💡 Funzionalità aggiornate al firmware standard del NE-1000:
- L'aggiornamento alle funzionalità avanzate del firmware X con rampa lineare/a gradiente per sfumature uniformi e funzioni di programmazione aggiuntive.
- Il firmware X2 con funzionalità avanzate e potenziamento della memoria, che include tutte le funzionalità della versione X del firmware con un aumento della memoria dei programmi di pompaggio da 41 a 340 fasi.
Come programmare la pompa a siringa NE-1000 utilizzando Python?
Di seguito verranno presentati alcuni frammenti di codice Python che illustrano come aprire la porta seriale, scrivere e inviare stringhe di comandi di controllo alla pompa e scrivere un programma di pompaggio sul NE-1000.
Esamineremo alcuni frammenti di codice che illustrano come eseguire operazioni comuni quali l’infusione di liquidi, l’impostazione delle velocità di pompaggio e l’esecuzione di sequenze di pompaggio complesse. Questi esempi consentiranno di acquisire una comprensione pratica del controllo basato su Python della pompa a siringa NE-1000.
Replica delle funzionalità di SyringePumpPro e PumpTerm
In questa prima parte utilizzeremo Python per riprodurre le funzionalità offerte da SyringePumpPro e PumpTerm: il caricamento di un programma di pompaggio da un computer (o la sua scrittura diretta sulla pompa). Questa sottosezione illustrerà come uno script Python riesca a emulare efficacemente le funzionalità di questi strumenti software, consentendo il controllo e l’automazione della pompa a siringa NE-1000.
Utilizzeremo la libreria“serial”di Python per stabilire la comunicazione con la pompa a siringa NE-1000 tramite una connessione alla porta seriale. Innanzitutto, importiamo il modulo“serial”, che fornisce gli strumenti per la comunicazione seriale. La funzione“serial.Serial”viene quindi utilizzata per inizializzare la connessione alla porta seriale, specificando parametri quali il nome della porta (“COM2”), la velocità di trasmissione (19200) e le impostazioni di comunicazione quali parità, dimensione dei byte e bit di stop.
Di seguito sono riportati e descritti in dettaglio i frammenti di codice Python👇.
Trasferimento di un file PPL dal computer alla pompa
'''
------------------------------------------------
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 funzione“send_command”è stata definita per semplificare il processo di invio dei comandi alla pompa (con la possibilità di leggere anche la sua risposta). All’interno di questa funzione, i comandi vengono inviati alla pompa sotto forma di stringhe codificate, seguite da un breve ritardo ottenuto tramite“time.sleep()” per consentire alla pompa di elaborare il comando.
Inoltre, è inclusa una funzione“read_ppl_file”che consente di leggere il contenuto di un file PPL (Pump Programming Language), contenente sequenze di comandi che devono essere eseguiti dalla pompa. Si specifica il percorso del file PPL e il suo contenuto viene letto tramite la funzione“read_ppl_file”.
La pompa viene ripristinata tramite il comando“RESET”, garantendo così un avvio corretto prima dell’esecuzione della sequenza di comandi contenuta nel file PPL. Il contenuto del file PPL viene suddiviso in righe e ciascuna riga viene inviata come comando alla pompa tramite la funzione“send_command”.Infine, viene inviato il comando“RUN”per avviare il processo di pompaggio.
Una volta eseguiti tutti i comandi, è possibile chiudere la connessione alla porta seriale utilizzando“ser.close()”, garantendo così la corretta liberazione delle risorse.
Scrittura di un programma di pompaggio sulla pompa
Il codice precedente illustra un approccio semplificato al controllo della pompa a siringa NE-1000 tramite Python. Tuttavia, è possibile che non si abbia accesso al foglio di calcolo per la generazione del programma di pompaggio oppure che si preferisca semplicemente scrivere il programma direttamente nello script Python, in modo da poter apportare modifiche immediate e visive al programma prima di inviarlo alla pompa. Questo approccio offre maggiore flessibilità e immediatezza nella programmazione delle azioni della pompa. Il seguente frammento di codice illustra questo metodo, consentendo agli utenti di definire il programma di pompaggio direttamente all’interno dello script Python e permettendo così di regolare in tempo reale i parametri e le sequenze.
'''
-------------------------------------
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()
In questa sede definiamo un programma di pompaggio direttamente all’interno dello script Python. Il programma (descritto in dettaglio negli Esempi di programmi di pompaggio riportati di seguito 👇) contiene una sequenza di comandi, organizzati in singole righe. Ogni riga viene inviata come comando alla pompa tramite la funzione“send_command”.
Dopo aver inviato l'intero programma di pompaggio alla pompa, viene impartito il comando“RUN”per avviare il processo di pompaggio.
Esempi di programmi di pompaggio
Di seguito sono riportati tre esempi di programmi di pompaggio progettati per la pompa a siringa NE-1000, ciascuno adattato a specifiche esigenze sperimentali.
Esempio 1: Somministrazione e prelievo di liquidi
In questo esempio, la pompa a siringa NE-1000 eroga un liquido a una portata e a un volume specificati, effettua una pausa di 10 secondi, preleva un volume diverso a una portata diversa e infine si arresta. Le diverse fasi del programma di pompaggio sono riassunte nella tabella sottostante, mentre il programma corrispondente è riportato nel frammento di codice.
| Fase | Funzione | Valore | Tasso | Volume | Direzione |
|---|---|---|---|---|---|
| 1 | RAT | - | 500 mL/ora | 2,0 mL | Infondere |
| 2 | PAS | 10 | - | - | - |
| 3 | RAT | - | 200 mL/ora | 1,0 mL | Ritiro |
| 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
Esempio 2: Erogazioni ripetute con aspirazione di ritorno
Questo programma di pompaggio eroga 2,0 mL di un liquido con un intervallo di pausa di 20 secondi tra un'erogazione e l'altra (per un totale di 4 erogazioni). Dopo ogni erogazione, viene aspirato un piccolo volume di 0,25 mL per evitare il gocciolamento. Inoltre, 3 secondi prima della fine di ogni pausa viene emesso un segnale acustico per segnalare l'imminente erogazione. A partire dalla seconda erogazione, al volume erogato vengono aggiunti 0,25 mL per compensare il volume risucchiato durante l’erogazione precedente.
Le diverse fasi del programma di pompaggio sono riassunte nella tabella sottostante, mentre il programma corrispondente è riportato nel frammento di codice.
| Fase | Funzione | Valore | Tasso | Volume | Direzione |
|---|---|---|---|---|---|
| 1 | RAT | - | 500 mL/ora | 2,0 mL | Infondere |
| 2 | RAT | - | 500 mL/ora | 0,25 mL | Ritiro |
| 3 | LPS | - | - | - | - |
| 4 | PAS | 17 | - | - | - |
| 5 | BEP | - | - | - | - |
| 6 | PAS | 3 | - | - | - |
| 7 | RAT | - | 500 mL/ora | 2,25 mL | Infondere |
| 8 | RAT | - | 500 mL/ora | 0,25 mL | Ritiro |
| 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
Esempio 3: Aumento graduale della portata
Questo programma di pompaggio aumenta e diminuisce continuamente la portata, passando da un valore iniziale di 300 mL/h a 400 mL/h con incrementi di 20 mL/h ogni volta che viene erogato un volume di 0,5 mL. Dopo aver raggiunto la portata massima, la portata di pompaggio diminuisce con incrementi simili, dopo ogni erogazione di 0,5 mL, fino a raggiungere i 200 mL/h. Infine, la portata viene riportata al valore iniziale e il ciclo si ripete.
Le diverse fasi del programma di pompaggio sono riassunte nella tabella sottostante, mentre il programma corrispondente è riportato nel frammento di codice.
| Fase | Funzione | Valore | Tasso | Volume | Direzione |
|---|---|---|---|---|---|
| 1 | RAT | - | 300 mL/ora | 0,5 mL | Infondere |
| 2 | LPS | - | - | - | - |
| 3 | INC | - | 20 mL/ora | 0,5 mL | Infondere |
| 4 | LOP | 5 | - | - | - |
| 5 | LPS | - | - | - | - |
| 6 | DEC | - | 20 mL/ora | 0,5 mL | Infondere |
| 7 | LOP | 10 | - | - | - |
| 8 | LPS | - | - | - | - |
| 9 | INC | - | 20 mL/ora | 0,5 mL | Infondere |
| 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
Libreria Python personalizzata per il controllo della pompa a siringa NE
In questa seconda parte viene presentato un altro metodo efficace per controllare la pompa a siringa NE-1000 tramite Python. È stata sviluppata una libreria Python personalizzata che offre funzioni di facile utilizzo per impostare i parametri, eseguire azioni e gestire la comunicazione.
Di seguito presenteremo la libreria personalizzata utilizzata per il controllo della pompa a siringa NE-1000 e ne illustreremo i limiti. Approfondiremo tre diversi esempi di programmi di pompaggio (gli Esempi 1, 2 e 3 appena presentati sopra), dimostrando come queste funzioni possano essere utilizzate per eseguire sequenze di pompaggio precise.
'''
-----------------------------------------------------------------------
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 #####
Questa libreria personalizzata consente di controllare la pompa a siringa NE-1000. Stabilisce la comunicazione con la pompa tramite una porta seriale e permette agli utenti di impostare parametri quali il diametro della siringa, la velocità di pompaggio, il volume e la direzione. Gli utenti possono avviare azioni relative alla pompa, quali l'avvio, l'arresto e il ripristino della pompa. Inoltre, è stata definita una funzione “RATE” che utilizza un insieme di funzioni già predefinite. Grazie a questa libreria, gli utenti possono creare sequenze di pompaggio precise direttamente dal proprio ambiente Python, come verrà illustrato nei tre esempi riportati di seguito.
Esempio 1: Somministrazione e prelievo di liquidi
In questo esempio, la pompa a siringa NE-1000 eroga un liquido a una portata e a un volume specificati, effettua una pausa di 10 secondi, preleva un volume diverso a una portata diversa e poi si arresta. SÌ, hai ragione! Questo esempio è stato presentato proprio poco sopra e illustra come la libreria consenta di eseguire la stessa sequenza di pompaggio descritta in precedenza.
#--------------------------------------------------------------------------------------------#
# 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
Questo frammento di codice Python illustra l'uso della libreria personalizzata per il controllo della pompa a siringa NE-1000 al fine di eseguire una specifica sequenza di pompaggio. Innanzitutto, la pompa viene inizializzata con la porta COM specificata, quindi viene resettata per ripristinare i parametri predefiniti. Il diametro della siringa viene impostato di conseguenza.
La sequenza di pompaggio si articola in tre fasi principali:
- La pompa eroga 4,0 mL di liquido a una portata di 500 mL/ora.
- Dopo una pausa di 10 secondi, la pompa aspira 2,0 mL di liquido a una portata di 200 mL/ora.
- Infine, la pompa viene arrestata.
Ogni fase della sequenza viene eseguita utilizzando il metodo "run_RATE_function" della classe "NewEraSyringePump", specificando la velocità di pompaggio, il volume, le unità di misura e la direzione. Una volta completata la sequenza di pompaggio, l'istanza della pompa viene eliminata e la porta di comunicazione seriale viene chiusa.
Questo codice fornisce un esempio semplice di come sia possibile utilizzare la libreria personalizzata per controllare la pompa a siringa NE-1000 ed eseguire sequenze di pompaggio precise. Di seguito sono riportati altri due esempi.
Esempio 2: Erogazioni ripetute con aspirazione di ritorno
Questo programma di pompaggio eroga 2,0 mL di un liquido con un intervallo di pausa di 20 secondi tra un'erogazione e l'altra (per un totale di 4 erogazioni). Dopo ogni erogazione, viene aspirato un piccolo volume di 0,25 mL per evitare che il liquido goccioli. Inoltre, 3 secondi prima della fine di ogni pausa viene emesso un segnale acustico per segnalare l'imminente erogazione. A partire dalla seconda erogazione, al volume erogato vengono aggiunti 0,25 mL per compensare il volume riassorbito durante l’erogazione precedente. Il programma corrispondente è riportato nel frammento di codice qui sotto.
#--------------------------------------------------------------------------------------------#
# 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
Esempio 3: Aumento graduale della portata
Questo programma di pompaggio aumenta e diminuisce continuamente la portata, passando da un valore iniziale di 300 mL/h a 400 mL/h con incrementi di 20 mL/h ogni volta che viene erogato un volume di 0,5 mL. Dopo aver raggiunto la portata massima, la portata di pompaggio diminuisce con incrementi simili, dopo ogni erogazione di 0,5 mL, fino a raggiungere i 200 mL/h. Infine, la portata viene riportata al valore iniziale e il ciclo si ripete. Il programma corrispondente è riportato nel frammento di codice qui sotto.
#--------------------------------------------------------------------------------------------#
# 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
Sebbene la libreria Python personalizzata rappresenti uno strumento prezioso per il controllo della pompa a siringa NE-1000, è fondamentale tenere conto del limite intrinseco rappresentato dal ritardo nella comunicazione v RS-232 e. Tale ritardo deriva dal processo di ricezione ed esecuzione dei comandi da parte della pompa, il che comporta un intervallo molto breve tra comandi consecutivi.
Questo ritardo, sebbene minimo, può causare lievi discrepanze nei volumi erogati, particolarmente evidenti quando sono richieste rapide variazioni di portata all’interno di un programma di pompaggio; infatti, durante tali variazioni, il funzionamento della pompa dovrebbe essere interrotto per inviare una nuova portata, come specificato nella documentazione della pompa. In essa si specifica che la nuova portata viene memorizzata nella memoria non volatile solo se il programma di pompaggio non è in funzione 🚧. Ciò può, in alcuni casi, interrompere il flusso del fluido e compromettere la precisione dell’esperimento.
Nonostante i tentativi di mitigare questo problema attraverso una sequenza strategica dei comandi e l’introduzione di ritardi temporali, la difficoltà persiste, influenzando la capacità della pompa di mantenere un funzionamento continuo e preciso, specialmente negli esperimenti microfluidici in cui il fattore tempo è determinante. In prospettiva, affrontare il problema dei ritardi rimane una priorità per garantire prestazioni ottimali della pompa e risultati sperimentali accurati.
Conclusione
In questo articolo del blog abbiamo approfondito le nozioni di base relative al controllo della comunicazione tramite il comando “ RS-232 ” della pompa a siringa NE-1000 utilizzando Python, trattando tutti gli aspetti, dalla configurazione della porta di comunicazione alla programmazione di sequenze di pompaggio personalizzate. Ci auguriamo che questo articolo possa rappresentare una guida utile per ricercatori e ingegneri che intendono utilizzare Python per controllare a distanza le loro pompe a siringa New Era tramite il set di comandi “ RS-232 ”.
Rimanete sintonizzati per ulteriori approfondimenti, tutorial e applicazioni pratiche nei nostri prossimi articoli. Fino ad allora, buon lavoro con il pompaggio e la programmazione 💻!
📧 Per qualsiasi domanda o riscontro, non esitate a contattarci all'indirizzo support@darwin-microfluidics.com.


