java对接Modbus

一、Modbus含义

Modbus是一种单主站的主/从通信模式,它定义了一种通讯规范,用于在工业自动化系统中实现设备之间的数据交换。Modbus网络上只能有一个主站存在,主站在Modbus网络上没有地址,而从站的地址范围为0-247,其中0为广播地址,从站的实际地址范围为1-247。

Modbus通信协议可以通过多种传输方式传播,如RS232C、RS485、光纤和无线电等。它具有两种串行传输模式,即ASCII和RTU,它们定义了数据如何打包和解码的方式。一般来说,支持Modbus协议的设备都会支持RTU格式,通信双方必须同时支持这两种模式中的一种。

总结来说,Modbus是一种用于工业自动化系统的通信协议,它定义了通信格式和规范,可以通过不同的传输方式进行数据交换

二、Java如何对接Modbus

        1、读取数据

public class Modbus4jUtils {
	/**
	 * 工厂。
	 */
	static ModbusFactory modbusFactory;
	static {
		if (modbusFactory == null) {
			modbusFactory = new ModbusFactory();
		}
	}

	/**
	 * 获取master
	 * 
	 * @return
	 * @throws ModbusInitException
	 */
	public static ModbusMaster getMaster() throws ModbusInitException {
		IpParameters params = new IpParameters();
		params.setHost("你的硬件ip");
		params.setPort("端口号");
		//
		// modbusFactory.createRtuMaster(wapper); //RTU 协议
		// modbusFactory.createUdpMaster(params);//UDP 协议
		// modbusFactory.createAsciiMaster(wrapper);//ASCII 协议
		ModbusMaster master = modbusFactory.createTcpMaster(params, false);// TCP 协议
		master.init();

		return master;
	}

	/**
	 * 读取[01 Coil Status 0x]类型 开关数据
	 * 
	 * @param slaveId
	 *            slaveId
	 * @param offset
	 *            位置
	 * @return 读取值
	 * @throws ModbusTransportException
	 *             异常
	 * @throws ErrorResponseException
	 *             异常
	 * @throws ModbusInitException
	 *             异常
	 */
	public static Boolean readCoilStatus(int slaveId, int offset)
			throws ModbusTransportException, ErrorResponseException, ModbusInitException {
		// 01 Coil Status
		BaseLocator<Boolean> loc = BaseLocator.coilStatus(slaveId, offset);
		Boolean value = getMaster().getValue(loc);
		return value;
	}

	/**
	 * 读取[02 Input Status 1x]类型 开关数据
	 * 
	 * @param slaveId
	 * @param offset
	 * @return
	 * @throws ModbusTransportException
	 * @throws ErrorResponseException
	 * @throws ModbusInitException
	 */
	public static Boolean readInputStatus(int slaveId, int offset)
			throws ModbusTransportException, ErrorResponseException, ModbusInitException {
		// 02 Input Status
		BaseLocator<Boolean> loc = BaseLocator.inputStatus(slaveId, offset);
		Boolean value = getMaster().getValue(loc);
		return value;
	}

	/**
	 * 读取[03 Holding Register类型 2x]模拟量数据
	 * 
	 * @param slaveId
	 *            slave Id
	 * @param offset
	 *            位置
	 * @param dataType
	 *            数据类型,来自com.serotonin.modbus4j.code.DataType
	 * @return
	 * @throws ModbusTransportException
	 *             异常
	 * @throws ErrorResponseException
	 *             异常
	 * @throws ModbusInitException
	 *             异常
	 */
	public static Number readHoldingRegister(int slaveId, int offset, int dataType)
			throws ModbusTransportException, ErrorResponseException, ModbusInitException {
		// 03 Holding Register类型数据读取
		BaseLocator<Number> loc = BaseLocator.holdingRegister(slaveId, offset, dataType);
		Number value = getMaster().getValue(loc);
		return value;
	}

