【MODBUS】Используйте modbus4j для реализации связи ModbusTCP.
【MODBUS】Используйте modbus4j для реализации связи ModbusTCP.

1. зависимость maven

Официальное описание: GitHub - MangoAutomation/modbus4j: A high-performance and ease-of-use implementation of the Modbus protocol written in Java. Supports ASCII, RTU, TCP, and UDP transports as slave or master, automatic request partitioning and response data type parsing. Здесь есть подводный камень: склад Alibaba Cloud, настроенный с помощью Maven, невозможно загрузить. Только закомментировав склад Alibaba Cloud и используя склад по умолчанию, загрузка может быть успешной.

pom.xml

Язык кода:javascript
копировать
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>com.tcb</groupId>
  <artifactId>modbus</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>modbus</name>
  <url>http://maven.apache.org</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>
  
  <!-- Если вы хотите ссылаться на 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>
    
    <dependencies>
         <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13-beta-3</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.infiniteautomation</groupId>
            <artifactId>modbus4j</artifactId>
            <version>3.0.3</version>
        </dependency>
        
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.9</version>
        </dependency>
    </dependencies>

</project>
2. Java реализует связь по протоколу Modbus.

Оригинальная ссылка: modbus Инструкция по использованию TCP-связи Modbus4j-Java Programming-Zuosou Основные зависимости: modbus4j.jar commons-lang3-3.0.jar

Класс Modbus4jUtils

Язык кода:javascript
копировать
/**
 * Класс инструментов связи Modbus, реализованный с использованием modbus4j.
 * 
 * @author lxq
 * @dependencies modbus4j-3.0.3.jar
 * @website https://github.com/infiniteautomation/modbus4j
 */
public class Modbus4jUtils {
    /**
     * фабрика.
     */
    static ModbusFactory modbusFactory;
    static {
        if (modbusFactory == null) {
            modbusFactory = new ModbusFactory();
        }
    }

    /**
     * Получить мастера
     * 
     * @return
     * @throws ModbusInitException
     */
    public static ModbusMaster getMaster() throws ModbusInitException {
        IpParameters params = new IpParameters();
        params.setHost("localhost");
        params.setPort(502);
        //
        // modbusFactory.createRtuMaster(params); //RTU протокол
        // modbusFactory.createUdpMaster(params);//UDP протокол
        // modbusFactory.createAsciiMaster(params);//ASCII протокол

        // использовать Modbus RTU over TCP/IP, второй параметр правда, это modbusFactory.createTcpMaster(params, true)
        ModbusMaster master = modbusFactory.createTcpMaster(params, false);// TCP протокол
        master.init();

        return master;
    }

    /**
     * Читать[01 Coil Status 0x] тип выключательданные     * 
     * @param slaveId
     *            slaveId
     * @param offset
     *            Расположение
     * @return Чтение значения
     * @throws ModbusTransportException
     *             аномальный
     * @throws ErrorResponseException
     *             аномальный
     * @throws ModbusInitException
     *             аномальный
     */
    public static Boolean readCoilStatus(int slaveId, int offset)
            throws ModbusTransportException, ErrorResponseException, ModbusInitException {
        // 01 Coil Status
        BaseLocator<Boolean> loc = BaseLocator.coilStatus(slaveId, offset);
        Boolean value = getMaster().getValue(loc);
        return value;
    }

    /**
     * Читать[02 Input Status 1x] тип выключательданные     * 
     * @param slaveId
     * @param offset
     * @return
     * @throws ModbusTransportException
     * @throws ErrorResponseException
     * @throws ModbusInitException
     */
    public static Boolean readInputStatus(int slaveId, int offset)
            throws ModbusTransportException, ErrorResponseException, ModbusInitException {
        // 02 Input Status
        BaseLocator<Boolean> loc = BaseLocator.inputStatus(slaveId, offset);
        Boolean value = getMaster().getValue(loc);
        return value;
    }

    /**
     * Читать[03 Holding Тип регистрации 2x]Аналоговое количестводанные     * 
     * @param slaveId
     *            slave Id
     * @param offset
     *            Расположение
     * @param dataType
     *            тип данных из com.serotonin.modbus4j.code.DataType.
     * @return
     * @throws ModbusTransportException
     *             аномальный
     * @throws ErrorResponseException
     *             аномальный
     * @throws ModbusInitException
     *             аномальный
     */
    public static Number readHoldingRegister(int slaveId, int offset, int dataType)
            throws ModbusTransportException, ErrorResponseException, ModbusInitException {
        // 03 Holding Тип регистрацииданные读取
        BaseLocator<Number> loc = BaseLocator.holdingRegister(slaveId, offset, dataType);
        Number value = getMaster().getValue(loc);
        return value;
    }

