Java Modbus開発完全ガイド:エンタープライズクラスの産業用アプリケーションの構築

freeFree Technical Resource

This content is free to read, suitable for basic learning and search traffic.

Java Modbus開発完全ガイド:エンタープライズクラスの産業用アプリケーションの構築

Java Modbus開発完全ガイド:エンタープライズクラスの産業用アプリケーションの構築

産業オートメーションにおけるJavaの利点

Javaは、そのクロスプラットフォーム機能、強力な型システム、豊富なエンタープライズクラスのクラスライブラリ、成熟したエコシステムにより、産業オートメーションの世界で重要な地位を占めています。大規模なSCADAシステムから組み込みゲートウェイデバイスまで、Javaは完全なソリューションスタックを提供し、高信頼性、高性能、長期メンテナンスを必要とするエンタープライズクラスの産業用アプリケーションに特に適しています。 この記事では、Modbus 4 J、jamod、j 2 modなどの主流ライブラリの使用に焦点を当て、Spring BootやMQTTなどの最新のテクノロジースタックと組み合わせて、プロフェッショナルグレードの産業用IoTシステムを構築する方法を示します。

Java Modbus開発環境の設定

1.1開発環境の要件

<!-- Mavenプロジェクトの構成-->
<Project Projectプロジェクト>
    <modelVersion 4.0.0/modelVersion>
    <groupId com.example/groupId>
    <artifactId industrial-modbus/artifactId>
    <バージョン1.0.0/バージョン>
    <properties>
        <maven. compiler.source 17/maven. compiler.source>
        <maven.compiler.target 17/maven.compiler.target>
        <project.build.sourceEncoding UTF-8/project.build.sourceEncoding>
    </properties>
<プロジェクト/Project>

1.2コア依存構成

<dependencies>
    <!-- Modbus 4 J-最も包括的なModbusライブラリ->
    <依存関係は>
        <groupId com.infiniteautomation/groupId>
        <artifactId modbus4j/artifactId>
        <バージョン3.4/バージョン>
    </dependency>

    <!-- j 2 mod-モダンで軽量なオプション->
    <依存関係は>
        <groupId com.gande/groupId>
        <artifactId j 2 mod/artifactId>
        <バージョン3.1.4とバージョン>
    </dependency>

    <!-- Spring Boot-エンタープライズアプリケーションのフレームワーク>
    <依存関係は>
        <groupId. ingframework.boot/groupId>
        <artifactId spring-boot-starter-web/artifactId>
        <バージョン3.2.0/バージョン>
    </dependency>

    <!-- MQTTクライアント-モノのインターネットCommunication ->
    <依存関係は>
        <groupId.eclipse.paho/groupId>
        <artifactId org.eclipse.paho.client.mqttv3/artifactId>
        <バージョン1.2.5/バージョン>
    </dependency>
</依存関係>

2.主流のJava Modbusライブラリの比較

2.1 Modbus 4 J:エンタープライズクラスの選択肢

特徴:- すべてのModbus関数コードをサポートする最も包括的な機能 - TCP、RTU、ASCIIのすべての転送モードをサポート - マスターモードとスレーブモードの両方に対応 - アクティブなコミュニティメンテナンスInfinite Automation - 完璧な例外処理とログシステム適用シーン:- 大規模SCADAシステム - エンタープライズレベルの産業監視プラットフォーム - 高い信頼性を必要とする本番

2.2 J 2 mod:軽量ソリューションの近代化

特徴:- シンプルなコードとモダンなAPIデザイン - Modbus TCPおよびRTUのサポート - 軽量で依存性が低い - マイクロサービスアーキテクチャに適合適用シーン:- マイクロサービスアーキテクチャの産業応用 - リソースに制約のある組み込み機器 - ラピッドプロトタイピング

2.3 Jamod:安定した選択

特徴:- 長い歴史と安定性 - ネイティブ依存のない純粋なJava実装 - 充実したドキュメント、豊富な例 - 高いコミュニティ活動適用シーン:- 従来型産業システムのアップグレード - 教育と学習の利用 - 長期安定支援が必要なプロジェクト

Modbus 4 Jの開発

3.1 Modbus TCPクライアントの実装

package com.example.modbus;

import com.serotonin.modbus4j.modbusFactory;
import com.serotonin.modbus4j.ModbusMaster;
import com.serotonin.modbus4j.ip.t.T;
import com.serotonin.modbus4j.exception.modbusInitException;

public class modbusTcpClient {