	/**
	 * 读取[04 Input Registers 3x]类型 模拟量数据
	 * 
	 * @param slaveId
	 *            slaveId
	 * @param offset
	 *            位置
	 * @param dataType
	 *            数据类型,来自com.serotonin.modbus4j.code.DataType
	 * @return 返回结果
	 * @throws ModbusTransportException
	 *             异常
	 * @throws ErrorResponseException
	 *             异常
	 * @throws ModbusInitException
	 *             异常
	 */
	public static Number readInputRegisters(int slaveId, int offset, int dataType)
			throws ModbusTransportException, ErrorResponseException, ModbusInitException {
		// 04 Input Registers类型数据读取
		BaseLocator<Number> loc = BaseLocator.inputRegister(slaveId, offset, dataType);
		Number value = getMaster().getValue(loc);
		return value;
	}
}

        2.写入数据

public class Modbus4jWriteUtils {
	static Log log = LogFactory.getLog(Modbus4jWriteUtils.class);
	/**
	 * 工厂。
	 */
	static ModbusFactory modbusFactory;
	static {
		if (modbusFactory == null) {
			modbusFactory = new ModbusFactory();
		}
	}

	/**
	 * 获取tcpMaster
	 *
	 * @return
	 * @throws ModbusInitException
	 */
	public static ModbusMaster getMaster() throws ModbusInitException {
		IpParameters params = new IpParameters();
		params.setHost("你的硬件地址");
		params.setPort("端口号");

		ModbusMaster tcpMaster = modbusFactory.createTcpMaster(params, false);
		tcpMaster.init();

		return tcpMaster;
	}

	/**
	 * 写 [01 Coil Status(0x)]写一个 function ID = 5
	 *
	 * @param slaveId
	 *            slave的ID
	 * @param writeOffset
	 *            位置
	 * @param writeValue
	 *            值
	 * @return 是否写入成功
	 * @throws ModbusTransportException
	 * @throws ModbusInitException
	 */
	public static boolean writeCoil(int slaveId, int writeOffset, boolean writeValue)
			throws ModbusTransportException, ModbusInitException {
		// 获取master
		ModbusMaster tcpMaster = getMaster();
		// 创建请求
		WriteCoilRequest request = new WriteCoilRequest(slaveId, writeOffset, writeValue);
		// 发送请求并获取响应对象
		WriteCoilResponse response = (WriteCoilResponse) tcpMaster.send(request);
		if (response.isException()) {
			return false;
		} else {
			return true;
		}
	}

	/**
	 * 写[01 Coil Status(0x)] 写多个 function ID = 15
	 *
	 * @param slaveId
	 *            slaveId
	 * @param startOffset
	 *            开始位置
	 * @param bdata
	 *            写入的数据
	 * @return 是否写入成功
	 * @throws ModbusTransportException
	 * @throws ModbusInitException
	 */
	public static boolean writeCoils(int slaveId, int startOffset, boolean[] bdata)
			throws ModbusTransportException, ModbusInitException {
		// 获取master
		ModbusMaster tcpMaster = getMaster();
		// 创建请求
		WriteCoilsRequest request = new WriteCoilsRequest(slaveId, startOffset, bdata);
		// 发送请求并获取响应对象
		WriteCoilsResponse response = (WriteCoilsResponse) tcpMaster.send(request);
		if (response.isException()) {
			return false;
		} else {
			return true;
		}

	}

	/***
	 * 写[03 Holding Register(4x)] 写一个 function ID = 6
	 *
	 * @param slaveId
	 * @param writeOffset
	 * @param writeValue
	 * @return
	 * @throws ModbusTransportException
	 * @throws ModbusInitException
	 */
	public static boolean writeRegister(int slaveId, int writeOffset, short writeValue)
			throws ModbusTransportException, ModbusInitException {
		// 获取master
		ModbusMaster tcpMaster = getMaster();
		// 创建请求对象
		WriteRegisterRequest request = new WriteRegisterRequest(slaveId, writeOffset, writeValue);
		WriteRegisterResponse response = (WriteRegisterResponse) tcpMaster.send(request);
		if (response.isException()) {
			log.error(response.getExceptionMessage());
			return false;
		} else {
			return true;
		}

	}

