Modbus4Android

repository·master·Indexed 42 days ago

https://github.com/licheedev/modbus4android

An Android implementation of the Modbus protocol supporting TCP and Serial (RTU) communication. It provides a ModbusManager for connection lifecycle handling and supports standard callbacks, RxJava, and Kotlin Coroutines for operations such as reading holding registers. Version 3.0.0 is available via JitPack.

Tokens
2.1K
Snippets
8
Records
8
Agent score
5%

What's inside Modbus4Android

  1. Install Modbus4Android via Gradle

    master

    To use Modbus4Android, add the JitPack repository to your allprojects block and include the dependency in your dependencies block. It is recommended to exclude commons-logging to avoid conflicts.

    allprojects {
      repositories {
        ...
        maven { url 'https://jitpack.io' }
      }
    }
    
      dependencies {
        implementation('com.github.licheedev:Modbus4Android:3.0.0') {
            // 解决"commons-logging"冲突问题
            exclude group: 'commons-logging', module: 'commons-logging'
        }
    }
  2. Initialize Modbus via ModbusManager singleton

    master

    The library is best used by creating a singleton that extends ModbusWorker. This manager handles the lifecycle of the Modbus connection. You can implement a release() method to nullify the singleton instance and clean up resources.

    public class ModbusManager extends ModbusWorker {
    
        private static volatile ModbusManager sInstance;
    
        public static ModbusManager get() {
            ModbusManager manager = sInstance;
            if (manager == null) {
                synchronized (ModbusManager.class) {
                    manager = sInstance;
                    if (manager == null) {
                        manager = new ModbusManager();
                        sInstance = manager;
                    }
                }
            }
            return manager;
        }
    
        private ModbusManager() {
        }
    
        /**
         * 释放整个ModbusManager,单例会被置null
         */
        public synchronized void release() {
            super.release();
            sInstance = null;
        }
    }
  3. Open a Modbus connection (Serial or TCP)

    master

    To start communication, create a parameter object (SerialParam for RTU/Serial or TcpParam for TCP) and call init() on your ModbusManager. Always call closeModbusMaster() before re-initializing to ensure a clean state.

    // Example for Serial (RTU)
    ModbusParam param = SerialParam.create(path, baudrate)
        .setDataBits(mDataBits)
        .setParity(mParity)
        .setStopBits(mStopBits)
        .setTimeout(1000)
        .setRetries(0);
    
    // Example for TCP
    ModbusParam param = TcpParam.create(host, port)
        .setTimeout(1000)
        .setRetries(0)
        .setEncapsulated(false)
        .setKeepAlive(true);
    
    ModbusManager.get().closeModbusMaster();
    ModbusManager.get().init(param, new ModbusCallback<ModbusMaster>() {
        @Override
        public void onSuccess(ModbusMaster modbusMaster) {
            // Handle success
        }
    
        @Override
        public void onFailure(Throwable tr) {
            // Handle failure
        }
    
        @Override
        public void onFinally() {
            // Cleanup
        }
    });
  4. Configure Android Manifest for legacy HTTP support

    master

    To resolve potential commons-logging conflicts in Android, add the following library usage to your AndroidManifest.xml within the <application> tag:

    <manifest ...>
        <application ...>
            <!-- 解决"commons-logging"冲突问题 -->
            <uses-library android:name="org.apache.http.legacy" android:required="false" />
        </application>
    </manifest>
  5. Configure Modbus global settings

    master

    Use ModbusConfig to adjust global behavior such as CRC validation for RTU or enabling data logging for debugging.

    // 启用rtu的crc校验(默认就启用)
    ModbusConfig.setEnableRtuCrc(true);
    
    // 打印数据log(默认全禁用)
    ModbusConfig.setEnableDataLog(true, true);
  6. Read Holding Registers with Kotlin Coroutines

    master

    To use Coroutines, copy the ModbusWorkers.kt file from the repository to your project. Your ModbusManager should then provide await methods for seamless integration with lifecycleScope or other coroutine scopes.

    // Ensure ModbusWorkers.kt is included in your project
    lifecycleScope.launch {
        try {
            val response = ModbusManager.get().awaitReadHoldingRegisters(mSalveId, mOffset, mAmount)
            val data: ByteArray = response.data
            // Process data
        } catch (e: Exception) {
            // Handle error
        }
    }
  7. Read Holding Registers with RxJava

    master

    To use RxJava, your ModbusManager must extend RxModbusWorker. You must copy the rxjava implementation files from the repository to your project. This allows you to use rxReadHoldingRegisters and observe results on specific threads.

    // Ensure ModbusManager extends RxModbusWorker
    ModbusManager.get()
        .rxReadHoldingRegisters(mSalveId, mOffset, mAmount)
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(new ModbusObserver<ReadHoldingRegistersResponse>() {
            @Override
            public void onSuccess(ReadHoldingRegistersResponse response) {
                byte[] data = response.getData();
            }
    
            @Override
            public void onFailure(Throwable tr) {
                // Handle error
            }
        });
  8. Read Holding Registers (Standard Callback)

    master

    Use readHoldingRegisters to perform a standard Modbus function code 03 operation. The result is returned via a ModbusCallback containing a ReadHoldingRegistersResponse.

    ModbusManager.get()
        .readHoldingRegisters(mSalveId, mOffset, mAmount,
            new ModbusCallback<ReadHoldingRegistersResponse>() {
                @Override
                public void onSuccess(ReadHoldingRegistersResponse response) {
                    byte[] data = response.getData();
                    // Process data
                }
    
                @Override
                public void onFailure(Throwable tr) {
                    // Handle error
                }
    
                @Override
                public void onFinally() {
                }
            });