FT4232H
|
1 2 3 4 5 6 7 |
FT4232H переключить в режим MODBUS 485 https://manpages.debian.org/testing/ftdi-eeprom/ftdi_eeprom.1.en.html https://netcup-03.armbian.com/dl/rockpi-s/archive/Armbian_26.2.1_Rockpi-s_trixie_current_6.18.9_minimal.img.xz PID 6011 = FT4232H в режиме Quad UART (4 последовательных порта) PID 6014 = FT4232H в режиме Quad UART/FIFO (с поддержкой дополнительных режимов) |
napic arbian
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 |
0. Дистрибутив: Armbian_26.2.1_Rockpi-s_trixie_current_6.18.9_minimal 1. Оверлеи: /boot/armbianEnv.txt overlays=otg-host 2. Костюмные оверлеи от напи: команда для добавления: armbian-add-overlay <файл.dts> инструкция: https://napiworld.ru/recipes/armbian-tuning/ где брать файлы: https://gitlab.nnz-ipc.net/pub/napilinux/kernel/-/tree/linux6.6/arch/arm64/boot/dts/rockchip/overlay 3. Необходимый софт установка: apt update apt install libftdi1-2 libftdi-dev ftdi-eeprom gcc libftdi1-dev libftdi1 libudev-dev 4. Проверка usb: lsusb lsusb -v -d 0403:6011 | grep -i "serial\|product" Выгрузка модулей если требуется: rmmod ftdi_sio rmmod usbserial 5. ДОКИ /usr/share/doc/ftdi-eeprom/examples/ zcat /usr/share/doc/ftdi-eeprom/example.conf.gz 6. Пример конфигурационный файл для прошивки FT4232 в режиме MODBUS 485: cat > ft4232h.conf << EOF # Имя файла, содержащий образ EEPROM, который будет создан filename=test.bin # Идентификатор производителя. Для FT4232H значение по умолчанию: 0x0403 vendor_id=0x0403 # Идентификатор продукта. Для FT4232H значение по умолчанию: 0x6011 product_id=0x6011 # Тип EEPROM микросхемы. 0x46 для 93xx46, 0x56 для 93xx56 и 0x66 для 93xx66 #eeprom_type=0x46 eeprom_type=0x56 manufacturer="lablab2" product="Quad RS485" serial="1234" # Разрешить использование серийного номера use_serial=true # Ограничение по потреблению микросхемы: (значение параметра) * 2 мА. Значение параметра # должно быть равно 0, когда self_powered=true #max_power=0 #max_power=500 # Микросхема питается не от USB, а от собственного источника питания #self_powered=true #self_powered=false # Если на линии RI логический 0 и значение параметра равно true, то хост контроллер USB # выйдет из режима ожидания примерно через 20 мс. # remote_wakeup=false #remote_wakeup=true # Задать режим работы порта # # "UART", "FIFO", "OPTO", "CPU", "FT1284" #cha_type=UART #chb_type=FIFO #chc_type=OPTO #chd_type=CPU # Использовать драйвер виртуального com-порта #cha_vcp=true #chb_vcp=true #chc_vcp=true #chd_vcp=true # Разрешить режим RS-485 #cha_rs485=true #chb_rs485=true #chc_rs485=true #chd_rs485=true # Channel A cha_type=UART cha_vcp=true cha_rs485=true #cbush0 = TXDEN # Channel B chb_type=UART chb_vcp=true chb_rs485=true # Channel C #chc_type=UART chc_vcp=true chc_rs485=true #CDBUS7=TXDEN # Channel D #chd_type=UART chd_vcp=true chd_rs485=true #DDBUS7=TXDEN # Управление направлением (TXDEN) # invert_txd = true EOF 7. Работа с прошивкой ft4232 Зашить: ftdi_eeprom --flash-eeprom ft4232h.conf прочитать: ftdi_eeprom --read-eeprom ft4232h.conf |
Сборка libftdi
|
1 2 3 4 5 6 7 8 9 |
Собирем сам соберется, но тут 0.17 :( cd /opt git clone https://github.com/lipro/libftdi cd libftdi mkdir build cd build cmake -DCMAKE_INSTALL_PREFIX="/usr" ../ make make install |
Собираем с сайта libftdi
|
1 2 3 4 5 6 7 8 9 10 11 |
###https://www.intra2net.com/en/developer/libftdi/download.php ###Requirements and dependencies ###libusb 1.0 - Library for talking to USB devices from user-space. Needed by libftdi. ###libconfuse - Library for parsing configuration files. Needed by ftdi_eeprom. ### wget https://www.intra2net.com/en/developer/libftdi/download/libftdi1-1.5.tar.bz2 mkdir build cd build cmake -DCMAKE_INSTALL_PREFIX="/usr" ../ make make install |
Питон скрипт для тестов:
|
1 |
Python env:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
0. Установите пакеты: apt update && apt install python3-venv python3-full -y 1. Создайте виртуальное окружение (например, в папке myenv): python3 -m venv myenv 2. Активируйте его: source myenv/bin/activate 3. Установите библиотеку: pip install minimalmodbus 4. Пере использование окружения: cd /root/myenv source /root/myenv/bin/activate Запуск python read_modbus.py |
Python скрипты для тестов:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 |
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 python 1.txt 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 python 2.txt cat > rs485.py << "EOF" import os import fcntl import struct import sys TIOCGRS485 = 0x542E TIOCSRS485 = 0x542F SER_RS485_ENABLED = 0x01 SER_RS485_RX_DURING_TX = 0x08 def set_rs485(port, enable=True): fd = os.open(port, os.O_RDWR | os.O_NOCTTY) try: # Читаем текущие настройки buf = fcntl.ioctl(fd, TIOCGRS485, struct.pack('8I', 0,0,0,0,0,0,0,0)) flags = struct.unpack('8I', buf)[0] if enable: flags |= SER_RS485_ENABLED flags &= ~SER_RS485_RX_DURING_TX else: flags &= ~SER_RS485_ENABLED fcntl.ioctl(fd, TIOCSRS485, struct.pack('8I', flags, 0,0,0,0,0,0,0)) finally: os.close(fd) if __name__ == "__main__": if len(sys.argv) < 2: print("Usage: python rs485.py /dev/ttyUSB0") sys.exit(1) set_rs485(sys.argv[1], True) EOF python3 rs485.py /dev/ttyUSB0 python3 rs485.py /dev/ttyUSB1 python3 rs485.py /dev/ttyUSB2 python3 rs485.py /dev/ttyUSB3 |
mbpoll и modpoll:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
0. датчик: holding (output) регистры: 768 температура * 10 796 влажность *10 ID, по умолчанию 1. Как изменить пока не ясно. 13 скорость, по умолчанию 3 - 9600 14 чётность, по умолчанию 0 - NONE 1279 коррекция температуры 1280 коррекция влажности В некоторых сниферах и OPC серверах надо указывать адрес на 1 больше. 1. Пример команд: mbpoll -m rtu -a 1 -r 769 -c 1 -t 4 -b 9600 -P none -v /dev/ttyUSB0 modpoll -b 9600 -p none -m rtu -a 1 -r 769 -c 1 -t 4 -1 /dev/ttyUSB1 for i in 0 1 2 3 ; do modpoll -b 9600 -p none -m rtu -a 1 -r 769 -c 1 -t 4 -1 /dev/ttyUSB$i sleep 2 done for port in 0 1 2 3 ; do for reg in 768 796 1279 1280 ; do modpoll -b 9600 -p none -m rtu -a 1 -r $reg -t 4 -c 1 -1 /dev/ttyUSB$port sleep 1 done done screen /dev/ttyUSB0 9600 cs8 -parenb -cstopb stty -F /dev/ttyUSB0 9600 raw -echo; cat /dev/ttyUSB0 socat -d -d OPEN:/dev/ttyUSB0,b9600,rawer,echo=0 SYSTEM:'tee /tmp/tty.log | socat - "OPEN:/dev/ttyUSB0,b9600,rawer,echo=0"' 2. Тесты: while true; do echo "x" > /dev/ttyUSB0; sleep 0.1; done 3. Снять блокировку если нужно rm -f /var/lock/LCK..ttyUSB0 |