	/**
	 *
	 * 写入[03 Holding Register(4x)]写多个 function ID=16
	 *
	 * @param slaveId
	 *            modbus的slaveID
	 * @param startOffset
	 *            起始位置偏移量值
	 * @param sdata
	 *            写入的数据
	 * @return 返回是否写入成功
	 * @throws ModbusTransportException
	 * @throws ModbusInitException
	 */
	public static boolean writeRegisters(int slaveId, int startOffset, short[] sdata)
			throws ModbusTransportException, ModbusInitException {
		// 获取master
		ModbusMaster tcpMaster = getMaster();
		// 创建请求对象
		WriteRegistersRequest request = new WriteRegistersRequest(slaveId, startOffset, sdata);
		// 发送请求并获取响应对象
		ModbusResponse response = tcpMaster.send(request);
		if (response.isException()) {
			log.error(response.getExceptionMessage());
			return false;
		} else {
			return true;
		}
	}

	/**
	 * 写入数字类型的模拟量(如:写入Float类型的模拟量、Double类型模拟量、整数类型Short、Integer、Long)
	 *
	 * @param slaveId
	 * @param offset
	 * @param value
	 *            写入值,Number的子类,例如写入Float浮点类型,Double双精度类型,以及整型short,int,long
	 * @param registerCount
	 * ,com.serotonin.modbus4j.code.DataType
	 * @throws ModbusTransportException
	 * @throws ErrorResponseException
	 * @throws ModbusInitException
	 */
	public static void writeHoldingRegister(int slaveId, int offset, Number value, int dataType)
			throws ModbusTransportException, ErrorResponseException, ModbusInitException {
		// 获取master
		ModbusMaster tcpMaster = getMaster();
		// 类型
		BaseLocator<Number> locator = BaseLocator.holdingRegister(slaveId, offset, dataType);
		tcpMaster.setValue(locator, value);
	}
 
}

  • 3
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
Java对接Modbus RTU可以通过使用一些现有的Java库来实现。以下是一种常见的方法: 1. 首先,你需要引入一个Java Modbus库,比如`jamod`。在你的项目中添加该库的依赖项。 2. 创建一个Modbus主站(Master)对象,用于与Modbus从站(Slave)进行通信。你可以使用`ModbusMasterFactory`类的静态方法来创建主站对象。例如,使用串口连接创建一个RTU主站对象: ```java String portName = "/dev/ttyUSB0"; // 串口名称 int baudRate = 9600; // 波特率 SerialParameters parameters = new SerialParameters(); parameters.setPortName(portName); parameters.setBaudRate(baudRate); ModbusSerialMaster modbusMaster = ModbusMasterFactory.createModbusMasterRTU(parameters); ``` 3. 使用`connect()`方法连接到Modbus从站: ```java modbusMaster.connect(); ``` 4. 现在你可以使用主站对象发送Modbus请求并接收响应。例如,读取从站中的保持寄存器的值: ```java int slaveId = 1; // 从站ID int startAddress = 0; // 寄存器起始地址 int numberOfRegisters = 10; // 寄存器数量 ReadMultipleRegistersRequest request = new ReadMultipleRegistersRequest(slaveId, startAddress, numberOfRegisters); ReadMultipleRegistersResponse response = (ReadMultipleRegistersResponse) modbusMaster.send(request); ``` 5. 处理响应数据,例如获取读取到的寄存器值: ```java if (response.isException()) { System.out.println("Modbus request failed: " + response.getExceptionMessage()); } else { int[] registerValues = response.getShortData(); for (int value : registerValues) { System.out.println("Register value: " + value); } } ``` 6. 最后,使用`disconnect()`方法断开与Modbus从站的连接: ```java modbusMaster.disconnect(); ``` 这只是一个简单的示例,你可以根据实际情况进行更多的操作和错误处理。请确保你已经正确配置了串口参数和从站ID等信息。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值