Ascii through TCP

Help
Anonymous
2010-09-07
2013-05-13
  • Anonymous - 2010-09-07

    Hello! Thank tou for a perfect project!
    I've got a question:
    I have a modbus  ascii serial device, that is connected through Adam-4579 TCP<->Serial converter. Can I connect to it using modbus4j?

     
  • Anonymous - 2010-09-08

    Thank you for a link to mango. Just downloaded it. But the problen is still is.

    The communication itself is ok. The problem is - device wants to communicate over ASCII encoding, while jamod TCP does not allow to choose encoding. In debug screen of my device I see that requests are coming, but the format is wrong.

     
  • Anonymous - 2010-09-08

    Of course not jamod, but modbus4j. I'm trying to use both jamod and modbus4j, but neither is working to ascii over tcp :(

     
  • Matthew Lohbihler

    I missed the TCP part. You're trying to do ASCII encapsulation over TCP? Or you are using serial to TCP to serial conversion? Modbus4J recently added RTU encapsulation over I/P, but i've never heard of ASCII encap.

     
  • Anonymous - 2010-09-10

    I'm using TCP/Serial converter, serial cable is connected to my device, TCP port connected to my computer. So i'm trying to do ASCII encapsulation over TCP.

     
  • Matthew Lohbihler

    Hmm, no Modbus4J doesn't support that. If you can, i'd suggest using RTU instead. If you absolutely need encap ASCII, Serotonin can be contracted to build it in. Go to http://mango.serotoninsoftware.com/contact.jsp

     
  • Anonymous - 2010-09-10

    It's a pity, but I use a device, that can't be RTU. I'll try to write to support. Maybe i'll try to do it by myself, but I'm not shure that it'll be good to spoil their code )) There is some wrong design there, I think. Transport ASCII is extending Serial class. It's not very good, but they couldn't suppose, that there''ll be a need in such a strange thing :)

     
  • Anonymous - 2010-09-13

    I did it by myself. Here is the code, if someone interested. It was very simple. Thank for OO design of modbus4j.

    /*
     * ============================================================================
     * GNU General Public License
     * ============================================================================
     *
     * Copyright (C) 2006-2011 Serotonin Software Technologies Inc. http://serotoninsoftware.com
     * @author Matthew Lohbihler
     *
     * This program is free software: you can redistribute it and/or modify
     * it under the terms of the GNU General Public License as published by
     * the Free Software Foundation, either version 3 of the License, or
     * (at your option) any later version.
     *
     * This program is distributed in the hope that it will be useful,
     * but WITHOUT ANY WARRANTY; without even the implied warranty of
     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     * GNU General Public License for more details.
     * You should have received a copy of the GNU General Public License
     * along with this program.  If not, see <http://www.gnu.org/licenses/>.
     */
    package testapp;
    import java.io.IOException;
    import java.net.InetSocketAddress;
    import java.net.Socket;
    import com.serotonin.messaging.MessageControl;
    import com.serotonin.messaging.OutgoingRequestMessage;
    import com.serotonin.messaging.StreamTransport;
    import com.serotonin.modbus4j.ModbusMaster;
    import com.serotonin.modbus4j.base.BaseMessageParser;
    import com.serotonin.modbus4j.exception.ModbusInitException;
    import com.serotonin.modbus4j.exception.ModbusTransportException;
    import com.serotonin.modbus4j.ip.IpMessageResponse;
    import com.serotonin.modbus4j.ip.IpParameters;
    import com.serotonin.modbus4j.ip.encap.EncapMessageParser;
    import com.serotonin.modbus4j.ip.encap.EncapMessageRequest;
    import com.serotonin.modbus4j.ip.xa.XaMessageParser;
    import com.serotonin.modbus4j.ip.xa.XaMessageRequest;
    import com.serotonin.modbus4j.msg.ModbusRequest;
    import com.serotonin.modbus4j.msg.ModbusResponse;
    import com.serotonin.modbus4j.serial.ascii.AsciiMessageParser;
    import com.serotonin.modbus4j.serial.ascii.AsciiMessageRequest;
    import com.serotonin.modbus4j.serial.ascii.AsciiMessageResponse;
    public class TCPASCIIMaster extends ModbusMaster {
        // Configuration fields.
        private short nextTransactionId = 0;
        private final IpParameters ipParameters;
        private final boolean keepAlive;
        // Runtime fields.
        private BaseMessageParser ipMessageParser;
        private Socket socket;
        private StreamTransport transport;
        private MessageControl conn;
        public TCPASCIIMaster(IpParameters params, boolean keepAlive) {
            ipParameters = params;
            this.keepAlive = keepAlive;
        }
        protected short getNextTransactionId() {
            return nextTransactionId++;
        }
        @Override
        synchronized public void init() throws ModbusInitException {
                ipMessageParser = new AsciiMessageParser(true);
            try {
                if (keepAlive)
                    openConnection();
            }
            catch (Exception e) {
                throw new ModbusInitException(e);
            }
            initialized = true;
        }
        @Override
        synchronized public void destroy() {
            closeConnection();
        }
        @Override
        synchronized public ModbusResponse send(ModbusRequest request) throws ModbusTransportException {
            try {
                // Check if we need to open the connection.
                if (!keepAlive)
                    openConnection();
            }
            catch (Exception e) {
                closeConnection();
                throw new ModbusTransportException(e, request.getSlaveId());
            }
            // Wrap the modbus request in a ip request.
            OutgoingRequestMessage ipRequest = null;
                ipRequest = new AsciiMessageRequest(request);
            // Send the request to get the response.
            AsciiMessageResponse ipResponse;
            try {
                ipResponse = (AsciiMessageResponse) conn.send(ipRequest);
                if (ipResponse == null)
                    return null;
                return ipResponse.getModbusResponse();
            }
            catch (Exception e) {
                if (keepAlive) {
                    // The connection may have been reset, so try to reopen it and attempt the message again.
                    try {
                        // System.out.println("Modbus4J: Keep-alive connection may have been reset. Attempting to re-open.");
                        openConnection();
                        ipResponse = (AsciiMessageResponse)conn.send(ipRequest);
                        if (ipResponse == null)
                            return null;
                        return ipResponse.getModbusResponse();
                    }
                    catch (Exception e2) {
                        throw new ModbusTransportException(e2, request.getSlaveId());
                    }
                }
                throw new ModbusTransportException(e, request.getSlaveId());
            }
            finally {
                // Check if we should close the connection.
                if (!keepAlive)
                    closeConnection();
            }
        }
        //
        // /
        // / Private methods
        // /
        //
        private void openConnection() throws IOException {
            // Make sure any existing connection is closed.
            closeConnection();
            // Try 'retries' times to get the socket open.
            int retries = getRetries();
            while (true) {
                try {
                    socket = new Socket();
                    socket.connect(new InetSocketAddress(ipParameters.getHost(), ipParameters.getPort()), getTimeout());
                    transport = new StreamTransport(socket.getInputStream(), socket.getOutputStream());
                    break;
                }
                catch (IOException e) {
                    closeConnection();
                    if (retries <= 0)
                        throw e;
                    // System.out.println("Modbus4J: Open connection failed, trying again.");
                    retries--;
                }
            }
            conn = getMessageControl();
            conn.start(transport, ipMessageParser, null);
            transport.start("Modbus4J TcpMaster");
        }
        private void closeConnection() {
            closeMessageControl(conn);
            try {
                if (socket != null)
                    socket.close();
            }
            catch (IOException e) {
                getExceptionHandler().receivedException(e);
            }
            conn = null;
            socket = null;
        }
    }
    
     
  • Anonymous - 2010-09-13

    Nevertheless it would be a great thing to decouple ASCII and RTU classes from Serial :)

     

Log in to post a comment.

Get latest updates about Open Source Projects, Conferences and News.

Sign up for the SourceForge newsletter:





No, thanks