    プライベートファイナルモドバスマスター;

    public ModbusTcpClient String host int port {
        ModbusFactory = new ModbusFactory;
        Tparams = new T;
        params.setHost host;
        params.setPort port;
        params.setKeepAlive true;

        master = factory.createTcpMaster params true;
        master.setRetries 3;
        master.setExceptionListeners new ExceptionListenerImpl;
    }

    public start throws ModbusInitException {
        master.init;
        System.out.println "Modbus TCP接続が確立されました";
    }

    public short readHoldingRegister int slaveId int offset {
        return master.readHoldingRegister slaveId offset.getValue;
    }

    public int[] readHoldingRegisters int slaveId int offset int count {
        return master.readHoldingRegisters slaveId offset count.getValue;
    }

    public void writeRegister int slaveId int offset short value {
        master.writeRegister slaveId、offset、value;
    }

    public void stop {
        master.destroy;
    }

    // 使用事例
    public static main String[] s {
        Try {
            ModbusTcpClientクライアント= new ModbusTcpClient "192.16 8.1。100"502;
            client.start;

            //保持レジスタの読み込み
            short temperature = client.readHoldingRegister 1 0;
            System. out.println "temperature" + temperature + "°C";

            //バッチ読み取り
            int[] values = client.readHoldingRegisters 1 0 10;
            for int i = 0; i val.; i++{
                System.out."レジスタ" + i +"" + val [i];
            }

            //レジスタへの書き込み
            client.writeRegister 1 0 short 250;

            client.stop nClose;
        } catch Exception e {
            e. Stack;
        }
    }
}

3.2 Modbus RTUクライアントの実装

package com.example.modbus;

import com.serotonin.modbus4j.modbusFactory;
import com.serotonin.modbus4j.ModbusMaster;
import com.serotonin.modbus 4j.serial.rtu.RtuParameters;

public class modbusRtuClient {

    プライベートファイナルモドバスマスター;

    public ModbusRtuClient String serialPort int baudRate {
        ModbusFactory = new ModbusFactory;
        RtuParameters = new RtuParameters;
        params.setCommPortId serialPort; //例:“/dev/ttyUSB0”または“COM3”
        params. setBaudb;
        params.setStopBits 1;
        params.setParity 0; // 0=、1=Odd、2=Even
        params.setFlowControlIn 0;
        params.setFlowControlOut 0;

        master = factory.createRMaster params;
        master.setRetries 3;
        master.setTimeout 500;
    }

    public void start throws Exception {
        master.init;
        System.out.println "Modbus RTU接続が確立されました";
    }

    public short readInputRegister int slaveId int offset {
        return master.readInputRegister slaveId offset.getValue;
    }

    public booreadCoil int slId int {
        return master.readCoil slaveId offset.getValue;
    }

    public void writeCoil int slaveId int offset boolean value {
        master.writeCoil slaveId offset value;
    }

    public void stop {
        master.destroy;
    }
}

3.3 Modbusスレーブサーバ実装

package com.example.modbus;

import com.serotonin.modbus4j.modbusFactory;
import com.serotonin.modbus4j.ModbusMaster;
import com.serotonin.modbus4j.ip.t.T;
import com.serotonin.modbus4j.slave.modbusSlave;
import com.serotonin.modbus4j.slave.SlaveEventListener;

パブリッククラスModbusServer {

    プライベート·モドブス·スレーブ

    public void start int port throws Exception {
        ModbusFactory = new ModbusFactory;
        Tparams = new T;
        params.setHost "0.0.0.0";
        params.setPort port;

        slave = factory.createTcpSlave params true;
        slave.setEventListener new SlaveEventListenerImpl;
        slave.addProcessImage 1 new ModbusProcessImageImpl;

        slave.start nCloth nCloth;
        System. out.println "Modbusサーバーが起動しました。リスニングポート" + port;
    }

    public void stop {
        if Slave != NULL {
            slave.stop nCloth nCloth;
        }
    }
}

4. Spring Bootの統合

4.1プロジェクトの構造

src/main/java/com/example/industrial/
├── IndustrialApplication.java
├── config/
│   └── ModbusConfig.java
├── service/
│   ├── ModbusService.java
│   └── DataProcessingService.java
├── controller/
│   └── ModbusController.java
└── model/
    └── DeviceData.java

4.2 Modbus構成クラス

package com.example.industrial.config;

import com.example.industrial.service.ModbusService;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class ModbusConfig {

    @Bean
    public ModbusService modbusService() {
        return new ModbusService("192.168.1.100", 502);
    }
}

