Java использует modbus4j для реализации связи ModbusTCP.
Java использует modbus4j для реализации связи ModbusTCP.

Протокол ModbusTCP

Modbus был разработан компанией MODICON в 1979 году и представляет собой стандарт протокола промышленной полевой шины. В 1996 году Шнайдер запустил протокол Modbus, основанный на Ethernet TCP/IP: ModbusTCP. Протокол Modbus — это протокол передачи сообщений прикладного уровня, включающий три типа сообщений: ASCII, RTU и TCP. Стандартные интерфейсы физического уровня протокола Modbus включают интерфейсы RS232, RS422, RS485 и Ethernet, которые обмениваются данными в режиме «ведущий/подчиненный».

Личное ощущение:

modbusпротокол Это тоже верноадресная переменнаяВыполнять операции чтения или записи,Что может измениться, так этоадресная переменнаяизадреситип данных。 Этот код функции (определяет, что делать для 4 различных регистров объекта Modbus: читать, записывать или выполнять несколько операций вместе)

Связь между Modbus и RS485: Modbus — это протокол, а интерфейсы физического уровня включают интерфейсы RS232, RS422, RS485 и Ethernet.

Программное обеспечение для моделирования

Я хочу написать Мастер (главную станцию), поэтому мне нужен Слейв (ведомая станция)

  • Ведомое устройство ModbusЗагрузить
  • Установка: продолжайте переходить к следующему шагу.
  • Код активации: 5455415451475662.
  • активация:Connection-->connect...(F3),Введите код активации,Есть ли скриншот ниже?Введите код активации,Потому что на тот момент я не смог найти код активации
  • действовать:Создайте четыре новых разных Кода. окно функции, затем запустите код и измените Программное обеспечение для Стоимость рассмотрения.

Убедитесь, что для четырех часто используемых функций «Код», «Программное обеспечение для моделирования» отображаются F=01, F=02, F=03 и F=04.

  • 0x01: прочитать катушку
  • 0x02: Чтение дискретного входа.
  • 0x03: Чтение регистра временного хранения.
  • 0x04: Чтение входного регистра.

Соответствующий код необходимо написать в 4 методах

Понимание параметров кода

saveid: См. информацию «На шине Modbus может быть несколько подчиненных станций», Программное обеспечение для тестирование может моделировать ведомую станцию, которая имеет ID=1, естественно ее можно модифицировать на ID=2Код функции:4индивидуальный Код функция, соответствующая написанию 4-х методов, Программное обеспечение для F=1 при рассмотрении или F=2, 3, 4адрес: когда вы впервые смотрите на код, адреса всех четырех методов начинаются с 0. Повторяются ли они? Ответ: 4 Код. функциивыражать4индивидуальный区域或者设备,addrвыражать各自区域изадрессерийный номер。

Выберите режим TCP, порт фиксированный 502.

Тип адреса

F8:

Slave Definition

Вы можете свободно установить начальный адрес адреса (по умолчанию 0) и установить номер (по умолчанию 10).

Код функции

действовать:Создайте четыре новых разных Кода. окно функции, затем запустите код и измените Программное обеспечение для Стоимость рассмотрения.

тип данных

Код функции01


Код функции02


Код функции03,выбиратьFloatтип

подписано: подписано без знака: без знака шестнадцатеричный: шестнадцатеричный двоичный: двоичный

big-endian: big endian, сохраняет старший байт по начальному адресу (старшая адресация) Little-endian: Little-endian, сохраняет младший байт по начальному адресу (младшая адресация).

обмен: обмен

Дважды щелкните первый адрес для ввода данных, и вам будет предложено ввести тип данных. 32-битные данные занимают 2 адреса, поэтому следующий адрес:


Код функции04


Использование modbus4j

зависимость Maven

Язык кода:javascript
копировать
<!-- Если вы хотите ссылаться на modbus4j, вам необходимо ввести следующий репозиторий id:ias-snapshots id:ias-releases два ,Загрузка с использованием репозитория по умолчанию,Не используйте облачный склад Alibaba.-->
    <repositories>
        <repository>
            <releases>
                <enabled>false</enabled>
            </releases>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
            <id>ias-snapshots</id>
            <name>Infinite Automation Snapshot Repository</name>
            <url>https://maven.mangoautomation.net/repository/ias-snapshot/</url>
        </repository>
        <repository>
            <releases>
                <enabled>true</enabled>
            </releases>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
            <id>ias-releases</id>
            <name>Infinite Automation Release Repository</name>
            <url>https://maven.mangoautomation.net/repository/ias-release/</url>
        </repository>
    </repositories>
     <!-- modbus4j -->
        <dependency>
            <groupId>com.infiniteautomation</groupId>
            <artifactId>modbus4j</artifactId>
            <version>3.0.3</version>
        </dependency>

