package jydamserial;

import com.serotonin.io.serial.*;
import com.serotonin.modbus4j.*;
import com.serotonin.modbus4j.exception.*;
import com.serotonin.modbus4j.msg.*;

import java.util.*;

public class helloword {
	//MODBUS的设备地址。   默认为254， 但由于次代码不支持254的地址，所以需要修改设备的地址为1.
    private final static int SLAVE_ADDRESS=1;
 
    //默认波特率为9600
    private final static int BAUD_RATE = 9600;
	
    public static void main(String[] args) throws ModbusInitException, InterruptedException{
    	SerialParameters serialParameters = new SerialParameters();
    	 
        //设定MODBUS通讯的串行口
        serialParameters.setCommPortId("COM1");
 
        //设定成无奇偶校验
        serialParameters.setParity(0);
 
        //设定成数据位是8位
        serialParameters.setDataBits(8);
 
        //设定为1个停止位
        serialParameters.setStopBits(1);
 
        serialParameters.setPortOwnerName("Numb nuts");
 
        //串行口上的波特率
        serialParameters.setBaudRate(BAUD_RATE);
        
        ModbusFactory modbusFactory = new ModbusFactory();
        ModbusMaster master = modbusFactory.createRtuMaster(serialParameters);
        try {
        	master.init();
			//
            readDiscreteInputTest(master,SLAVE_ADDRESS,0,8);//读取设备的光耦状态     8为光耦的数量，根据实际设备通道来写
			readInputRegistersTest(master,SLAVE_ADDRESS,0,8);//读取设备的模拟量状态     8为模拟量的数量，根据实际设备通道来写
            writeRegistersTest(master,SLAVE_ADDRESS, 0, new short[]{1,2,3,4,5,6, 7, 8, 9} );//写保持寄存器内容  不需要可以屏蔽
            readHoldingRegistersTest(master,SLAVE_ADDRESS,0,2);//读取保持寄存器内容  不需要可以屏蔽
            writeCoilTest(master,SLAVE_ADDRESS,0,true);//控制继电器输出   第1通道打开
            Thread.sleep(1000);
            writeCoilTest(master,SLAVE_ADDRESS,0,false);//控制继电器输出   第1通道打开
            Thread.sleep(1000);
            writeCoilTest(master,SLAVE_ADDRESS,1,true);//控制继电器输出   第2通道打开
            Thread.sleep(1000);
            writeCoilTest(master,SLAVE_ADDRESS,1,false);//控制单个继电器输出 第2通道关闭
            
            Thread.sleep(1000);
            writeCoilsTest(master,SLAVE_ADDRESS,1,new boolean[]{false,true,false,true});//控制继电器输出 不能超过设备通道数量
            
            Thread.sleep(1000);
            writeCoilsTest(master,SLAVE_ADDRESS,1,new boolean[]{true,false,true,false});//控制继电器输出 不能超过设备通道数量
        }
        finally {
            master.destroy();
        }
        
        
    }
    
    
   /**
     * 读光耦输入信号
     * @param master 主站
     * @param slaveId 从站地址
     * @param start 起始地址的偏移量
     * @param len 待读寄存器的个数
     */
    private static void readDiscreteInputTest(ModbusMaster master, int slaveId, int start, int len) {
        try {
            ReadDiscreteInputsRequest request = new ReadDiscreteInputsRequest(slaveId, start, len);
            ReadDiscreteInputsResponse response = (ReadDiscreteInputsResponse) master.send(request);
 
            System.out.println("读光耦输入信号");
            if (response.isException())
                System.out.println("Exception response: message=" + response.getExceptionMessage());
            else
                System.out.println(Arrays.toString(response.getBooleanData()));
        }
        catch (ModbusTransportException e) {
            e.printStackTrace();
        }
    }
	
   /**

     * 读输入寄存器上的内容
     * @param master 主站
     * @param slaveId 从站地址
     * @param start 起始地址的偏移量
     * @param len 待读寄存器的个数
     */
    private static void readInputRegistersTest(ModbusMaster master, int slaveId, int start, int len) {
        try {
        	ReadInputRegistersRequest request = new ReadInputRegistersRequest(slaveId, start, len);
        	ReadInputRegistersResponse response = (ReadInputRegistersResponse) master.send(request);
 
            System.out.println("读输入寄存器上的内容");
            if (response.isException())
                System.out.println("Exception response: message=" + response.getExceptionMessage());
            else
                System.out.println(Arrays.toString(response.getShortData()));
        }
        catch (ModbusTransportException e) {
            e.printStackTrace();
        }
    }

 
   /**
     * 读保持寄存器上的内容
     * @param master 主站
     * @param slaveId 从站地址
     * @param start 起始地址的偏移量
     * @param len 待读寄存器的个数
     */
    private static void readHoldingRegistersTest(ModbusMaster master, int slaveId, int start, int len) {
        try {
            ReadHoldingRegistersRequest request = new ReadHoldingRegistersRequest(slaveId, start, len);
            ReadHoldingRegistersResponse response = (ReadHoldingRegistersResponse) master.send(request);
 
            System.out.println("读保持寄存器上的内容");
            if (response.isException())
                System.out.println("Exception response: message=" + response.getExceptionMessage());
            else
                System.out.println(Arrays.toString(response.getShortData()));
        }
        catch (ModbusTransportException e) {
            e.printStackTrace();
        }
    }
 
/**
     * 批量写数据到保持寄存器
     * @param master 主站
     * @param slaveId 从站地址
     * @param start 起始地址的偏移量
     * @param values 待写数据
     */
    public static void writeRegistersTest(ModbusMaster master, int slaveId, int start, short[] values) {
        try {
        	WriteRegistersRequest request = new WriteRegistersRequest(slaveId, start, values);
        	WriteRegistersResponse response = (WriteRegistersResponse) master.send(request);
 
            System.out.println("批量写数据到保持寄存器");
            if (response.isException())
                System.out.println("Exception response: message=" + response.getExceptionMessage());
            else
                System.out.println("Success");
        }
        catch (ModbusTransportException e) {
            e.printStackTrace();
        }
    }
    
    
/**
     * 控制单个继电器输出
     * @param master 主站
     * @param slaveId 从站地址
     * @param start 起始地址的偏移量
     * @param val 待写数据
     */
    public static void writeCoilTest(ModbusMaster master, int slaveId, int start, boolean val) {
        try {
        	WriteCoilRequest request = new WriteCoilRequest(slaveId, start, val);
            WriteCoilResponse response = (WriteCoilResponse) master.send(request);
 
            System.out.println("控制单个继电器输出");
            if (response.isException())
                System.out.println("Exception response: message=" + response.getExceptionMessage());
            else
                System.out.println("Success");
        }
        catch (ModbusTransportException e) {
            e.printStackTrace();
        }
    }
    
    
/**
     * 控制多个继电器输出
     * @param master 主站
     * @param slaveId 从站地址
     * @param start 起始地址的偏移量
     * @param values 待写数据
     */
    public static void writeCoilsTest(ModbusMaster master, int slaveId, int start, boolean[] values) {
        try {
        	WriteCoilsRequest request = new WriteCoilsRequest(slaveId, start, values);
            WriteCoilsResponse response = (WriteCoilsResponse) master.send(request);
 
            System.out.println("控制多个继电器输出");
            if (response.isException())
                System.out.println("Exception response: message=" + response.getExceptionMessage());
            else
                System.out.println("Success");
        }
        catch (ModbusTransportException e) {
            e.printStackTrace();
        }
    }
    
	
}