4.3 Modbusサービス層

package com.example.industrial.service;

import com.example.modbus.ModbusTcpClient;
import com.example.industrial.model.DeviceData;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.util.ArrayList;
import java.util.List;

@Service
public class ModbusService {

    private ModbusTcpClient client;
    private final String host;
    private final int port;

    public ModbusService(String host, int port) {
        this.host = host;
        this.port = port;
    }

    @PostConstruct
    public void init() {
        client = new ModbusTcpClient(host, port);
        try {
            client.start();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @PreDestroy
    public void destroy() {
        if (client != null) {
            client.stop();
        }
    }

    public DeviceData readDeviceData(int slaveId) {
        DeviceData data = new DeviceData();
        data.setDeviceId(slaveId);
        data.setTemperature(client.readHoldingRegister(slaveId, 0));
        data.setHumidity(client.readHoldingRegister(slaveId, 1));
        data.setPressure(client.readHoldingRegister(slaveId, 2));
        data.setTimestamp(System.currentTimeMillis());
        return data;
    }

    public List<DeviceData> readAllDevices(int startId, int count) {
        List<DeviceData> devices = new ArrayList<>();
        for (int i = 0; i < count; i++) {
            devices.add(readDeviceData(startId + i));
        }
        return devices;
    }

    public void writeSetpoint(int slaveId, short value) {
        client.writeRegister(slaveId, 100, value);
    }
}

4.4 REST APIコントローラ

package com.example.industrial.controller。

import com.example. industrial.model.DeviceData;
import com.example. industrial.service.ModbusService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation. *;

import java.util.List;

@RestController
@RequestMapping("/api/modbus")
@CrossOrigin origins = "*"
public class modbus Controller {

    Auto
    プライベートモジュールバスサービス;

    GetM
    public DeviceData getDeviceData @PathVariable int slaveId {
        return modbusService.readDeviceData slaveId;
    }

    GetM
    public List DeviceData getAllDevices
        @RequestParam defaultValue = "1" int startId
        @RequestParam defaultValue = "10" int count
    ) {
        return modbusService.readAllDevices startId count;
    }

    PostM
    public String eSetpoint
        @PathVariable int slaveId、
        @RequestParam short value
    ) {
        modbusService.writeSetpoint slaveId value;
        return "セットポイントが更新された";
    }
}

4.5データモデル

package com.example.industrial.model;

import lombok.Data;

@Data
public class DeviceData {
    private int deviceId;
    private short temperature;
    private short humidity;
    private short pressure;
    private long timestamp;
}

V.高度なアプリケーションシナリオ

5.1非同期データ収集

package com.example.industrial.service;

import java.util.concurrent. *;
Java. util.function.Consumerのインポート

public class AsyncDataCollector {

    Private Final ScheduledExecutorService Schedulerの略。 
        Executors.uThread4;

    プライベート·ファイナンス·モジュバス·サービス

    public AsyncDataCollector ModbusService modbusService {
        modbus Service = modbus Service;
    }

    public void startPeriodicCollection int slaveId long interval 
                                        mer
        scheduler.scheduleAtFixedRate-{
            Try {
                DeviceData data = modbusService.readDeviceData slaveId;
                callback.data;
            } catch Exception e {
                System. err.println "データ収集に失敗しました" + e.getMessage;
            }
        } 0 interval TimeUnit.MILLISECONDS;
    }

    public void stop {
        scheduler.shutdown;
    }
}

5.2データキャッシュとバッチ処理

package com.example.industrial.service;

import java.util.concurrent.ConcurrentHashMap;
Java. util.concurrent.TimeUnit;

public class DataCacheService {

    private final concurrentHashMap Integer、DeviceData cache = 
        new ConHashMap;

    private final long cacheTimeout = 5,000; // 5 秒

    public Data getCachedData int slId {
        DeviceData data = cache.get slaveId;
        if Data != Null&& 
            System.currentTimeMillis-data.getTimestamp cacheTimeout {
            データのリターン;
        }
        nullを返す;
    }

    public void updateCache DeviceData data {
        cache.put data.getDeviceId data;
    }

    public cleanup {
        long now = System.currentTimeMillis;
        cache.entrySet. removeIf entry -> 
            now - entry.getValue.getTimestamp cacheTimeout
        );
    }
}

5.3例外処理と再試行メカニズム

package com.example.industrial.service;

