Menu

WriteMultipleRegistersRequest() with float ?

Help
Ramon
2013-08-08
2015-09-03
  • Ramon

    Ramon - 2013-08-08

    Hello Fellas,

    I am a student of electrical engineering and IT. At the moment I am in a practical phase and I have a project where I need to write a Java program to communicate with a "Siemens Sentron PAC3200" measurement device via modbus tcp. Here comes the problem:

    I want to write a value which is stored as float in the device. The devices register I want to write on is two times 16 bits ( = 32 bits ) large. The class WriteMultipleRegistersRequest() needs to get a Register[] as input parameter. I filled this Register[] with two SimpleRegisters(). But a SimpleRegister can not store floats. When I try to execute the program with storing integers instead, I do NOT get a SlaveException or any other exception. The program runs, but the value in the device does not change (I can check that on the devices display).
    I managed to write other registers on this device with this method, despite they stored the value as unsigned long. I am a little bit confused and I have no idea how to solve this. Below u can see my source code for better understanding of my problem. I hope u have any suggestions =)

    public class Writer {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        try {
    
         /**************************************/
    
        //Write Multiple Registers
        int port = Modbus.DEFAULT_PORT; 
        int ref = 50073;                //Register
        int SlaveAddr= 1;               //standart in Modbus
        String astr = "192.168.10.2";   //Modbus Device (Siemens Sentron PAC3200)
    
        int msv = 6;                    //values to be written 
        int lsv = 5;                    // values to be written
    
        Register[] register = new Register[2];  // register for WriteRegisters Class Input
        register [0] = new SimpleRegister(msv); // value for first 2 bytes
        register [1] = new SimpleRegister(lsv); // value for second 2 bytes
    
        InetAddress addr = InetAddress.getByName(astr);
        TCPMasterConnection con = new TCPMasterConnection(addr); //the connection
        ModbusTCPTransaction trans = new ModbusTCPTransaction(con); //the transaction
    
        //1.Prepare the request
        /************************************/
        WriteMultipleRegistersRequest Rreq = new WriteMultipleRegistersRequest(ref, register); // WriteRegisters Class
        //WriteMultipleRegistersResponse Rres = new WriteMultipleRegistersResponse();
    
        Rreq.setUnitID(SlaveAddr); //set Slave Address  
        //Rres.setUnitID(SlaveAddr); //set Slave Address
    
        //2. Open the connection
        con.setPort(port);
        con.connect();
        con.setTimeout(2500);
    
        //3. Start Transaction
        trans.setRetries(5);
        trans.setReconnecting(true);
        trans.setRequest(Rreq);
        trans.execute();
    
        //4. Print out connection (not necessary)
        System.out.println("Connected to=  "+ astr + " " + con.isConnected() + " / Start Register " + ref);
    
    /****************Close Connection**************/
        con.close();
        System.exit(0);
    
    } catch (Exception ex) {
      ex.printStackTrace();
    }
    
    }
    

    }

     
  • Ken

    Ken - 2014-07-11

    Maybe a too late answer...

    Float is not part of the original Modbus protocol. It has appeard in some extensions (Look for Enron Modbus extension).
    If you try to play with register to make a kind new type, it will be easier to create a new function as an extension

     
  • Julie Haugh

    Julie Haugh - 2015-09-03

    The proper approach to handling floating point numbers is to convert the value into the appropriate 16 bit pieces and send those values. Yes, there are extensions, but the slave device must support them.

    The Java method for doing this with IEEE floating point values is to create a Float() object which contains the desired value, then invoke the floatToIntBits() method. This will return a 32-bit representation of the floating point value as an "int". With that value in hand, you use bit-masking and shifting to create the two 16-bit halves. You will need to know if the device expects those two halves (or even the bytes within those two halves) in big or little endian order.

    If you have any further questions, the j2mod project, which is a fork of jamod, is located here -

    https://sourceforge.net/projects/j2mod/

    Converting from jamod to j2mod is fairly straightfoward and you may find better support there.

     

Log in to post a comment.