Les pompes péristaltiques jouent un rôle crucial dans la recherche microfluidique et le diagnostic médical, offrant un contrôle précis du fluide avec un risque minimal de contamination. Parmi les nombreuses options disponibles, les pompes Longer, fabriquées par Longer Precision Pump Co., Ltd., ont acquis une réputation pour leur fiabilité, leur précision et leur polyvalence.
L'une des caractéristiques remarquables des pompes péristaltiques Longer est leur capacité à être contrôlées à distance depuis un ordinateur, ce qui permet aux utilisateurs d'exécuter des programmes de pompage complexes impliquant des boucles, des pauses et des débits variables avec une flexibilité et une commodité accrues.
Dans cet article de blog, nous allons explorer le contrôle des pompes péristaltiques Longer à l'aide du protocole Modbus RTU, un protocole de communication série largement utilisé qui permet d'envoyer des commandes et de recevoir des réponses de la pompe. Bien que les spécificités du protocole Modbus puissent varier légèrement entre les différents modèles de pompes, pour cet article, nous utiliserons la pompe péristaltique Longer L100-1S-2 comme exemple de référence. Nous vous présenterons également des exemples Python et des extraits de code que vous pourrez copier directement et utiliser dans vos propres scripts pour contrôler facilement votre pompe.
🚨 Vous pouvez appliquer les mêmes concepts et exemples de code à d'autres pompes Longer, en ajustant certaines commandes en fonction du protocole spécifique de votre modèle de pompe.
De quoi avez-vous besoin pour communiquer avec votre pompe Longer ?
Pour communiquer avec une pompe péristaltique Longer en utilisant le protocole Modbus RTU, vous aurez besoin des éléments suivants :
- Une pompe Longer avec une tête de pompe et un tube de votre choix
- Un module de contrôle RS485 qui se branche sur le port DB15 à l'arrière de la pompe
- Un câble série qui connecte le module de contrôle RS485 à votre ordinateur ou appareil
- Une plateforme de programmation (Python dans le cas présent)
- Une compréhension de base du protocole Modbus RTU (expliqué ci-dessous 👇).
Comment configurer le port de communication ?
Avant de pouvoir commencer à envoyer et recevoir des données de la pompe, vous devez configurer correctement le port de communication. Voici les étapes à suivre :
- Connectez le connecteur DB15 au port DB15 à l'arrière de la pompe
- Allumez la pompe et utilisez le clavier situé à l'avant de la pompe pour accéder à l'interface de réglage de la télécommande et définir le mode de télécommande sur « COM » 🕹️
- Assurez-vous que les paramètres de communication de votre plateforme de programmation correspondent à ceux du L100-1S-2 (comme illustré dans la figure ci-dessous), à savoir :
- 1 bit de début
- 8 bits de données
- Parité : P-n (pas de parité), P-O (parité impaire) ou P-E (parité paire)
- Bit d'arrêt : S-1 (1 bit d'arrêt) ou S-2 (2 bits d'arrêt)
- Débit en bauds : 12 (1200 bits/s), 24 (2400 bits/s), 48 (4800 bits/s), 96 (9600 bits/s), 192 (19200 bits/s) ou 384 (38400 bits/s).
🚨 La communication est valide uniquement lorsque la pompe affiche l'écran de fonctionnement du mode de contrôle de communication « COM ».
Comprendre le protocole Modbus RTU
Le protocole Modbus RTU est un standard de communication largement adopté, utilisé dans les systèmes industriels et d'automatisation pour échanger des données entre appareils. Reconnu pour sa simplicité et sa robustesse, il est idéal pour contrôler des équipements tels que les pompes péristaltiques Longer. Dans cette section, nous approfondirons les éléments clés du Modbus RTU, y compris son format de communication, le contrôle de redondance cyclique (CRC) et les paramètres de communication. Nous explorerons également la structure des messages Modbus RTU et l'ensemble des commandes utilisées pour contrôler efficacement les pompes Longer.
Format de communication standard RTU Modbus
Le protocole Modbus est un cadre de communication couramment utilisé qui facilite les interactions maître-esclave entre appareils intelligents. Un message Modbus transmis d'un maître à un esclave comprend l'adresse de l'esclave, une commande spécifique (telle que la lecture ou l'écriture dans un registre), les données associées et une somme de contrôle pour la vérification des erreurs.
Ce format de message est décrit dans le tableau ci-dessous.
| Champ | Taille | Description |
|---|---|---|
| Adresse esclave | 1 octet | Adresse de la pompe. La plage est de 1 à 32 ; 0 est utilisé pour la communication de diffusion. |
| Code de fonction | 1 octet | Instruction pour le dispositif esclave : - 03H : Lecture des registres de maintien - 06H : Écriture d'un registre unique - 10H : Écriture de plusieurs registres |
| Zone de données | 0 – 252 octets | Données à transmettre (longueur variable) |
| Contrôle CRC | 2 octets | Contrôle de Redondance Cyclique pour la détection d'erreurs : - CRC faible (1 octet) : Octet de poids faible du CRC - CRC élevé (1 octet) : Octet de poids fort du CRC |
Contrôle CRC avec CRC-16 en Python
Le CRC (Cyclic Redundancy Check) est une technique essentielle pour la détection d'erreurs dans la transmission de données. Dans ce qui suit, nous allons démontrer comment implémenter le CRC-16, celui utilisé dans le système synchrone binaire américain, en utilisant Python. Dans le CRC-16, l'algorithme de détection d'erreurs utilise un polynôme G(X) = X16 + X15 + X2 + 1 pour générer la somme de contrôle. Ce polynôme définit les opérations mathématiques effectuées sur les bits du message pendant le processus de calcul du CRC. Un aperçu de l'algorithme est détaillé ci-dessous :
- Initialiser un registre 16 bits avec la valeur hexadécimale FFFF (tous les bits à un), désigné comme le registre CRC.
- Effectuez un XOR sur les 8 premiers octets du message avec l'octet de poids faible du registre CRC. Stockez le résultat dans le registre CRC.
- Décaler le registre CRC d'un bit vers la droite, avec le bit de poids fort (MSB) mis à zéro.
- Vérifier le bit de poids faible (LSB) du registre CRC :
- Si le LSB est 0, répétez l'étape 3 (opération de décalage).
- Si le LSB est 1, effectuez un XOR du registre CRC avec la valeur polynomiale 0xA001 (1010 0000 0000 0001).
- Répétez les étapes 3 et 4, pour un total de 8 décalages, afin de traiter chaque octet.
- Répétez les étapes 2 à 5 pour chaque octet du message jusqu'à ce que tous les octets aient été traités.
- Le contenu final du registre CRC est la valeur CRC.
Paramètres de communication
Chaque octet de données possède une structure composée d'un bit de début, de 8 bits de données, d'un bit de parité et d'un ou deux bits d'arrêt. Les bits sont envoyés dans l'ordre du bit de poids faible (LSB) au bit de poids fort (MSB).
Pour les entiers (2 octets), les données sont organisées avec le deuxième octet en premier, suivi du premier octet. Par exemple, la valeur hexadécimale 2378H est envoyée sous la forme 23H 78H. Pour les entiers longs et les flottants (4 octets), les données sont organisées avec le quatrième octet en premier, suivi des troisième, deuxième et premier octets.
Format de trame de message RTU Modbus
La fréquence de trame du message Modbus RTU est celle décrite dans le tableau ci-dessous.
| Champ | Taille | Description |
|---|---|---|
| Démarrer | ≥ 3,5 caractères | Indique le début de la transmission. |
| Adresse | 8 bits | Adresse du dispositif esclave. |
| Code de fonction | 8 bits | Instruction pour le dispositif esclave. |
| Données | N x 8 Bits | Données à transmettre (longueur variable, N octets). |
| Code de contrôle CRC | 16 Bits | Contrôle de Redondance Cyclique pour la détection d'erreurs. |
| Fin | ≥ 3,5 caractères | Indique la fin de la transmission. |
🚨 Assurez-vous que la trame de message est transmise en continu sans espaces inactifs entre les caractères supérieurs à 1,5 temps caractère. Les trames de message incomplètes, indiquées par un espace inactif excessif, doivent être ignorées par le nœud récepteur.
Réglage des paramètres
Le tableau ci-dessous présente les paramètres essentiels pour le modèle L100-1S-2. Ces paramètres peuvent varier entre les différents modèles de pompes Longer, soit en raison des fonctions spécifiques disponibles, soit des adresses et descriptions uniques associées à chaque paramètre.
| Paramètre | Adresse | Type de données | Description |
|---|---|---|---|
| Vitesse | 0x01 | uint_16 | Plage : 1-10 000, correspondant à 0,01 tr/min à 100 tr/min, par incréments de 0,01 tr/min. La pompe affiche la vitesse en tr/min. Exemple : 100 = 0,01 tr/min, 10000 = 100 tr/min. |
| débit | 0x02 | uint_16 | Les octets de poids fort du débit. Utilisé avec l'octet de poids faible du débit. L'unité du débit est 1 nL/min. Exemple : 02 FA F0 80H = 50.0 mL/min. |
| 0x03 | uint_16 | Les octets de poids faible du débit. Utilisé avec l'octet de poids fort du débit. L'unité du débit est 1 nL/min. Exemple : 02 FA F0 80H = 50.0 mL/min. | |
| État de la pompe | 0x04 | uint_16 | L'octet de poids faible est valide. BIT0 : Marche/Arrêt (0 = arrêt, 1 = marche). BIT1 : Pleine vitesse (0 = vitesse normale, 1 = pleine vitesse). BIT2 : Affichage de la vitesse/du débit. BIT3 : Réservé. BIT4 : Direction (0 = horaire, 1 = anti-horaire) |
| Adresse de la pompe | 0x05 | uint_16 | L'octet de poids faible est valide. Plage valide : 1-32 |
| Débit en bauds | 0x06 | uint_16 | L'octet de poids faible est valide. 01H : 1200 bps 02H : 2400 bps 03H : 4800 bps 04H : 9600 bps 05H : 19200 bps 06H : 38400 bps |
| Parité | 0x07 | uint_16 | L'octet de poids faible est valide. 01H : Pas de parité 02H : Parité impaire 03H : Parité paire |
| Bit d'arrêt | 0x08 | uint_16 | L'octet de poids faible est valide. 01H : 1 bit d'arrêt 02H : 2 bits d'arrêt |
| Verrouillage du clavier | 0x09 | uint_16 | Octet de poids faible : Active la fonction de verrouillage du clavier. 01H : Désactivé 02H : Activé Octet de poids fort : Délai avant verrouillage. 00H : 30s 01H : 60s 02H : 180s 03H : 300s 04H : 480s 05H : 600s |
💡 Notes importantes :
- Le protocole Modbus RTU Longer ne prend en charge que les codes de fonction 03H (lecture de registres), 06H (écriture d'un seul registre) et 10H (écriture de plusieurs registres).
- Lors de l'utilisation du code de fonction 06H, la pompe fonctionne en fonction de la dernière commande reçue, affichant la vitesse avec un paramètre de vitesse et le débit avec un paramètre de débit.
- Pour régler le débit, l'octet de poids fort et l'octet de poids faible doivent être spécifiés simultanément. L'unité de débit est 1 nL/min (par exemple, la commande 02 FA F0 80H correspond à 50,0 mL/min).
- Si le débit ou la vitesse dépasse la plage autorisée, la pompe affiche la valeur maximale ou minimale sans émettre d'avertissement.
Relation de conversion entre le débit et la vitesse
La relation entre le débit et la vitesse pour le L100-1S-2 peut être décrite par l'équation : Q = V x f
Où Q représente le débit en mL/min, V désigne la vitesse en tr/min, et f est le coefficient de débit mesuré en mL/r, qui est par défaut de 1.
La valeur par défaut f = 1 indique une corrélation directe entre la vitesse et le débit dans des conditions standard. Cette simplicité permet aux opérateurs d'optimiser facilement les réglages de la pompe pour leurs applications spécifiques.
Comment communiquer avec le L100-1S-2 en utilisant Python ?
Une bibliothèque Python de base conçue pour faciliter la communication et le contrôle des pompes péristaltiques Longer utilisant le protocole Modbus RTU est présentée dans cette section. Elle encapsule des fonctionnalités essentielles, telles que le réglage de la vitesse, du débit et de la direction de la pompe, ainsi que le démarrage et l'arrêt de la pompe avec facilité.
Cette bibliothèque est spécifiquement écrite sur la base du protocole de la pompe péristaltique Longer L100-1S-2 et sert d'exemple modifiable. En ajustant les commandes et les paramètres selon les besoins, les utilisateurs peuvent l'adapter au protocole Modbus RTU de leur modèle de pompe Longer spécifique.
🚨🚨🚨 Note importante
- When viewing this code, please be aware that <, >, and & symbols might not display correctly due to formatting issues. These should appear as standard Python code syntax, so make sure to interpret < as <, > as >, and & as &.
'''
-------------------------------------------------------------
Longer Peristaltic Pump Control Library Using Modbus Protocol
-------------------------------------------------------------
'''
import serial
import time
#------------------------------------------------------#
# LIBRARY MANAGING THE COMMUNICATION WITH THE PUMP #
#------------------------------------------------------#
class Longer_Pump:
# Initialize the class with serial communication parameters
def __init__(self, port, address=1, baudrate=9600, parity=serial.PARITY_NONE, bytesize=8, stopbits=1, timeout=1):
"""
Parameters:
port (str): The COM port for serial communication.
address (int): Modbus address of the pump (default is 1).
baudrate (int): The baud rate (default is 9600).
parity (str): Parity for serial communication (default is none).
bytesize (int): Number of data bits (default is 8).
stopbits (int): Number of stop bits (default is 1).
timeout (int): Timeout for serial communication (default is 1s).
"""
self.ser = serial.Serial(port=port, baudrate=baudrate, parity=parity, bytesize=bytesize, stopbits=stopbits, timeout=timeout)
self.address = address
# Open the serial port for communication with the pump
def connect(self):
if not self.ser.is_open:
self.ser.open()
# Close the serial port to end communication with the pump
def disconnect(self):
if self.ser.is_open:
self.ser.close()
# Calculate the CRC for Modbus communication
def _calculate_crc(self, data):
"""
Parameters:
data (bytearray): The data for which to calculate the CRC.
Returns:
bytes: The calculated CRC as a 2-byte value.
"""
crc = 0xFFFF
for byte in data:
crc ^= byte
for _ in range(8):
if crc & 0x0001:
crc >>= 1
crc ^= 0xA001
else:
crc >>= 1
return crc.to_bytes(2, byteorder='little')
# Send a command to the pump using the Modbus protocol
def _send_command(self, function_code, register_address, data):
"""
Parameters:
function_code (int): e.g., 0x03 for read, 0x06 for write.
register_address (int): to read from or write to.
data (list or int): to be sent (for writing registers).
Returns:
bytes: The response from the pump.
"""
# Prepare the command payload for Modbus
payload = bytearray([self.address, function_code])
payload.extend(register_address.to_bytes(2, byteorder='big'))
if isinstance(data, list):
# For multi-register commands (function code 0x10)
number_of_registers = len(data)
payload.extend(number_of_registers.to_bytes(2, byteorder='big'))
payload.append(len(data) * 2) # Byte count for the data
for value in data:
payload.extend(value.to_bytes(2, byteorder='big'))
else:
# For single-register commands (function code 0x06)
payload.extend(data.to_bytes(2, byteorder='big'))
# Append CRC
crc = self._calculate_crc(payload)
payload.extend(crc)
# Send the command to the pump
self.ser.write(payload)
response = self.ser.read(8) # Adjust this based on expected response length
return response
# Set the pump speed in RPM (0.01 RPM increments)
def set_speed(self, speed_rpm):
"""
Parameters:
speed_rpm (float): The desired speed in RPM.
"""
speed_value = int(speed_rpm * 100) # 0.01 RPM increments
response = self._send_command(0x06, 0x01, speed_value)
print(f"Set speed response: {response.hex()}")
# Set the pump flow rate in mL/min (combined high/low bytes)
def set_flow_rate(self, flow_rate_ml_min):
"""
Parameters:
flow_rate_ml_min (float): The desired flow rate in mL/min.
"""
flow_rate_nl_min = int(flow_rate_ml_min * 1_000_000) # Convert mL/min to nL/min
high_byte = (flow_rate_nl_min >> 16) & 0xFFFF
low_byte = flow_rate_nl_min & 0xFFFF
response = self._send_command(0x10, 0x02, [high_byte, low_byte])
print(f"Set flow rate response: {response.hex()}")
# Start the pump and set the display mode to either 'speed' (RPM) or 'flow_rate' (mL/min)
def start(self, display_mode="speed"):
"""
Parameters:
display_mode (str): 'speed' or 'flow_rate'.
"""
if display_mode == "speed":
pump_state = 0b00000001 # Run + Display Speed
elif display_mode == "flow_rate":
pump_state = 0b00000101 # Run + Display Flow Rate
else:
raise ValueError("Invalid display_mode. Use 'speed' or 'flow_rate'.")
response = self._send_command(0x06, 0x04, pump_state)
print(f"Start pump response: {response.hex()}")
# Stop the pump and set the display mode to either 'speed' (RPM) or 'flow_rate' (mL/min)
def stop(self, display_mode="speed"):
"""
Parameters:
display_mode (str): 'speed' or 'flow_rate'.
"""
if display_mode == "speed":
pump_state = 0b00000000 # Stop + Display Speed
elif display_mode == "flow_rate":
pump_state = 0b00000100 # Stop + Display Flow Rate
else:
raise ValueError("Invalid display_mode. Use 'speed' or 'flow_rate'.")
response = self._send_command(0x06, 0x04, pump_state)
print(f"Stop pump response: {response.hex()}")
# Set the pump direction (CW or CCW)
def set_direction(self, direction):
"""
Parameters:
direction (str): 'CW' for clockwise, 'CCW' for counter-clockwise.
"""
direction_value = 0x0010 if direction.upper() == 'CCW' else 0x0000
response = self._send_command(0x06, 0x04, direction_value)
print(f"Set direction response: {response.hex()}")
# Custom function: Run the pump at the specified speed for a certain amount of time and then stop
def run(self, speed_rpm, run_time_s, direction='CW'):
"""
Parameters:
speed_rpm (float): The speed at which to run the pump in RPM.
run_time_s (int): The time to run the pump in seconds.
direction (str): 'CW' or 'CCW'.
"""
try:
self.set_speed(speed_rpm)
self.set_direction(direction)
self.start(display_mode="speed")
# Run the pump for the specified time
for remaining_time in range(run_time_s, 0, -1):
print(f"Running... {remaining_time} seconds remaining")
time.sleep(1)
finally:
self.stop(display_mode="speed")
#-----------------------------------------------------------------------#
# EXAMPLES ON HOW TO USE THE DEFINED CLASS TO CONTROL A LONGER PUMP #
#-----------------------------------------------------------------------#
pump = Longer_Pump(port='COM7', address=1) # Adjust port and address as needed
pump.connect()
# Run the pump at 40 rpm
pump.set_speed(40.00) # Speed in RPM
pump.start(display_mode="speed")
pump.stop(display_mode="speed")
# Set direction to counter-clockwise
pump.set_direction('CCW')
# Run the pump in flow rate mode at 35 mL/min
pump.set_flow_rate(35) # Flow rate in mL/min
pump.start(display_mode="flow_rate")
pump.stop(display_mode="flow_rate") # Stop the pump
# Run the pump counter-clockwise at 10 RPM for 25 seconds
pump.run(speed_rpm=10.0, run_time_s=25, direction='CCW')
# Disconnect the pump
pump.disconnect()
Conclusion
Dans cet article de blog, nous avons abordé comment contrôler les pompes péristaltiques Longer en utilisant le protocole Modbus RTU, offrant des aperçus sur le format de communication et fournissant une bibliothèque Python pour vous aider à démarrer. Que vous travailliez avec le modèle L100-1S-2 ou que vous adaptiez le code pour une pompe différente, nous espérons que ce guide vous sera une ressource précieuse.
Restez à l'écoute pour plus de tutoriels et d'applications pratiques dans nos prochains articles. D'ici là, bon pompage et bon codage ! 💻
📧 Si vous avez des questions ou des commentaires, n'hésitez pas à nous contacter à l'adresse support@darwin-microfluidics.com.