Завод подключения Modbus

Класс подключения ModbusTcpMaster

Язык кода:javascript
копировать
@Service(value = "ModbusTcpMaster")
public class ModbusTcpMaster {
    private final ModbusFactory modbusFactory = new ModbusFactory();

    /**
     * Получить раба
     * @return
     * @throws ModbusInitException
     */
    public ModbusMaster getSlave(String ip,int port) {
        ModbusMaster master = null;
        try {
            IpParameters params = new IpParameters();
            params.setHost(ip);
            params.setPort(port);
            //Этот атрибут определяет, является ли кадр протокола структурой RTU, инкапсулированной через TCP с использованием Modbus При использовании TCP/IP установите значение false. с использованием Modbus rtu over Для TCP/IP установите значение true
            params.setEncapsulated(false);
            // modbusFactory.createRtuMaster(wapper); //RTU протокол
            // modbusFactory.createUdpMaster(params);//UDP протокол
            // modbusFactory.createAsciiMaster(wrapper);//ASCII протокол
            master = modbusFactory.createTcpMaster(params, false);
            //Максимальное время ожидания
            master.setTimeout(2000);
            //Максимальное количество подключений
            master.setRetries(5);
            master.init();
        } catch (ModbusInitException e) {
            e.printStackTrace();

        }
        return master;
    }
}

Java читает данные через modbus4j

Класс Modbus4jReadUtil

Язык кода:javascript
копировать
public class Modbus4jReadUtil {

    /**
     * Читать[01 Coil Status 0x] тип выключательданные     *
     * @param slaveId slaveId
     * @param offset  Расположение
     * @return Чтение значения
     * @throws ModbusTransportException аномальный
     * @throws ErrorResponseException   аномальный
     */
    public static Boolean readCoilStatus(ModbusMaster master,int slaveId, int offset,String dev_code){
        // 01 Coil Status
        BaseLocator<Boolean> loc = BaseLocator.coilStatus(slaveId, offset);
        try {
            return master.getValue(loc);
        }catch (Exception e){
            if (e.getMessage().equals("java.net.SocketTimeoutException: connect timed out")) System.err.println(dev_code+":"+e.getMessage());
            else e.printStackTrace();
            return null;
        }
    }


    /**
     * Читать[02 Input Status 1x] тип выключательданные     *
     * @param slaveId
     * @param offset
     * @return
     * @throws ModbusTransportException
     * @throws ErrorResponseException
     */
    public static Boolean readInputStatus(ModbusMaster master,int slaveId, int offset,String dev_code) {
        // 02 Input Status
        BaseLocator<Boolean> loc = BaseLocator.inputStatus(slaveId, offset);
        try{
            return master.getValue(loc);
        }catch (Exception e){
            if (e.getMessage().equals("java.net.SocketTimeoutException: connect timed out")) System.err.println(dev_code+":"+e.getMessage());
            else e.printStackTrace();
            return null;
        }
    }


    /**
     * Читать[03 Holding Тип регистрации 2x]Аналоговое количестводанные     *
     * @param slaveId  slave Id
     * @param offset   Расположение
     * @param dataType тип данных,Из com.serotonin.modbus4j.code.DataType.     * @return
     * @throws ModbusTransportException аномальный
     * @throws ErrorResponseException   аномальный
     */
    public static Number readHoldingRegister(ModbusMaster master,int slaveId, int offset, int dataType,String dev_code) {
        // 03 Holding Тип регистрацииданные读取
        BaseLocator<Number> loc = BaseLocator.holdingRegister(slaveId, offset, dataType);
        try {
            return master.getValue(loc);
        }catch (Exception e){
            if (e.getMessage().equals("java.net.SocketTimeoutException: connect timed out")) System.err.println(dev_code+":"+e.getMessage());
            else e.printStackTrace();
            return null;
        }
    }


