Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

基于modbus4j的Modbus的Android实现,添加对Android串口(RTU)的支持

Notifications You must be signed in to change notification settings

licheedev/Modbus4Android

Open more actions menu

Repository files navigation

Modbus4Android

Modbus的Android实现,添加对Android串口(RTU)的支持

APP TCP

不了解Modbus的,可以阅读一下 MODBUS通讯协议

参考

https://github.com/infiniteautomation/modbus4j

https://github.com/zgkxzx/Modbus4Android

使用

添加依赖

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'
    }
}
<manifest ...>
    <application ...>
        <!-- 解决"commons-logging"冲突问题 -->
        <uses-library android:name="org.apache.http.legacy" android:required="false" />
    </application>
</manifest>

创建管理类单例

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;
    }
}

开启设备

ModbusParam param;

if (mMode == MODE_SERIAL) {
    // 串口
    String path = mDevicePaths[mDeviceIndex];
    int baudrate = mBaudrates[mBaudrateIndex];

    mDeviceConfig.updateSerialConfig(path, baudrate);
    param = SerialParam.create(path, baudrate) // 串口地址和波特率
        .setDataBits(mDataBits) // 数据位
        .setParity(mParity) // 校验位
        .setStopBits(mStopBits) // 停止位
        .setTimeout(1000).setRetries(0); // 不重试
} else {
    // TCP
    String host = mEtHost.getText().toString().trim();
    int port = 0;
    try {
        port = Integer.parseInt(mEtPort.getText().toString().trim());
    } catch (NumberFormatException e) {
        //e.printStackTrace();
    }
    param = TcpParam.create(host, port)
        .setTimeout(1000)
        .setRetries(0)
        .setEncapsulated(false)
        .setKeepAlive(true);
}

ModbusManager.get().closeModbusMaster(); // 先关闭一下
ModbusManager.get().init(serialParam, new ModbusCallback<ModbusMaster>() {
    @Override
    public void onSuccess(ModbusMaster modbusMaster) {
        showOneToast("打开成功");
    }

    @Override
    public void onFailure(Throwable tr) {
        showOneToast("打开失败");
    }

    @Override
    public void onFinally() {
        // todo updateDeviceSwitchButton();
    }
});

可选配置

// 启用rtu的crc校验(默认就启用)
ModbusConfig.setEnableRtuCrc(true);
// 打印数据log(默认全禁用)
// System.out: MessagingControl.send: 01030000000305cb
// System.out: MessagingConnection.read: 010306000100020000bd75
ModbusConfig.setEnableDataLog(true, true);

功能码操作示例

普通用法

// 普通写法
ModbusManager.get()
    .readHoldingRegisters(mSalveId, mOffset, mAmount,
        new ModbusCallback<ReadHoldingRegistersResponse>() {
            @Override
            public void onSuccess(
                ReadHoldingRegistersResponse readHoldingRegistersResponse) {
                byte[] data = readHoldingRegistersResponse.getData();
                mTvConsole.append("F03读取:" + ByteUtil.bytes2HexStr(data) + "\n");
            }

            @Override
            public void onFailure(Throwable tr) {
                appendError("F03", tr);
            }

            @Override
            public void onFinally() {

            }
        });

其他功能码的用法,可以参考Demo的MainActivity.java

RxJava用法(2.0,其他版本按需修改)

复制rxjava相关文件到自己的项目中

// 修改实现方式
//public class ModbusManager extends ModbusWorker {}
public class ModbusManager extends RxModbusWorker {}

// Rx写法
ModbusManager.get()
    .rxReadHoldingRegisters(mSalveId, mOffset, mAmount)
    .observeOn(AndroidSchedulers.mainThread())
    .compose(this.<ReadHoldingRegistersResponse>bindUntilEvent(ActivityEvent.DESTROY))
    .subscribe(new ModbusObserver<ReadHoldingRegistersResponse>() {
        @Override
        public void onSuccess(
            ReadHoldingRegistersResponse readHoldingRegistersResponse) {
            byte[] data = readHoldingRegistersResponse.getData();
            mTvConsole.append("F03读取:" + ByteUtil.bytes2HexStr(data) + "\n");
        }

        @Override
        public void onFailure(Throwable tr) {
            appendError("F03", tr);
        }
    });

Kotlin协程用法

复制ModbusWorkers.kt文件到自己的项目中

// 协程写法
lifecycleScope.launch {
    try {
        val response =
            ModbusManager.get().awaitReadHoldingRegisters(mSalveId, mOffset, mAmount)
        val data: ByteArray = response.data
        appendText("F03读取:" + ByteUtil.bytes2HexStr(data) + "\n")
    } catch (e: Exception) {
        appendError("F03", e)
    }
}

截图

F01 F02 F03 F04 F05 F06 F15 F16

About

基于modbus4j的Modbus的Android实现,添加对Android串口(RTU)的支持

Resources

Stars

Watchers

Forks

Packages

No packages published
Morty Proxy This is a proxified and sanitized view of the page, visit original site.