In einer Welt der Laborautomation, in der Präzision und Kontrolle an oberster Stelle stehen, dienen Spritzenpumpen als hervorragende Werkzeuge zur Abgabe präziser Flüssigkeitsvolumina mit hoher Genauigkeit und Reproduzierbarkeit. Unter diesen Pumpen zeichnet sich die NE-1000 Spritzenpumpe durch ihre robuste Leistung und Vielseitigkeit aus.
In diesem Blogbeitrag beleuchten wir die rs-232-Kommunikationssteuerung der NE-1000 Spritzenpumpe, untersuchen ihre Leistungsmerkmale und geben Einblicke in die Einrichtung der Kommunikation sowie die Anbindung an Python – mit Schritt-für-Schritt-Anleitungen zur Optimierung des Prozesses. Ganz gleich, ob Sie ein erfahrener Forscher oder ein Neuling im Bereich der Pumpensteuerung sind, dieser Blogbeitrag vermittelt Ihnen das Wissen und die Werkzeuge, um die Kontrolle über Ihre NE-1000 Pumpe zu übernehmen.
INHALTSVERZEICHNIS
Warum sollte man sich für die NE-1000 Spritzenpumpe entscheiden?
Die NE-1000 Spritzenpumpe von New Era Pump Systems wird für ihre Zuverlässigkeit und Flexibilität geschätzt. Sie bietet einen großen Bereich von Flussraten (von 0,73 μL/h bei einer 1-ml-Spritze bis hin zu 2120 mL/h bei einer 60-ml-Spritze) sowie eine präzise Volumendosierung, womit sie sich ideal für diverse Anwendungen wie Wirkstoffdosierungen und kalibrierte Injektionen eignet. Mit ihrem kompakten Design und der benutzerfreundlichen Oberfläche vereinfacht die NE-1000 experimentelle Aufbauten und gewährleistet gleichzeitig konsistente und präzise Ergebnisse.
Sie ist voll programmierbar – entweder eigenständig (standalone) oder über einen beliebigen Computer bzw. ein Gerät mit einer rs-232-Kommunikationsschnittstelle. Sie verfügt über einen integrierten Pumpennetzwerk-drive mit einem Pumpennetzwerk, das bis zu 100 Pumpen und andere Geräte unterstützt. Zudem zeichnet sie sich durch einen nichtflüchtigen Speicher für alle Betriebsparameter und das pumping program aus, was komplexe Pumpanwendungen und Interaktionen mit externen Geräten ermöglicht.
Was ist ein pumping program?
Ein pumping program bestimmt die Abfolge der von der Pumpe auszuführenden Aktionen, einschließlich der Festlegung von Flussraten, Volumina und Richtungen sowie der Durchführung von Pausen oder bedingten Anweisungen. Diese zuvor definierten Funktionsabläufe gewährleisten einen präzisen und automatischen Pumpenbetrieb, sowohl mit als auch ohne Benutzereingriff.
Ein pumping program kann direkt über die Tastatur der Pumpe eingegeben oder von einem Computer über eine dedizierte Software hochgeladen werden: PumpTerm, ein Pumpen-Terminal-Emulator, der die Kommunikation mit jeder Pumpe erleichtert, die über eine PC-Schnittstelle verfügt, indem Programme und Befehle aus einer Datei hochgeladen werden, oderSyringePumpPro, das als Steuerungssoftware für Pumpen dient und die automatische Überwachung aller Pumpenparameter ermöglicht.
Zusätzlich steht eine Tabellenkalkulation zur Erstellung von pumping programs zur Verfügung, die bei der Entwicklung von Pumpsequenzen sowie beim Erstellen und Organisieren derselben unterstützt. Diese können in einer Textdatei gespeichert und zur Ausführung auf die Pumpe geladen werden 📄.
Während PumpTerm und SyringePumpPro wertvolle Tools zur Steuerung von Spritzenpumpen sind, stellen sie nicht die einzigen verfügbaren Optionen dar. Man kann Programmierplattformen wie Python verwenden, das über robuste Bibliotheken für die serielle Kommunikation verfügt und so eine präzise Steuerung sowie Automatisierung der NE-1000 Pumpe ermöglicht.
Bevor wir näher darauf eingehen, wie Python für die präzise Steuerung der NE-1000 Spritzenpumpe genutzt werden kann, und dabei Beispiele sowie Einblicke in die Anwendung geben, werden wir den für die Kommunikation mit der NE-1000 verwendeten rs-232-Befehlssatz kurz im Detail erläutern. Wenn Sie bereits mit dem rs-232-Kommunikationsprotokoll vertraut sind, können Sie direkt zu den Python-Code-Snippets springen.
Was wird für die Kommunikation mit der NE-1000 Pumpe benötigt?
Um über Python mit der NE-1000 Spritzenpumpe zu kommunizieren, benötigen Sie einige wenige Hauptkomponenten:
- Eine NE-1000 Spritzenpumpe mit einer Spritze Ihrer Wahl,
- Ein RS-232-Kabel, das serielle Kommunikation ermöglicht und den Datentransfer zwischen der Spritzenpumpe und dem Computer unterstützt,
- Eine serielle Schnittstelle: Der Computer muss über einen verfügbaren seriellen Anschluss oder einen usb-zu-seruell-Adapter für den Anschluss des RS-232-Kabels verfügen,
- Eine Python-Umgebung mit dem PySerial-Paket, das den Zugriff auf die serielle Schnittstelle kapselt,
- Ein grundlegendes Verständnis des RS-232-Befehlssatzes, der im Benutzerhandbuch der Pumpe beschrieben ist.
Wie richtet man den Kommunikationsport ein?
Bevor Sie Befehle via Python an die NE-1000 Pumpe senden können, ist die Konfiguration des Kommunikationsanschlusses essenziell. Folgen Sie diesen Schritten, um eine Verbindung herzustellen 🔧:
- Schließen Sie das RS-232-Kabel an die serielle Schnittstelle an der Rückseite der NE-1000 Spritzenpumpe sowie an den entsprechenden Anschluss des Computers an.
- Schalten Sie die Pumpe ein.
- Stellen Sie sicher, dass die Einstellungen des seriellen Ports den Spezifikationen Ihrer Spritzenpumpe entsprechen:
- 1 Startbit
- 8 Datenbits
- Parität: keine
- 1 Stoppbit
- eine Baudrate von 19200 Baud
- Identifizieren Sie den Namen des seriellen Ports, der der Verbindung auf Ihrem Computer zugewiesen ist (z. B. COM4 unter Windows oder /dev/ttyUSB0 unter Linux). Diese Information finden Sie typischerweise im Geräte-Manager oder durch die Verwendung von Terminalbefehlen.
- Ein Dreiecksymbol (oben links auf dem Pumpenbildschirm) zeigt eine erfolgreiche Kommunikation an, die bis zum Ausschalten oder Aufrufen der „Setup Configuration“ bestehen bleibt.
- Testen Sie die Verbindung, indem Sie einen einfachen Befehl senden, beispielsweise das Abfragen des Pumpenstatus.
Was ist der RS-232-Befehlssatz?
Die Spritzenpumpe NE-1000 kommuniziert über rs-232 und speichert Datenänderungen in einem nichtflüchtigen Speicher, mit Ausnahme von Anpassungen der Förderrate während des Betriebs. Jede Programmphase umfasst Förderrate, zu dosierendes Volumen und Förderrichtung, die über den Befehl „PHN“ ausgewählt werden können.
Der zur Steuerung der NE-1000-Pumpe verwendete rs-232-Befehlssatz ist in der nachstehenden Tabelle zusammengefasst. Befehle ohne Parameter dienen als Abfragen, die die angeforderten Daten zurückgeben. Antworten spiegeln in der Regel die Befehlsparameter wider. Erfolgreiche Einstellbefehle lösen eine Statusantwort aus, während nicht erfolgreiche eine Fehlermeldung generieren.
| Befehl | Definition |
|---|---|
| DIA [Float] | Innendurchmesser der Spritze |
| PHN [Phasendaten] | Programmphasennummer |
| FUN [Phasenfunktion] | Programmphasenfunktion |
| RAT | Förderratenfunktion („RATE“) |
| RAT [Float | Rateneinheiten] | Förderrate |
| VOL [Float | Volumeneinheiten] | Zu dosierendes Volumen |
| DIR [INF \ WDR] | Förderrichtung |
| INC | Inkrementratenfunktion („INCR“) |
| DEC | Dekrementratenfunktion („DECR“) |
| JMP [Phasendaten] | Springe zur Programmphasenfunktion („JP:nn“) |
| LPS | Schleife starten, 'LP:ST' |
| LOP [Zähldaten] | Zurückspringen zum vorherigen Schleifenanfang 'nn'-mal, 'LP:nn' |
| LPE | Schleife beenden, 'LP:EN' |
| PAS [Nummerndaten] | Pumprozess für 'nn' Sekunden pausieren, 'PS:nn' |
| BEP | Kurzen Piepton ausgeben, 'BEEP' |
| CLD [INF \ WDR] | Abgegebenes Volumen zurücksetzen |
| RESET | Pumpe zurücksetzen und Programmspeicher löschen |
| RUN | Das Pumpprogramm starten |
| STP | Pumpe anhalten, 'STOP' |
Die Rateneinheiten sind ‚UM‘ für µL/min, ‚MM‘ für mL/min, ‚UH‘ für µL/h und ‚MH‘ für mL/h. Die Volumeneinheiten sind ‚UL‘ für µL und ‚ML‘ für mL. Diese werden entsprechend der aktuellen Spritzendurchmessereinstellung festgelegt.
Beim Senden des Befehls ‚RUN‘ an die Pumpe wird das Pumpprogramm an dem Punkt fortgesetzt, an dem es angehalten wurde, falls es pausiert war. Andernfalls startet das Pumpprogramm bei Phase 1. Bei der Ausführung des Befehls ‚RUN #‘ beginnt das Programm ab der angegebenen Phase (# steht für die Phasen-‚PHN‘-Nummer).
Wenn der Befehl ‚STP‘ an die Pumpe gesendet wird und das Pumpprogramm läuft, wird dieses pausiert und die Pumpe angehalten. Wenn das Pumpprogramm bereits pausiert ist, bricht der Befehl ‚STP‘ die Pause ab und setzt das Pumpprogramm auf Phase 1 zurück. Weitere Einzelheiten zum RS-232-Befehlssatz finden Sie in der Dokumentation der NE-1000 Spritzenpumpe.
Sobald der Kommunikationsport konfiguriert ist und Sie über ein grundlegendes Verständnis des RS-232-Befehlssatzes verfügen, sind Sie bereit, Python-Skripte zur Steuerung der NE-1000 Spritzenpumpe zu entwickeln 🕹️.
💡 Erweiterte Funktionen für die Standard-Firmware des NE-1000:
- Das Firmware-Upgrade für erweiterte X-Funktionen mit linearer/gradientenförmiger Rampe für gleichmäßige Gradienten und zusätzliche Programmierfunktionen.
- Das X2 Firmware-Upgrade für erweiterte Funktionen und Speichererweiterung, das alle Features der X-Firmware-Version enthält sowie eine Vergrößerung des Pumpprogrammspeichers von 41 auf 340 Phasen bietet.
Programmierung der NE-1000 Spritzenpumpe mit Python?
Im Folgenden werden Python-Codeausschnitte vorgestellt, die zeigen, wie man die serielle Schnittstelle öffnet, Steuerbefehlsketten an die Pumpe schreibt und sendet sowie ein Pumpenprogramm für die NE-1000 erstellt.
Wir gehen Codeausschnitte durch, die demonstrieren, wie gängige Aufgaben wie das Fördern von Flüssigkeiten, das Einstellen von Förderraten und das Ausführen komplexer Pumpsequenzen durchgeführt werden. Diese Beispiele vermitteln ein praxisnahes Verständnis der Python-basierten Steuerung der NE-1000 Spritzenpumpe.
Replikation der Funktionalität von SyringePumpPro und PumpTerm
Im ersten Teil werden wir Python nutzen, um die Funktionalität von SyringePumpPro und PumpTerm nachzubilden: das Hochladen eines Pumpenprogramms von einem Computer (oder das direkte Schreiben auf die Pumpe). Dieser Unterabschnitt erläutert, wie ein Python-Skript die Funktionen dieser Software-Tools effektiv emuliert und so die Steuerung und Automatisierung der NE-1000 Spritzenpumpe ermöglicht.
Wir verwenden die Python-Bibliothek „serial“, um die Kommunikation mit der NE-1000 Spritzenpumpe über eine serielle Verbindung aufzubauen. Zuerst importieren wir das Modul „serial“, das Werkzeuge für die serielle Kommunikation bereitstellt. Anschließend wird die Funktion „serial.Serial“ verwendet, um die serielle Verbindung zu initialisieren, wobei Parameter wie der Port-Name („COM2“), die Baudrate (19200) und Kommunikationseinstellungen wie Parität, Bytelänge und Stoppbits angegeben werden.
Die Python-Codeausschnitte werden nachfolgend dargestellt und erläutert👇.
Hochladen einer PPL-Datei von einem Computer auf die Pumpe
'''
------------------------------------------------
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()
Die Funktion „send_command“ ist definiert, um den Prozess des Sendens von Befehlen an die Pumpe zu optimieren (mit der Option, auch deren Antwort zu lesen). Innerhalb dieser Funktion werden Befehle als codierte Strings an die Pumpe gesendet, gefolgt von einer kurzen Verzögerung mittels „time.sleep()“, damit die Pumpe Zeit hat, den Befehl zu verarbeiten.
Zusätzlich ist eine Funktion „read_ppl_file“ enthalten, um den Inhalt einer PPL-Datei (Pump Programming Language) zu lesen, die Befehlssequenzen enthält, die von der Pumpe ausgeführt werden sollen. Der Dateipfad zur PPL-Datei wird angegeben, und ihr Inhalt wird über die Funktion „read_ppl_file“ eingelesen.
Die Pumpe wird mit dem Befehl „RESET“ zurückgesetzt, um einen sauberen Start vor der Ausführung der in der PPL-Datei enthaltenen Befehlssequenz zu gewährleisten. Der PPL-Inhalt wird in Zeilen aufgeteilt, und jede Zeile wird als Befehl mit der Funktion „send_command“ an die Pumpe gesendet. Schließlich wird der Befehl „RUN“ gesendet, um den Pumpvorgang zu starten.
Sobald alle Befehle ausgeführt wurden, kann die serielle Verbindung mit „ser.close()“ geschlossen werden, um eine ordnungsgemäße Freigabe der Ressourcen zu gewährleisten.
Schreiben eines Pumpenprogramms auf die Pumpe
Der vorherige Code demonstriert einen optimierten Ansatz zur Steuerung der NE-1000 Spritzenpumpe mit Python. Man hat jedoch möglicherweise keinen Zugriff auf die Tabellenkalkulation des Pumpenprogramm-Generators oder zieht es einfach vor, das Pumpenprogramm direkt im Python-Skript zu schreiben, um direkte und visuelle Änderungen am Programm vorzunehmen, bevor es an die Pumpe gesendet wird. Dieser Ansatz bietet eine größere Flexibilität und Unmittelbarkeit bei der Programmierung der Pumpenaktionen. Der folgende Codeausschnitt veranschaulicht diese Methode und ermöglicht es Benutzern, das Pumpenprogramm direkt im Python-Skript zu definieren, was Anpassungen von Parametern und Sequenzen in Echtzeit ermöglicht.
'''
-------------------------------------
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()
Hier definieren wir ein Pumping_Program direkt im Python-Skript. Das Programm (das in den Beispielen für Pumpenprogramme weiter unten 👇 näher erläutert wird) enthält eine Sequenz von Befehlen, die in einzelne Zeilen unterteilt sind. Jede Zeile wird als Befehl mit der Funktion „send_command“ an die Pumpe gesendet.
Nachdem das gesamte Pumpenprogramm an die Pumpe gesendet wurde, wird der Befehl „RUN“ ausgegeben, um den Pumpvorgang zu starten.
Beispiele für Pumpenprogramme
Unten finden Sie drei Beispiele für Pumpenprogramme, die für die NE-1000 Spritzenpumpe entworfen und auf spezifische experimentelle Anforderungen zugeschnitten sind.
Beispiel 1: Dosieren und Entnehmen von Flüssigkeiten
In diesem Beispiel dosiert die NE-1000 Spritzenpumpe eine Flüssigkeit mit einer bestimmten Rate und einem bestimmten Volumen, pausiert für 10 Sekunden, entzieht ein anderes Volumen mit einer anderen Rate und stoppt dann. Die verschiedenen Phasen des Pumpenprogramms sind in der folgenden Tabelle zusammengefasst und das entsprechende Programm ist im Codeausschnitt dargestellt.
| Phase | Funktion | Wert | Rate | Volumen | Richtung |
|---|---|---|---|---|---|
| 1 | RAT | - | 500 mL/h | 2,0 mL | Infiltrieren |
| 2 | PAS | 10 | - | - | - |
| 3 | RAT | - | 200 mL/h | 1,0 mL | Rückzug |
| 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
Beispiel 2: Wiederholte Dosierungen mit Rückzug
Dieses Pumpenprogramm dosiert 2,0 mL einer Flüssigkeit mit einer Pause von 20 Sekunden zwischen den Dosierungen (insgesamt 4 Dosierungen). Nach jeder Dosierung wird ein kleines Volumen von 0,25 mL zurückgezogen, um ein Tropfen zu verhindern. Zusätzlich ertönt 3 Sekunden vor dem Ende jeder Pause ein Signalton, um die bevorstehende Dosierung anzukündigen. Ab der zweiten Dosierung werden dem dosierten Volumen 0,25 mL hinzugefügt, um das zurückgezogene Volumen der vorherigen Dosierung zu kompensieren.
Die verschiedenen Phasen des Pumpenprogramms sind in der folgenden Tabelle zusammengefasst, und das dazugehörige Programm ist im Code-Snippet dargestellt.
| Phase | Funktion | Wert | Rate | Volumen | Richtung |
|---|---|---|---|---|---|
| 1 | RAT | - | 500 mL/h | 2,0 mL | Infiltrieren |
| 2 | RAT | - | 500 mL/h | 0,25 mL | Rückzug |
| 3 | LPS | - | - | - | - |
| 4 | PAS | 17 | - | - | - |
| 5 | BEP | - | - | - | - |
| 6 | PAS | 3 | - | - | - |
| 7 | RAT | - | 500 mL/h | 2,25 mL | Infiltrieren |
| 8 | RAT | - | 500 mL/h | 0,25 mL | Rückzug |
| 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
Beispiel 3: Rampensteuerung der Flussrate
Dieses Pumpenprogramm erhöht und senkt die Pumpenrate kontinuierlich, indem es nach der Dosierung eines Volumens von 0,5 mL ausgehend von einem Anfangswert von 300 mL/h in Schritten von 20 mL/h auf 400 mL/h ansteigt. Nach Erreichen der Maximalrate wird die Pumpenrate nach jeweils 0,5 mL dosiertem Volumen in ähnlichen Schritten bis auf 200 mL/h reduziert. Schließlich wird die Rate wieder auf den Anfangswert erhöht und der Zyklus wiederholt sich.
Die verschiedenen Phasen des Pumpenprogramms sind in der folgenden Tabelle zusammengefasst, und das dazugehörige Programm ist im Code-Snippet dargestellt.
| Phase | Funktion | Wert | Rate | Volumen | Richtung |
|---|---|---|---|---|---|
| 1 | RAT | - | 300 mL/h | 0,5 mL | Infiltrieren |
| 2 | LPS | - | - | - | - |
| 3 | INC | - | 20 mL/h | 0,5 mL | Infiltrieren |
| 4 | LOP | 5 | - | - | - |
| 5 | LPS | - | - | - | - |
| 6 | DEC | - | 20 mL/h | 0,5 mL | Infiltrieren |
| 7 | LOP | 10 | - | - | - |
| 8 | LPS | - | - | - | - |
| 9 | INC | - | 20 mL/h | 0,5 mL | Infiltrieren |
| 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
Benutzerdefinierte Python-Bibliothek zur Steuerung der NE-Spritzenpumpe
In diesem zweiten Teil wird ein weiterer effektiver Weg zur Steuerung der NE-1000 Spritzenpumpe über Python vorgestellt. Es wird eine benutzerdefinierte Python-Bibliothek entwickelt, die benutzerfreundliche Funktionen zur Parametrisierung, Aktionsausführung und Kommunikationsverwaltung bereitstellt.
Im Folgenden stellen wir die benutzerdefinierte Bibliothek zur Steuerung der NE-1000 Spritzenpumpe vor und erläutern deren Einschränkungen. Wir gehen auf drei verschiedene Beispiele für Pumpenprogramme ein (die zuvor präsentierten Beispiele 1, 2 und 3) und demonstrieren, wie diese Funktionen zur Ausführung präziser Pumpsequenzen genutzt werden können.
'''
-----------------------------------------------------------------------
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 #####
Diese benutzerdefinierte Bibliothek ermöglicht die Steuerung der NE-1000 Spritzenpumpe. Sie stellt die Kommunikation mit der Pumpe über einen seriellen Port her und versetzt Benutzer in die Lage, Parameter wie Spritzendurchmesser, Flussrate, Volumen und Richtung einzustellen. Benutzer können Pumpenaktionen wie Starten, Stoppen und Zurücksetzen initiieren. Darüber hinaus wird eine „RATE“-Funktion mithilfe einer Reihe bereits definierter Funktionen definiert. Über diese Bibliothek können Benutzer präzise Pumpsequenzen direkt aus ihrer Python-Umgebung erstellen, wie in den drei folgenden Beispielen demonstriert wird.
Beispiel 1: Dosieren und Entnehmen von Flüssigkeiten
In diesem Beispiel infundiert die NE-1000 Spritzenpumpe eine Flüssigkeit mit einer bestimmten Rate und einem bestimmten Volumen, pausiert für 10 Sekunden, zieht ein anderes Volumen mit einer anderen Rate zurück und stoppt dann. JA, Sie haben richtig gelesen! Dieses Beispiel wurde soeben vorgestellt und veranschaulicht, wie die Bibliothek die Ausführung derselben zuvor beschriebenen Pumpsequenz ermöglicht.
#--------------------------------------------------------------------------------------------#
# 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
Dieses Python-Code-Snippet demonstriert die Verwendung der benutzerdefinierten Bibliothek zur Steuerung der NE-1000 Spritzenpumpe für die Ausführung einer spezifischen Pumpsequenz. Zunächst wird die Pumpe mit dem angegebenen COM-Port initialisiert und dann zurückgesetzt, um die Standardparameter sicherzustellen. Der Spritzendurchmesser wird entsprechend eingestellt.
Die Pumpsequenz besteht aus drei Hauptschritten:
- Die Pumpe infundiert 4,0 mL Flüssigkeit mit einer Rate von 500 mL/h.
- Nach einer 10-sekündigen Pause zieht die Pumpe 2,0 mL Flüssigkeit mit einer Rate von 200 mL/h zurück.
- Schließlich wird die Pumpe gestoppt.
Jeder Schritt der Sequenz wird über die Methode „run_RATE_function“ der Klasse „NewEraSyringePump“ ausgeführt, wobei Förderrate, Volumen, Einheiten und Richtung angegeben werden. Nach Abschluss der Fördersequenz wird die Pumpeninstanz gelöscht und der serielle Kommunikationsport geschlossen.
Dieser Code bietet ein unkompliziertes Beispiel dafür, wie die benutzerdefinierte Bibliothek zur Steuerung der NE-1000 Spritzenpumpe und zur Ausführung präziser Fördersequenzen verwendet werden kann. Zwei weitere Beispiele sind unten aufgeführt.
Beispiel 2: Wiederholte Dosierungen mit Rückzug
Dieses Förderprogramm dosiert 2,0 ml einer Flüssigkeit mit einer Pause von 20 Sekunden zwischen den Dosierungen (insgesamt 4 Dosierungen). Nach jeder Dosierung wird ein kleines Volumen von 0,25 ml zurückgezogen, um ein Tropfen zu verhindern. Zusätzlich ertönt 3 Sekunden vor Ende jeder Pause ein Piepton, um die bevorstehende Dosierung zu signalisieren. Ab der zweiten Dosierung werden dem dosierten Volumen 0,25 ml hinzugefügt, um das zurückgesaugte Volumen der vorherigen Dosierung zu kompensieren. Das entsprechende Programm ist im folgenden Code-Snippet dargestellt.
#--------------------------------------------------------------------------------------------#
# 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
Beispiel 3: Rampensteuerung der Flussrate
Dieses Förderprogramm erhöht und verringert die Förderrate kontinuierlich, indem es ausgehend von einem Anfangswert von 300 ml/h in Schritten von 20 ml/h ansteigt, jeweils nachdem ein Volumen von 0,5 ml dosiert wurde. Nach Erreichen der maximalen Rate verringert sich die Förderrate in ähnlichen Schritten nach jeder Dosierung von 0,5 ml, bis 200 ml/h erreicht sind. Schließlich wird die Rate wieder auf den Ausgangswert erhöht und der Zyklus wiederholt sich. Das entsprechende Programm ist im folgenden Code-Snippet dargestellt.
#--------------------------------------------------------------------------------------------#
# 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
Obwohl die benutzerdefinierte Python-Bibliothek ein wertvolles Werkzeug zur Steuerung der NE-1000 Spritzenpumpe darstellt, ist es wichtig, die inhärente Einschränkung durch die Zeitverzögerung in der RS-232-Kommunikation zu berücksichtigen. Diese beobachtete Verzögerung resultiert aus dem Prozess des Empfangens und Ausführens von Befehlen durch die Pumpe, was zu einer sehr kurzen Llücke zwischen aufeinanderfolgenden Befehlen führt.
Diese Verzögerung kann, obwohl gering, zu leichten Abweichungen der dosierten Volumina führen. Dies macht sich besonders bemerkbar, wenn schnelle Äderungen der Förderrate innerhalb eines Förderprogramms erforderlich sind, da laut der Pumpendokumentation der Pumpbetrieb gestoppt werden muss, um eine neue Rate zu senden. Sie besagt, dass die neue Rate nur dann im nichtflüchtigen Speicher gespeichert wird, wenn das Förderprogramm nicht läuft 🚧. Dies kann in einigen Fällen den Fluidstrom stören und die Genauigkeit des Experiments beeinträchtigen.
Trotz Versuchen, dieses Problem durch strategische Befehlssequenzierung und Zeitverzögerungen zu mindern, bleibt die Herausforderung bestehen. Sie beeinflusst die Fähigkeit der Pumpe, einen kontinuierlichen und präzisen Pumpbetrieb aufrechtzuerhalten, insbesondere bei zeitkritischen mikrofluidischen Experimenten. Auch in Zukunft bleibt die Behebung dieses Verzögerungsproblems eine Priorität, um eine optimale Pumpenleistung und genaue experimentelle Ergebnisse sicherzustellen.
Fazit
In diesem Blogbeitrag haben wir die Grundlagen der RS-232-Kommunikationssteuerung der NE-1000 Spritzenpumpe mittels Python untersucht und dabei alles von der Konfiguration des Kommunikationsports bis zur Programmierung benutzerdefinierter Fördersequenzen abgedeckt. Wir hoffen, dass dieser Beitrag Forschenden und Ingenieurinnen sowie Ingenieuren als wertvoller Leitfaden dient, die Python nutzen möchten, um ihre New Era Spritzenpumpen über den RS-232-Befehlssatz fernzusteuern.
Bleiben Sie dran für weitere Einblicke, Tutorials und praktische Anwendungen in unseren zukünftigen Beiträgen. Bis dahin viel Erfolg beim Pumpen und Programmieren 💻!
📧 Bei Fragen oder Anmerkungen können Sie uns gerne kontaktieren unter support@darwin-microfluidics.com.