    /**
     * Читать[04 Input Registers 3x] тип Аналоговое количестводанные     *
     * @param slaveId  slaveId
     * @param offset   Расположение
     * @param dataType тип данных,Из com.serotonin.modbus4j.code.DataType.     * @return Возврат результатов
     * @throws ModbusTransportException аномальный
     * @throws ErrorResponseException   аномальный
     */
    public static Number readInputRegisters(ModbusMaster master,int slaveId, int offset, int dataType,String dev_code) {
        // 04 Input Регистры типа данных для чтения
        BaseLocator<Number> loc = BaseLocator.inputRegister(slaveId, offset, dataType);
        try{
            return master.getValue(loc);
        }catch (Exception e){
            if (e.getMessage().equals("java.net.SocketTimeoutException: connect timed out")) System.err.println(dev_code+":"+e.getMessage());
            else e.printStackTrace();
            return null;
        }
    }

    /**
     * Как использовать пакетное чтение
     *
     * @throws ModbusTransportException
     * @throws ErrorResponseException
     */
    public static void batchRead(ModbusMaster master) throws ModbusTransportException, ErrorResponseException {
        BatchRead<Integer> batch = new BatchRead<Integer>();
        batch.addLocator(0, BaseLocator.holdingRegister(1, 1, DataType.TWO_BYTE_INT_SIGNED));
        batch.addLocator(1, BaseLocator.inputStatus(1, 0));
        batch.setContiguousRequests(true);
        BatchResults<Integer> results = master.send(batch);
        System.out.println("batchRead:" + results.getValue(0));
        System.out.println("batchRead:" + results.getValue(1));
    }

}

тест

