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

無料無料技术资料

这篇内容可直接阅读,适合用于基础学习和検索引流。

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クライアント-モノのインターネット通信 ->
    <依存関係は>
        <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 + "°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語。
この資料を実際のプロジェクトに活用しませんか?

ツールセンターで電文解析、CRCチェック、デバイスデバッグを行うか、要件を送信して選定と接続のアドバイスを受けましょう。

エンジニア会員

この記事を実行可能なデバッグ資料に

登録すると、高度な電文解析、資料パックのダウンロード、コード例、エンジニアリングケース、優先技術サポートが利用可能に。実際のプロジェクト納品に最適です。

高度なツール無制限
資料パックとコードパック
完全なエンジニアリングケースライブラリ
優先技術サポート窓口

发表回复

あなたのメールアドレスアドレス不会被公开。 必須項目已用 * 标注