import com.serotonin.modbus4j.exception.modbusException;
インポートorg.slf4j. Logger;
import org.slf4j.LoggerFactory;

public class ResilientModbus Service {

    private static final Logger logger = LoggerFactory.getLogger
        ResilientModbusService.class
    );

    プライベート·ファイナル·モジュラス·サービス·デリバリー
    private final int maxRetries = 3;
    private final long retryDelay = 1000;

    public ResilientModbusService ModbusService delegate {
        delegate = delegate;
    }

    public DeviceData readWithRetry int slaveId throws Exception {
        int attempts = 0;
        while attts Ret {
            Try {
                return delegate.readData slId;
            catch ModbusException e {
                Attempts++;
                logger.warn "読み取りに失敗しました。再試行{}/{}" attempts maxRetries;
                if attempts = maxRetries {
                    略称はE。
                }
                Thread.sleep retryDelay Thread.sleep retryDelay;
            }
        }
        throw new Exception "最大再回数";
    }
}

六、パフォーマンス最適化のベストプラクティス

6.1接続プールの管理

package com.example.industrial.pool;

import org.apache.commons.pool2.impl.GenericObjectPool;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;

public class ModbusConnectionPool {

    private final GenericObjectPool<ModbusTcpClient> pool;

    public ModbusConnectionPool(String host, int port, int maxConnections) {
        GenericObjectPoolConfig<ModbusTcpClient> config = 
            new GenericObjectPoolConfig<>();
        config.setMaxTotal(maxConnections);
        config.setMaxIdle(maxConnections);
        config.setMinIdle(2);
        config.setTestOnBorrow(true);

        pool = new GenericObjectPool<>(
            new ModbusClientFactory(host, port), 
            config
        );
    }

    public ModbusTcpClient borrowClient() throws Exception {
        return pool.borrowObject();
    }

    public void returnClient(ModbusTcpClient client) {
        pool.returnObject(client);
    }

    public void close() {
        pool.close();
    }
}

6.2バッチ読み取り最適化

//最適化前:複数の別々の読み取り
for int i = 0; i 100; i+++{
    short value = master.readHoldingRegister slaveId i.getValue;
}

//最適化後:1回のバッチ読み取り
short[] values = master.readHoldingRegisters slaveId 0 100.getValue;

6.3タイムアウト構成の最適化

//ネットワーク環境に応じてタイムアウト時間を調整する
master.setTimeout 500; //ローカルネットワーク
master.setTimeout 2000; //リモートネットワーク
master.setRetries 3;    //再試行回数

VII.セキュリティと監視

7.1アクセス制御

package com.example.industrial.security;

import java.util.HashSet;
import java.util.Set;

public class ModbusAccessControl {

    private final Set<Integer> allowedSlaves = new HashSet<>();
    private final Set<Integer> readOnlyRegisters = new HashSet<>();

    public void allowSlave(int slaveId) {
        allowedSlaves.add(slaveId);
    }

    public boolean isSlaveAllowed(int slaveId) {
        return allowedSlaves.contains(slaveId);
    }

    public void markReadOnly(int registerOffset) {
        readOnlyRegisters.add(registerOffset);
    }

    public boolean isReadOnly(int registerOffset) {
        return readOnlyRegisters.contains(registerOffset);
    }
}

7.2オペレーションログ

package com.example.industrial.logging;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class ModbusOperationLogger {

    private static final Logger logger = LoggerFactory.getLogger(
        ModbusOperationLogger.class
    );

    public void logRead(int slaveId, int register, Object value) {
        logger.info("READ | Slave={} Register={} Value={}", 
            slaveId, register, value);
    }

    public void logWrite(int slaveId, int register, Object value) {
        logger.warn("WRITE | Slave={} Register={} Value={}", 
            slaveId, register, value);
    }

    public void logError(int slaveId, String operation, Exception e) {
        logger.error("ERROR | Slave={} Operation={} Error={}", 
            slaveId, operation, e.getMessage());
    }
}

八、実戦事例:産業データ収集システム

8.1システムアーキテクチャ

�������������     ‥ ― ― ― ― ― ― ― ― ― ―     �������������
● PLC機器     │----│ Modbusゲートウェイ   │----│ Javaアプリケーション    │ │ │
│駅から。      │ │ │     │(TCP/RTU)    │ │ │     │メイン駅↓      │ │ │
3-------------------     その― ― ― ― ― ― ― ― ― ― ― ― ― ―     3-------------------
                                              │ │ │
                                              ▼ ▼ ▼
                                       �������������
                                       │データベースです。       │ │ │
                                       │ MySQL     │ │ │
                                       3-------------------