Язык кода:javascript
копировать
  @Autowired
    @Qualifier(value = "ModbusTcpMaster")
    ModbusTcpMaster masterTcp;
    @Test
    public void test() {
        //Открываем соединение ModbusTcpMaster
        ModbusMaster master = masterTcp.getSlave("127.0.0.1", 502);
        try {
            // 01тест
            Boolean v011 = Modbus4jReadUtil.readCoilStatus(master,1, 0,"test_code");
            Boolean v012 = Modbus4jReadUtil.readCoilStatus(master,1, 1,"test_code");
            Boolean v013 = Modbus4jReadUtil.readCoilStatus(master,1, 6,"test_code");
            System.out.println("v011:" + v011);
            System.out.println("v012:" + v012);
            System.out.println("v013:" + v013);
            // 02тест
            Boolean v021 = Modbus4jReadUtil.readInputStatus(master,1, 0,"test_code");
            Boolean v022 = Modbus4jReadUtil.readInputStatus(master,1, 1,"test_code");
            Boolean v023 = Modbus4jReadUtil.readInputStatus(master,1, 2,"test_code");
            System.out.println("v021:" + v021);
            System.out.println("v022:" + v022);
            System.out.println("v023:" + v023);

            // 03тест
            Number v031 = Modbus4jReadUtil.readHoldingRegister(master,1, 1, DataType.FOUR_BYTE_FLOAT,"test_code");// Обратите внимание, плавайте
            Number v032 = Modbus4jReadUtil.readHoldingRegister(master,1, 3, DataType.FOUR_BYTE_FLOAT,"test_code");// То же, что и выше
            System.out.println("v031:" + v031);
            System.out.println("v032:" + v032);

            // 04тест
            Number v041 = Modbus4jReadUtil.readInputRegisters(master,1, 0, DataType.FOUR_BYTE_FLOAT,"test_code");//
            Number v042 = Modbus4jReadUtil.readInputRegisters(master,1, 2, DataType.FOUR_BYTE_FLOAT,"test_code");//
            System.out.println("v041:" + v041);
            System.out.println("v042:" + v042);
            // пакетное чтение
            Modbus4jReadUtil.batchRead(master);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

подчиненная конфигурация

действовать:Создайте четыре новых разных Кода. окно функции, затем запустите код и измените Программное обеспечение для Стоимость рассмотрения.

Выход:

Язык кода:javascript
копировать
v011:true
v012:false
v013:true
v021:true
v022:false
v023:true
v031:7.5
v032:10.5
v041:1.5
v042:3.0
7.5
true

Java записывает данные через modbus4j

Классы Modbus4jWriteUtils

Язык кода:javascript
копировать
public class Modbus4jWriteUtils{

    /**
     * Запишите данные о значении одного (катушки) переключателя.
     * Код функция: 05, точка выхода переключателя Q устанавливается или сбрасывается, запись данных в регистр типа DO реальной машины, логический тип (0x), который можно читать и записывать.
     * @param slaveId     идентификатор подчиненного устройства
     * @param writeOffset Расположение-预访问изадрес-адресобъем:0-255
     * @param writeValue  Значение — 1, если установлено, 0, если сброшено.
     * @return Успешно ли написание
     */
    public static boolean writeCoil(ModbusMaster master,int slaveId, int writeOffset, boolean writeValue){
        boolean flag = false;
        try {
            // Создать запрос
            WriteCoilRequest request = new WriteCoilRequest(slaveId, writeOffset, writeValue);
            // Отправьте запрос и получите объект ответа
            WriteCoilResponse response = (WriteCoilResponse) master.send(request);
            flag =  !response.isException();
        }catch (ModbusTransportException e){
            e.printStackTrace();
        }
        return flag;
    }

    /**
     * Запись нескольких значений переключения данных (катушек)
     * Код функциидля:0F,Запись нескольких значений переключения данных (катушек)
     * @param slaveId     slaveId
     * @param startOffset начинать Расположение
     * @param bdata       писатьизданные     * @return Успешно ли написание
     */
    public static boolean writeCoils(ModbusMaster master,int slaveId, int startOffset, boolean[] bdata) {
        boolean flag = false;
        try {
            // Создать запрос
            WriteCoilsRequest request = new WriteCoilsRequest(slaveId, startOffset, bdata);
            // Отправьте запрос и получите объект ответа
            WriteCoilsResponse response = (WriteCoilsResponse) master.send(request);
            flag = !response.isException();
        }catch (ModbusTransportException e){
            e.printStackTrace();
        }
        return flag;
    }

    /***
     *  Регистр временного хранения записывает одиночный
     *  Код функция: 06, запись данных в память V, данные на реальную машину, тип данные — это Int, числовой тип, который можно читать и записывать (4x).
     * @param slaveId slaveId
     * @param writeOffset начинать Расположение
     * @param writeValue писатьизданные     */
    public static boolean writeRegister(ModbusMaster master,int slaveId, int writeOffset, short writeValue){
        boolean flag = false;
        try {
            // Создать объект запроса
            WriteRegisterRequest request = new WriteRegisterRequest(slaveId, writeOffset, writeValue);
            // Отправьте запрос и получите объект ответа
            WriteRegisterResponse response = (WriteRegisterResponse) master.send(request);
            flag = !response.isException();
        }catch (ModbusTransportException e){
            e.printStackTrace();
        }
        return flag;
    }

    /**
     * Запись нескольких аналоговых величин в данные регистра временного хранения.
     * Код функциидля:16,Воляданныеписать至多индивидуальныйVпамять,писатьданные на реальную машину, тип data is short[], числовой тип, который можно читать и записывать (4x).
     * @param slaveId     идентификатор подчиненного устройства Modbus
     * @param startOffset Начальное значение смещения регулировки
     * @param sdata       писатьизданные     * @return возвращаться Успешно ли написание
     */
    public static boolean writeRegisters(ModbusMaster master,int slaveId, int startOffset, short[] sdata) {
        boolean flag = false;
        try {
            // Создать объект запроса
            WriteRegistersRequest request = new WriteRegistersRequest(slaveId, startOffset, sdata);
            // Отправьте запрос и получите объект ответа
            WriteRegistersResponse response = (WriteRegistersResponse) master.send(request);
            flag = !response.isException();
        }catch (ModbusTransportException e){
            e.printStackTrace();
        }
        return flag;
    }

    /**
     * Запись данных в соответствии с типом (например: запись аналогового типа Float, аналогового типа Double, целочисленного типа Short, Integer, Long)
     *
     * @param value    записать значение
     * @param dataType com.serotonin.modbus4j.code.DataType
     */
    public static void writeHoldingRegister(ModbusMaster master,int slaveId, int offset, Number value, int dataType) {
        try {
            // тип
            BaseLocator<Number> locator = BaseLocator.holdingRegister(slaveId, offset, dataType);
            master.setValue(locator, value);
        }catch (Exception e){
            e.printStackTrace();
        }
    }

}

тест

Язык кода:javascript
копировать
 @Autowired
    @Qualifier(value = "ModbusTcpMaster")
    ModbusTcpMaster masterTcp;
    @Test
    public void test() {
        //Открываем соединение ModbusTcpMaster
        ModbusMaster master = masterTcp.getSlave("127.0.0.1", 502);
        try {
            //Запись аналоговой величины
            writeHoldingRegister(master,1,0, 10.1f, DataType.FOUR_BYTE_FLOAT);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

Ссылки: https://www.cnblogs.com/ioufev/p/10831289.html

boy illustration
RasaGpt — платформа чат-ботов на основе Rasa и LLM.
boy illustration
Nomic Embed: воспроизводимая модель внедрения SOTA с открытым исходным кодом.
boy illustration
Улучшение YOLOv8: EMA основана на эффективном многомасштабном внимании, основанном на межпространственном обучении, и эффект лучше, чем у ECA, CBAM и CA. Малые цели имеют очевидные преимущества | ICASSP2023
boy illustration
Урок 1 серии Libtorch: Тензорная библиотека Silky C++
boy illustration
Руководство по локальному развертыванию Stable Diffusion: подробные шаги и анализ распространенных проблем
boy illustration
Полностью автоматический инструмент для работы с видео в один клик: VideoLingo
boy illustration
Улучшения оптимизации RT-DETR: облегченные улучшения магистрали | Support Paddle облегченный rtdetr-r18, rtdetr-r34, rtdetr-r50, rtdet
boy illustration
Эксклюзивное оригинальное улучшение YOLOv8: собственная разработка SPPF | Деформируемое внимание с большим ядром (D-LKA Attention), большое ядро ​​​​свертки улучшает механизм внимания восприимчивых полей с различными функциями
boy illustration
Создано Datawhale: выпущено «Руководство по тонкой настройке развертывания большой модели GLM-4»!
boy illustration
7B превышает десятки миллиардов, aiXcoder-7B с открытым исходным кодом Пекинского университета — это самая мощная модель большого кода, лучший выбор для корпоративного развертывания.
boy illustration
Используйте модель Huggingface, чтобы заменить интерфейс внедрения OpenAI в китайской среде.
boy illustration
Оригинальные улучшения YOLOv8: несколько новых улучшений | Сохранение исходной информации — алгоритм отделяемой по глубине свертки (MDSConv) |
boy illustration
Второй пилот облачной разработки | Быстро поиграйте со средствами разработки на базе искусственного интеллекта
boy illustration
Бесшовная интеграция, мгновенный интеллект [1]: платформа больших моделей Dify-LLM, интеграция с нулевым кодированием и встраивание в сторонние системы, более 42 тысяч звезд, чтобы стать свидетелями эксклюзивных интеллектуальных решений.
boy illustration
Решенная Ошибка | Загрузка PyTorch медленная: TimeoutError: [Errno 110] При загрузке факела истекло время ожидания — Cat Head Tiger
boy illustration
Brother OCR, библиотека с открытым исходным кодом для Python, которая распознает коды проверки.
boy illustration
Новейшее подробное руководство по загрузке и использованию последней демонстрационной версии набора данных COCO.
boy illustration
Выпущен отчет о крупной модели финансовой отрасли за 2023 год | Полный текст включен в загрузку |
boy illustration
Обычные компьютеры также могут работать с большими моделями, и вы можете получить личного помощника с искусственным интеллектом за три шага | Руководство для начинающих по локальному развертыванию LLaMA-3
boy illustration
Одной статьи достаточно для анализа фактора транскрипции SCENIC на Python (4)
boy illustration
Бросая вызов ограничениям производительности небольших видеокарт, он научит вас запускать большие модели глубокого обучения с ограниченными ресурсами, а также предоставит полное руководство по оценке и эффективному использованию памяти графического процессора!
boy illustration
Команда Fudan NLP опубликовала 80-страничный обзор крупномасштабных модельных агентов, в котором в одной статье представлен обзор текущего состояния и будущего агентов ИИ.
boy illustration
[Эксклюзив] Вы должны знать о новой функции JetBrains 2024.1 «Полнострочное завершение кода», чтобы решить вашу путаницу!
boy illustration
Краткое изложение базовых знаний о регистрации изображений 1.0
boy illustration
Новейшее подробное руководство по установке и использованию библиотеки cv2 (OpenCV, opencv-python) в Python.
boy illustration
Легко создайте локальную базу знаний для крупных моделей на основе Ollama+AnythingLLM.
boy illustration
[Решено] ошибка установки conda. Среда решения: не удалось выполнить первоначальное зависание решения. Повторная попытка с помощью файла (графическое руководство).
boy illustration
Одна статья поможет вам понять RAG (Retrival Enhanced Generation) | Введение в концепцию и теорию + практику работы с кодом (включая исходный код).
boy illustration
Эволюция архитектуры шлюза облачной разработки
boy illustration
Docker и Kubernetes [Разработка контейнерных приложений с помощью Python]