Рубрики
python

pyhton env / modbus

Установка на 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