安卓平台串口通讯实现,Modbus-rtu模式

  1. 添加依赖
/* 在app下的build.gradle 中的 dependencies 中添加如下依赖 */
implementation 'com.github.MangoAutomation:modbus4j:3.1.0'
implementation 'com.github.licheedev:Android-SerialPort-API:2.0.0'
  1. 添加maven仓库
/* 在settings.gradle 中的 repositories 中添加如下maven仓库*/
maven { url 'https://www.jitpack.io' }
  1. 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) // 数据位,默认8;可选值为5~8
                    .stopBits(stopBits) // 停止位,默认1;1:1位停止位;2:2位停止位
                    .parity(parity) // 校验位;0:无校验位(NONE,默认);1:奇校验位(ODD);2:偶校验位(EVEN)
                    .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;
    }
}
  1. 主程序调用,这里以读取保存寄存器为例
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();
 }
  1. serialport打开文件时,需要文件权限可读写,如果不是,会修改文件权限,注意这里需要root权限,需要手动切su,否则会在waitfor()函数处卡死
if (!device.canRead() || !device.canWrite()) {
   try {
       /* Missing read/write permission, trying to chmod the file */
       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();
   }
}
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值