    /**
     * Читать[04 Input Registers 3x] тип Аналоговое количестводанные     * 
     * @param slaveId
     *            slaveId
     * @param offset
     *            Расположение
     * @param dataType
     *            тип данных из com.serotonin.modbus4j.code.DataType.
     * @return Возврат результатов
     * @throws ModbusTransportException
     *             аномальный
     * @throws ErrorResponseException
     *             аномальный
     * @throws ModbusInitException
     *             аномальный
     */
    public static Number readInputRegisters(int slaveId, int offset, int dataType)
            throws ModbusTransportException, ErrorResponseException, ModbusInitException {
        // 04 Input Регистры типа данных для чтения
        BaseLocator<Number> loc = BaseLocator.inputRegister(slaveId, offset, dataType);
        Number value = getMaster().getValue(loc);
        return value;
    }

    /**
     * Как использовать пакетное чтение
     * 
     * @throws ModbusTransportException
     * @throws ErrorResponseException
     * @throws ModbusInitException
     */
    public static void batchRead() throws ModbusTransportException, ErrorResponseException, ModbusInitException {

        BatchRead<Integer> batch = new BatchRead<Integer>();

        batch.addLocator(0, BaseLocator.holdingRegister(1, 1, DataType.FOUR_BYTE_FLOAT));
        batch.addLocator(1, BaseLocator.inputStatus(1, 0));

        ModbusMaster master = getMaster();

        batch.setContiguousRequests(false);
        BatchResults<Integer> results = master.send(batch);
        System.out.println(results.getValue(0));
        System.out.println(results.getValue(1));
    }

