Установка на debian:
apt update && apt install python3-venv python3-full -y
Создание и использование виртуального окружения:
Создайте виртуальное окружение (например, в папке myenv): python3 -m venv myenv Активируйте его: source myenv/bin/activate Установите библиотеку: pip install minimalmodbus Пере использование окружения: cd /root/myenv source /root/myenv/bin/activate Запуск скриптов: python read_modbus.py python 1.txt python 2.txt
Примеры скриптов для modbus:
cat > 1.txt << "EOF"
import minimalmodbus
import serial
# Настройка порта
instrument = minimalmodbus.Instrument('/dev/ttyUSB0', slaveaddress=1)
instrument.serial.baudrate = 9600
instrument.serial.bytesize = 8
instrument.serial.parity = serial.PARITY_NONE
instrument.serial.stopbits = 1
instrument.serial.timeout = 1.0
# Самая важная строчка для FTDI под Linux:
# Драйвер очистит входной буфер от эха сразу после отправки запроса
instrument.serial.flushInput()
try:
# Читаем 1 регистр (holding) с адреса 769 (в mbpoll это -r 769 -t 4)
# minimalmodbus использует адресацию от 0, поэтому проверяем 769 или 768 в зависимости от карты регистров устройства
value = instrument.read_register(769, functioncode=3)
print(f"Значение регистра: {value}")
except Exception as e:
print(f"Ошибка чтения: {e}")
EOF
cat > 2.txt << "EOF"
import serial
import time
# Настройки порта
ser = serial.Serial(
port='/dev/ttyUSB0',
baudrate=9600,
bytesize=8,
parity='N',
stopbits=1,
timeout=1.0
)
# Формируем запрос Modbus RTU (тот самый, что слал mbpoll)
# Чтение 1 регистра с адреса 769 (0x0301) для устройства 1
request = b'\x01\x03\x03\x00\x00\x01\x84\x4E'
# Очищаем буферы
ser.reset_input_buffer()
ser.reset_output_buffer()
# Отправляем запрос
ser.write(request)
ser.flush()
# Ждем ответа и вычитываем порцию (запрос занял время, плюс ответ)
time.sleep(0.1)
# Читаем сырые данные
raw_response = ser.read(ser.in_waiting)
print(f"Сырой ответ из порта: {raw_response}")
# Отсекаем эхо, если оно есть (ищем начало нашего ответа с адреса \x01)
# Если устройство вернуло 7 байт, как в ошибке:
if len(raw_response) >= 7:
# Если в начале висит эхо запроса (8 байт), отрезаем его
if raw_response.startswith(request):
response = raw_response[len(request):]
else:
response = raw_response
print(f"Пакет после отсечения эха: {response}")
if len(response) >= 7:
# Извлекаем данные из 4-го и 5-го байта (индексы 3 и 4)
high_byte = response[3]
low_byte = response[4]
value = (high_byte << 8) + low_byte
print(f" Успешно! Значение регистра: {value}")
else:
print("Не удалось получить полный ответ от устройства.")
ser.close()
EOF