Modbus的Android实现,添加对Android串口(RTU)的支持
不了解Modbus的,可以阅读一下 MODBUS通讯协议
参考
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-libraryandroid:name="org.apache.http.legacy"android:required="false" /> </application> </manifest>publicclassModbusManagerextendsModbusWorker{privatestaticvolatileModbusManagersInstance; publicstaticModbusManagerget(){ModbusManagermanager = sInstance; if (manager == null){synchronized (ModbusManager.class){manager = sInstance; if (manager == null){manager = newModbusManager(); sInstance = manager} } } returnmanager} privateModbusManager(){} /** * 释放整个ModbusManager,单例会被置null */publicsynchronizedvoidrelease(){super.release(); sInstance = null} }ModbusParamparam; if (mMode == MODE_SERIAL){// 串口Stringpath = mDevicePaths[mDeviceIndex]; intbaudrate = mBaudrates[mBaudrateIndex]; mDeviceConfig.updateSerialConfig(path, baudrate); param = SerialParam.create(path, baudrate) // 串口地址和波特率 .setDataBits(mDataBits) // 数据位 .setParity(mParity) // 校验位 .setStopBits(mStopBits) // 停止位 .setTimeout(1000).setRetries(0); // 不重试 } else{// TCPStringhost = mEtHost.getText().toString().trim(); intport = 0; try{port = Integer.parseInt(mEtPort.getText().toString().trim())} catch (NumberFormatExceptione){//e.printStackTrace(); } param = TcpParam.create(host, port) .setTimeout(1000) .setRetries(0) .setEncapsulated(false) .setKeepAlive(true)} ModbusManager.get().closeModbusMaster(); // 先关闭一下ModbusManager.get().init(serialParam, newModbusCallback<ModbusMaster>(){@OverridepublicvoidonSuccess(ModbusMastermodbusMaster){showOneToast("打开成功")} @OverridepublicvoidonFailure(Throwabletr){showOneToast("打开失败")} @OverridepublicvoidonFinally(){// todo updateDeviceSwitchButton(); } });// 启用rtu的crc校验(默认就启用)ModbusConfig.setEnableRtuCrc(true); // 打印数据log(默认全禁用)// System.out: MessagingControl.send: 01030000000305cb// System.out: MessagingConnection.read: 010306000100020000bd75ModbusConfig.setEnableDataLog(true, true);// 普通写法ModbusManager.get() .readHoldingRegisters(mSalveId, mOffset, mAmount, newModbusCallback<ReadHoldingRegistersResponse>(){@OverridepublicvoidonSuccess( ReadHoldingRegistersResponsereadHoldingRegistersResponse){byte[] data = readHoldingRegistersResponse.getData(); mTvConsole.append("F03读取:" + ByteUtil.bytes2HexStr(data) + "\n")} @OverridepublicvoidonFailure(Throwabletr){appendError("F03", tr)} @OverridepublicvoidonFinally(){} });其他功能码的用法,可以参考Demo的MainActivity.java
复制rxjava相关文件到自己的项目中
// 修改实现方式//public class ModbusManager extends ModbusWorker{}publicclassModbusManagerextendsRxModbusWorker{} // Rx写法ModbusManager.get() .rxReadHoldingRegisters(mSalveId, mOffset, mAmount) .observeOn(AndroidSchedulers.mainThread()) .compose(this.<ReadHoldingRegistersResponse>bindUntilEvent(ActivityEvent.DESTROY)) .subscribe(newModbusObserver<ReadHoldingRegistersResponse>(){@OverridepublicvoidonSuccess( ReadHoldingRegistersResponsereadHoldingRegistersResponse){byte[] data = readHoldingRegistersResponse.getData(); mTvConsole.append("F03读取:" + ByteUtil.bytes2HexStr(data) + "\n")} @OverridepublicvoidonFailure(Throwabletr){appendError("F03", tr)} });复制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) } }