8.2完全な実装コード

package com.example.industrial;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;

@SpringBootApplication
@EnableScheduling
public class IndustrialApplication {

    public static void main(String[] args) {
        SpringApplication.run(IndustrialApplication.class, args);
    }
}

9.よくある問題と解決策

9.1接続タイムアウトの問題

質問:Modbusデバイスの応答が遅いためタイムアウト解決策:
master.setTimeout(2000); //タイムアウト時間の増加
master.setRetries 3;     //再試行回数を増やす

9.2データの不整合

質問:読み取られたデータに時折異常値が発生する解決策:
//データ検証の追加
public short readValidatedRegister int slaveId int offset {
    short value = master.readHoldingRegister slaveId offset.getValue;
    if value<-1000|| value> 10000 {
        throw new RuntimeException "データが妥当な範囲外です";
    }
    リターンの価値;
}

9.3メモリリークの問題

質問:長時間の実行後にメモリ使用量が増加し続ける解決策:
定期的にキャッシュをクリーンアップ
@Scheduled fixedRate = 300000//5分ごと
public void cleanupCache {
    cacheService.cleanup;
}

接続を正しく閉じる。
@PreDestroy
public void destroy {
    if master != NULL {
        master.destroy;
    }
}

X.概要と展望

10.1 Java Modbus開発の利点

  1. クロスプラットフォーム性一度書くとどこでも走る。
  2. エンタープライズレベルのサポート:成熟したフレームワークとライブラリエコロジー
  3. 優れたパフォーマンスJVM最適化による高性能化
  4. メンテナンス可能性強い型付けと良いコード編成
  5. アクティブなコミュニティ:豊富な学習リソースと技術サポート

10.2技術選択の推奨事項

シーンはこちらおすすめの図書館理由は
エンタープライズレベルのアプリケーションModbus4Jフル機能、安定性
マイクロサービスはj2mod軽量でモダンなAPI
ラーニング/Teachingjamod充実したドキュメント、豊富な例
高いパフォーマンスをModbus 4 J+接続プール同時性とプールのサポート

10.3今後の方向性

  1. クラウドネイティブ統合Kubernetes、Dockerとの深い統合
  2. エッジコンピューティングエッジデバイスでModbusサービスを実行する
  3. AIの融合機械学習と予測保全の組み合わせ
  4. セキュリティの強化TLS/SSL暗号化通信のサポート

付録:クイックリファレンス

A.1 Maven依存性クイックチェック

<!-- Modbus4J -->
<dependency>
    <groupId>com.infiniteautomation</groupId>
    <artifactId>modbus4j</artifactId>
    <version>3.4.0</version>
</dependency>

<!-- j2mod -->
<dependency>
    <groupId>com.ghgande</groupId>
    <artifactId>j2mod</artifactId>
    <version>3.1.4</version>
</dependency>

A.2共通機能コード

関数コードの特徴機能性は説明書は
01リードコイルを読む読み取りスイッチ量出力
02離散入力の読み取り読み取りスイッチ量入力
03リードホールドレジスタアナログ出力の読み取り
04読み取り入力レジスタアナログ入力の読み取り
05シングルコイルを書く。スイッチ出力の制御
06単一レジスタの書き込みアナログ出力の制御
15複数のコイルを書く。バッチ制御
16複数のレジスタを書く。バッチ設定

A.3リソースへのリンク

  • Modbus4J GitHub: https://github.com/serotonin/modbus4j
  • j2mod GitHub: https://github.com/ghgande/j2mod
  • Spring Boot: https://spring.io/projects/spring-boot
  • Modbusの仕様: https://modbus.org/specs.php

キーワード:keywordsJava Modbus、Modbus 4 J、産業用モノのインターネット、エンタープライズアプリケーション、Spring Boot、データ収集、オートメーション制御単語の数約8,500語。
Put this resource to use in a real project?

Go to the Tool Center for message parsing, CRC verification and device debugging, or submit your requirements for selection and integration advice.

Engineer Membership

Turn this article into actionable debugging resources

After activation, you can use advanced message parsing, resource pack downloads, code examples, engineering cases and priority technical support, suitable for real project delivery.

Unlimited Advanced Tools
Resource & Code Packs
Complete Engineering Case Library
Priority Technical Support

Leave a Reply

Your email address will not be published. Required fields are marked *.