- 添加依赖
implementation 'com.github.MangoAutomation:modbus4j:3.1.0'
implementation 'com.github.licheedev:Android-SerialPort-API:2.0.0'
- 添加maven仓库
maven { url 'https://www.jitpack.io' }
- modbus4j实现
modbus4j的SerialPortWrapper接口没有实现类,所以我们需要新建一个类继承 SerialPortWrapper ,用于实现在安卓上的串口功能:
import android.serialport.SerialPort;
import android.util.Log;
import com.serotonin.modbus4j.serial.SerialPortWrapper;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class SerialPortWrapperImpl implements SerialPortWrapper {
private static final String TAG = "SerialPortWrapper";
private SerialPort mSerialPort = null;
private InputStream inputStream = null;
private OutputStream outputStream = null;
private String device;
private int baudRate;
private int dataBits;
private int stopBits;
private int parity;
public SerialPortWrapperImpl(String device, int baudRate, int dataBits, int stopBits, int parity) {
this.device = device;
this.baudRate = baudRate;
this.dataBits = dataBits;
this.stopBits = stopBits;
this.parity = parity;
}
@Override
public void open() throws Exception{
File fdevice = new File(device);
if (!fdevice.canRead() || !fdevice.canWrite()) {
Log.w(TAG, "File cant rw!");
}
try {
mSerialPort = SerialPort
.newBuilder(fdevice, baudRate)
.dataBits(dataBits)
.stopBits(stopBits)
.parity(parity)
.build();
if (mSerialPort != null) {
Log.i(TAG, "SerialPort open success");
this.inputStream = mSerialPort.getInputStream();
this.outputStream = mSerialPort.getOutputStream();
} else {
Log.e(TAG, "SerialPort open fail");
}
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void close() throws Exception {
try {
if (this.inputStream != null) {
inputStream.close();
}
if (this.outputStream != null) {
outputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
try{
if (mSerialPort != null) {
mSerialPort.close();
mSerialPort = null;
}
}catch (Exception e){
Log.e(TAG,"串口对象关闭异常:" +e.toString());
}
}
@Override
public InputStream getInputStream() {
return inputStream;
}
@Override
public OutputStream getOutputStream() {
return outputStream;
}
@Override
public int getBaudRate() {
return baudRate;
}
@Override
public int getDataBits() {
return dataBits;
}
@Override
public int getStopBits() {
return stopBits;
}
@Override
public int getParity() {
return parity;
}
}
- 主程序调用,这里以读取保存寄存器为例
SerialPortWrapper serialParameters = new SerialPortWrapperImpl("/dev/ttyS0", 115200, 8, 1, 0);
ModbusFactory modbusFactory = new ModbusFactory();
ModbusMaster master = modbusFactory.createRtuMaster(serialParameters);
try {
master.setTimeout(3000);
master.setRetries(3);
master.init();
Integer addr = Integer.parseInt("9001", 16);
ReadHoldingRegistersRequest request = new ReadHoldingRegistersRequest(1, addr.intValue(), 1);
ReadHoldingRegistersResponse response = (ReadHoldingRegistersResponse)master.send(request );
if (response.isException()) {
Log.e(TAG, "Exception response:" + response.getExceptionMessage());
} else {
short[] list = response.getShortData();
for (int i = 0; i < list.length; i++) {
Log.i(TAG, list[0]);
}
}
}catch (ModbusInitException e) {
e.printStackTrace();
}finally {
master.destroy();
}
- serialport打开文件时,需要文件权限可读写,如果不是,会修改文件权限,注意这里需要root权限,需要手动切su,否则会在waitfor()函数处卡死
if (!device.canRead() || !device.canWrite()) {
try {
Process su;
su = Runtime.getRuntime().exec(sSuPath);
String cmd = "chmod 666 " + device.getAbsolutePath() + "\n" + "exit\n";
su.getOutputStream().write(cmd.getBytes());
if ((su.waitFor() != 0) || !device.canRead() || !device.canWrite()) {
throw new SecurityException();
}
} catch (Exception e) {
e.printStackTrace();
throw new SecurityException();
}
}