    /**
     * тест
     * 
     * @param args
     */
    public static void main(String[] args) {
        try {
            // 01тест
            Boolean v011 = readCoilStatus(1, 0);
            Boolean v012 = readCoilStatus(1, 1);
            Boolean v013 = readCoilStatus(1, 6);
            System.out.println("v011:" + v011);
            System.out.println("v012:" + v012);
            System.out.println("v013:" + v013);
            // 02тест
            Boolean v021 = readInputStatus(1, 0);
            Boolean v022 = readInputStatus(1, 1);
            Boolean v023 = readInputStatus(1, 2);
            System.out.println("v021:" + v021);
            System.out.println("v022:" + v022);
            System.out.println("v023:" + v023);

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

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

        } 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.07.5true
3. Java записывает данные через modbus4j

Оригинальная ссылка: modbus Инструкция по использованию TCP-связи Modbus4j-Java Programming-Zuosou

ClassModbus4jWriteUtils.java

Язык кода:javascript
копировать
package com.tcb.modbus;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.serotonin.modbus4j.ModbusFactory;
import com.serotonin.modbus4j.ModbusMaster;
import com.serotonin.modbus4j.code.DataType;
import com.serotonin.modbus4j.exception.ErrorResponseException;
import com.serotonin.modbus4j.exception.ModbusInitException;
import com.serotonin.modbus4j.exception.ModbusTransportException;
import com.serotonin.modbus4j.ip.IpParameters;
import com.serotonin.modbus4j.locator.BaseLocator;
import com.serotonin.modbus4j.msg.ModbusResponse;
import com.serotonin.modbus4j.msg.WriteCoilRequest;
import com.serotonin.modbus4j.msg.WriteCoilResponse;
import com.serotonin.modbus4j.msg.WriteCoilsRequest;
import com.serotonin.modbus4j.msg.WriteCoilsResponse;
import com.serotonin.modbus4j.msg.WriteRegisterRequest;
import com.serotonin.modbus4j.msg.WriteRegisterResponse;
import com.serotonin.modbus4j.msg.WriteRegistersRequest;

/**
 * modbus4jПисатьвходитьданные
 * 
 * @author xq
 *
 */
public class Modbus4jWriteUtils {
    static Log log = LogFactory.getLog(Modbus4jWriteUtils.class);
    /**
     * фабрика.
     */
    static ModbusFactory modbusFactory;
    static {
        if (modbusFactory == null) {
            modbusFactory = new ModbusFactory();
        }
    }

    /**
     * Получить tcpMaster
     * 
     * @return
     * @throws ModbusInitException
     */
    public static ModbusMaster getMaster() throws ModbusInitException {
        IpParameters params = new IpParameters();
        params.setHost("localhost");
        params.setPort(502);

        ModbusMaster tcpMaster = modbusFactory.createTcpMaster(params, false);
        tcpMaster.init();

        return tcpMaster;
    }

    /**
     * Писать [01 Coil Статус(0x)]Писатьone function ID = 5
     * 
     * @param slaveId
     *            идентификатор подчиненного устройства
     * @param writeOffset
     *            Расположение
     * @param writeValue
     *            ценить
     * @return ли Писатьвходить成功
     * @throws ModbusTransportException
     * @throws ModbusInitException
     */
    public static boolean writeCoil(int slaveId, int writeOffset, boolean writeValue)
            throws ModbusTransportException, ModbusInitException {
        // Получить мастера
        ModbusMaster tcpMaster = getMaster();
        // Создать запрос
        WriteCoilRequest request = new WriteCoilRequest(slaveId, writeOffset, writeValue);
        // Отправьте запрос и получите объект ответа
        WriteCoilResponse response = (WriteCoilResponse) tcpMaster.send(request);
        if (response.isException()) {
            return false;
        } else {
            return true;
        }
    }

    /**
     * Писать[01 Coil Status(0x)] Писатьмножество function ID = 15
     * 
     * @param slaveId
     *            slaveId
     * @param startOffset
     *            开始Расположение
     * @param bdata
     *            Писатьвходить的данные
     * @return ли Писатьвходить成功
     * @throws ModbusTransportException
     * @throws ModbusInitException
     */
    public static boolean writeCoils(int slaveId, int startOffset, boolean[] bdata)
            throws ModbusTransportException, ModbusInitException {
        // Получить мастера
        ModbusMaster tcpMaster = getMaster();
        // Создать запрос
        WriteCoilsRequest request = new WriteCoilsRequest(slaveId, startOffset, bdata);
        // Отправьте запрос и получите объект ответа
        WriteCoilsResponse response = (WriteCoilsResponse) tcpMaster.send(request);
        if (response.isException()) {
            return false;
        } else {
            return true;
        }

    }

    /***
     * Писать[03 Holding Register(4x)] Писатьone function ID = 6
     * 
     * @param slaveId
     * @param writeOffset
     * @param writeValue
     * @return
     * @throws ModbusTransportException
     * @throws ModbusInitException
     */
    public static boolean writeRegister(int slaveId, int writeOffset, short writeValue)
            throws ModbusTransportException, ModbusInitException {
        // Получить мастера
        ModbusMaster tcpMaster = getMaster();
        // Создать объект запроса
        WriteRegisterRequest request = new WriteRegisterRequest(slaveId, writeOffset, writeValue);
        WriteRegisterResponse response = (WriteRegisterResponse) tcpMaster.send(request);
        if (response.isException()) {
            log.error(response.getExceptionMessage());
            return false;
        } else {
            return true;
        }

    }

    /**
     * 
     * Писатьвходить[03 Holding Register(4x)]Писатьмножество function ID=16
     * 
     * @param slaveId
     *            идентификатор подчиненного устройства Modbus
     * @param startOffset
     *            起始Расположениекомпенсироватьценить
     * @param sdata
     *            Писатьвходить的данные
     * @return 返回ли Писатьвходить成功
     * @throws ModbusTransportException
     * @throws ModbusInitException
     */
    public static boolean writeRegisters(int slaveId, int startOffset, short[] sdata)
            throws ModbusTransportException, ModbusInitException {
        // Получить мастера
        ModbusMaster tcpMaster = getMaster();
        // Создать объект запроса
        WriteRegistersRequest request = new WriteRegistersRequest(slaveId, startOffset, sdata);
        // Отправьте запрос и получите объект ответа
        ModbusResponse response = tcpMaster.send(request);
        if (response.isException()) {
            log.error(response.getExceptionMessage());
            return false;
        } else {
            return true;
        }
    }

    /**
     * Писатьвходить数字тип的Аналоговое количество(нравиться:ПисатьвходитьFloatтип的Аналоговое количество、Doubleтип Аналоговое количество、целое числотипShort、Integer、Long)
     * 
     * @param slaveId
     * @param offset
     * @param value
     *            Писатьвходитьценить,Подклассы числа,例нравиться ПисатьвходитьFloatс плавающей запятойтип,Doubleдвойная точностьтип,и целое число короткое,int,long
     * @param registerCount
     *            ,com.serotonin.modbus4j.code.DataType
     * @throws ModbusTransportException
     * @throws ErrorResponseException
     * @throws ModbusInitException
     */
    public static void writeHoldingRegister(int slaveId, int offset, Number value, int dataType)
            throws ModbusTransportException, ErrorResponseException, ModbusInitException {
        // Получить мастера
        ModbusMaster tcpMaster = getMaster();
        // тип
        BaseLocator<Number> locator = BaseLocator.holdingRegister(slaveId, offset, dataType);
        tcpMaster.setValue(locator, value);
    }

    public static void main(String[] args) {
        try {
            //@formatter:off
            // тест01
//            boolean t01 = writeCoil(1, 0, true);
//            System.out.println("T01:" + t01);

            // тест02
//            boolean t02 = writeCoils(1, 0, new boolean[] { true, false, true });
//            System.out.println("T02:" + t02);

            // тест03
//            short v = -3;
//            boolean t03 = writeRegister(1, 0, v);
//            System.out.println("T03:" + t03);
            // тест04
//            boolean t04 = writeRegisters(1, 0, new short[] { -3, 3, 9 });
//            System.out.println("t04:" + t04);
            //Писать Аналоговое количество
            writeHoldingRegister(1,0, 10.1f, DataType.FOUR_BYTE_FLOAT);
            
            //@formatter:on
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

}

понимание кода:

boy illustration
Неразрушающее увеличение изображений одним щелчком мыши, чтобы сделать их более четкими артефактами искусственного интеллекта, включая руководства по установке и использованию.
boy illustration
Копикодер: этот инструмент отлично работает с Cursor, Bolt и V0! Предоставьте более качественные подсказки для разработки интерфейса (создание навигационного веб-сайта с использованием искусственного интеллекта).
boy illustration
Новый бесплатный RooCline превосходит Cline v3.1? ! Быстрее, умнее и лучше вилка Cline! (Независимое программирование AI, порог 0)
boy illustration
Разработав более 10 проектов с помощью Cursor, я собрал 10 примеров и 60 подсказок.
boy illustration
Я потратил 72 часа на изучение курсорных агентов, и вот неоспоримые факты, которыми я должен поделиться!
boy illustration
Идеальная интеграция Cursor и DeepSeek API
boy illustration
DeepSeek V3 снижает затраты на обучение больших моделей
boy illustration
Артефакт, увеличивающий количество очков: на основе улучшения характеристик препятствия малым целям Yolov8 (SEAM, MultiSEAM).
boy illustration
DeepSeek V3 раскручивался уже три дня. Сегодня я попробовал самопровозглашенную модель «ChatGPT».
boy illustration
Open Devin — инженер-программист искусственного интеллекта с открытым исходным кодом, который меньше программирует и больше создает.
boy illustration
Эксклюзивное оригинальное улучшение YOLOv8: собственная разработка SPPF | SPPF сочетается с воспринимаемой большой сверткой ядра UniRepLK, а свертка с большим ядром + без расширения улучшает восприимчивое поле
boy illustration
Популярное и подробное объяснение DeepSeek-V3: от его появления до преимуществ и сравнения с GPT-4o.
boy illustration
9 основных словесных инструкций по доработке академических работ с помощью ChatGPT, эффективных и практичных, которые стоит собрать
boy illustration
Вызовите deepseek в vscode для реализации программирования с помощью искусственного интеллекта.
boy illustration
Познакомьтесь с принципами сверточных нейронных сетей (CNN) в одной статье (суперподробно)
boy illustration
50,3 тыс. звезд! Immich: автономное решение для резервного копирования фотографий и видео, которое экономит деньги и избавляет от беспокойства.
boy illustration
Cloud Native|Практика: установка Dashbaord для K8s, графика неплохая
boy illustration
Краткий обзор статьи — использование синтетических данных при обучении больших моделей и оптимизации производительности
boy illustration
MiniPerplx: новая поисковая система искусственного интеллекта с открытым исходным кодом, спонсируемая xAI и Vercel.
boy illustration
Конструкция сервиса Synology Drive сочетает проникновение в интрасеть и синхронизацию папок заметок Obsidian в облаке.
boy illustration
Центр конфигурации————Накос
boy illustration
Начинаем с нуля при разработке в облаке Copilot: начать разработку с минимальным использованием кода стало проще
boy illustration
[Серия Docker] Docker создает мультиплатформенные образы: практика архитектуры Arm64
boy illustration
Обновление новых возможностей coze | Я использовал coze для создания апплета помощника по исправлению домашних заданий по математике
boy illustration
Советы по развертыванию Nginx: практическое создание статических веб-сайтов на облачных серверах
boy illustration
Feiniu fnos использует Docker для развертывания личного блокнота Notepad
boy illustration
Сверточная нейронная сеть VGG реализует классификацию изображений Cifar10 — практический опыт Pytorch
boy illustration
Начало работы с EdgeonePages — новым недорогим решением для хостинга веб-сайтов
boy illustration
[Зона легкого облачного игрового сервера] Управление игровыми архивами
boy illustration
Развертывание SpringCloud-проекта на базе Docker и Docker-Compose