Modbus Software, Driver and Libraries
 Login 
Member of Modbus Organization

Have a Question?

We accept VISA, MasterCard, PayPal

30-day Money-Back Guarantee

Examples

Serial Example

The following example SerSimple.java shows how to configure a serial Modbus protocol and read values:

// Import the FieldTalk protocol library
import com.focus_sw.fieldtalk.*;


public class SerSimple
{

   public static void main(String[] args)
   {
      try
      {
         new SerSimple().poll();
      }
      catch (Exception e)
      {
         e.printStackTrace();
      }
   }


   public void poll() throws Exception
   {
      // Declare as MbusAsciiMasterProtocol if Modbus ASCII should be used
      //MbusAsciiMasterProtocol mbus = new MbusAsciiMasterProtocol();
      MbusRtuMasterProtocol mbus = new MbusRtuMasterProtocol();

      // Declare as int[] or float[] array to read 32-bit values instead
      short[] dataSet1 = new short[1 /*Number of values to be read*/];

      // Configure and open port
      mbus.setRetryCnt(0); // Increase to 2 for poor links
      mbus.setPollDelay(0); // Increase if slave needs time between polls
      mbus.openProtocol("COM1", 9600,
                        mbus.DATABITS_8, mbus.STOPBITS_1, mbus.PARITY_NONE);

      try
      {
         while (true)
         {
            try
            {
               // Read data from slave
               mbus.readMultipleRegisters(1 /*Slave address*/,
                                          100 /*Start reference*/,
                                          dataSet1);
               // Simply print the first value read
               System.out.println("Data = " + dataSet1[0]);
            }
            catch (BusProtocolException e)
            {
               System.out.println(e.toString());
            }
         }
      }
      finally
      {
         // Clean-up
         mbus.closeProtocol();
      }
   }
}

Multithreaded Example

The following example SerCommunicator.java shows how to use multi-threading for concurrent polling of multiple slave devices of the same type:

// Import the FieldTalk protocol library
import com.focus_sw.fieldtalk.*;


public class SerCommunicator implements Runnable
{
   // Declare as MbusAsciiMasterProtocol if Modbus ASCII should be used
   MbusRtuMasterProtocol mbus = new MbusRtuMasterProtocol ();

   // Data to be exchanged
   DeviceDataProfile device1 = new DeviceDataProfile();
   DeviceDataProfile device2 = new DeviceDataProfile();


   public static void main(String[] args)
   {
      try
      {
         new SerCommunicator("COM1");
      }
      catch (Exception e)
      {
         e.printStackTrace();
      }
   }


   public SerCommunicator(String portName)
      throws Exception
   {
      // Configure and open port
      mbus.setRetryCnt(0); // Increase to 2 for poor links
      mbus.setPollDelay(0); // Increase if slaves need quiet period on bus
      mbus.openProtocol(portName, 9600, MbusRtuMasterProtocol.DATABITS_8,
                                    MbusRtuMasterProtocol.STOPBITS_1,
                                    MbusRtuMasterProtocol.PARITY_NONE);

      // Start communication threads to two similar devices
      new PollThread(mbus, 1 /*Slave address*/, device1).start();
      new PollThread(mbus, 2 /*Slave address*/, device2).start();

      // Start data processing thread
      new Thread (this).start();
   }


   public void run()
   {
      while(true)
      {
         processData(device1);
         processData(device2);

         // Sleep for 1000 ms
         try { Thread.currentThread().sleep(1000); }
         catch (java.lang.InterruptedException e) { /* ignore */ }
      }
   }


   public void processData(DeviceDataProfile data)
   {
      synchronized(data.deviceDataSet1)
      {
         // Do something here with data ...
      }
      synchronized(data.deviceDataSet2)
      {
         // Do something here with data ...
      }
      synchronized(data.deviceDataSet3)
      {
         // Update data to be written here ...
      }
   }
}

class DeviceDataProfile
{
   // Declare as int[] or float[] array to read 32-bit values instead
   public short[] deviceDataSet1 = new short[10 /*No of values to be read*/];
   public short[] deviceDataSet2 = new short[10 /*No of values to be read*/];
   public short[] deviceDataSet3 = new short[10 /*No of values to be sent*/];
}

import java.io.*;

// Import the FieldTalk protocol library
import com.focus_sw.fieldtalk.*;


public class PollThread extends Thread
{
   MbusMasterFunctions mbus;
   int slaveAddr;
   DeviceDataProfile deviceDataProfile;

   public PollThread(MbusMasterFunctions mbus,
                     int slaveAddr,
                     DeviceDataProfile deviceDataProfile)
   {
      this.mbus = mbus;
      this.slaveAddr = slaveAddr;
      this.deviceDataProfile = deviceDataProfile;
   }


   public void run()
   {
      while (true)
      {
         try
         {
            // Read data set 1 from slave
            mbus.readMultipleRegisters(slaveAddr,
                                       100 /*Start reference*/,
                                       deviceDataProfile.deviceDataSet1);
            // Read data set 2 from slave
            mbus.readMultipleRegisters(slaveAddr,
                                       140 /*Start reference*/,
                                       deviceDataProfile.deviceDataSet2);
            // Write data set 3 to slave
            mbus.writeMultipleRegisters(slaveAddr,
                                        160 /*Start reference*/,
                                        deviceDataProfile.deviceDataSet3);
            System.out.println("Polling slave " + slaveAddr);
         }
         catch (BusProtocolException e)
         {
            System.out.println("Slave " + slaveAddr + ": " + e.toString());
         }
         catch (IOException e)
         {
            System.out.println("Slave " + slaveAddr + ": " + e.toString());
         }
      }
   }
}

MODBUS/TCP Example

The following example TcpSimple.java shows how to configure a MODBUS/TCP protocol and read values:

// Import the FieldTalk protocol library
import com.focus_sw.fieldtalk.*;


public class TcpSimple
{

   public static void main(String[] args)
   {
      try
      {
         new TcpSimple().poll();
      }
      catch (Exception e)
      {
         e.printStackTrace();
      }
   }


   public void poll() throws Exception
   {
      MbusTcpMasterProtocol mbus = new MbusTcpMasterProtocol ();

      // Declare as int[] or float[] array to read 32-bit values instead
      short[] dataSet1 = new short[10 /*Number of values to be read*/];

      // Configure and open connection
      mbus.setPollDelay(1000); // Poll only every 1 s
      mbus.openProtocol("127.0.0.1"); // Pass IP address or host name here

      try
      {
         while (true)
         {
            try
            {
               // Read data from slave
               mbus.readMultipleRegisters(1 /*Slave address*/,
                                          100 /*Start reference*/,
                                          dataSet1);
               // Simply print the first value read
               System.out.println("Data = " + dataSet1[0]);
            }
            catch (BusProtocolException e)
            {
               System.out.println(e.toString());
            }
         }
      }
      finally
      {
         // Clean-up
         mbus.closeProtocol();
      }
   }
}

Applet Example with Cyclic Polling

The following example CyclicPollApplet.java shows how to use the protocol package in conjunction with an applet to present process information dynamically on a web page.

The Applet shows a dynamic tank level display within a web page. The tank level data is retrieved from a MODBUS/TCP based measurement system at IP address 10.0.0.11, Modbus unit 1. Two tank levels are displayed. In addition a pump can be started and stopped. The Modbus register table is as follows:

  • Register 100 in the holding register table is tank level 1
  • Register 101 in the holding register table is tank level 2
  • Register 110 is a write register for a pump. Bit 0 starts the pump, bit 1 stops the pump.

CyclicPollApplet.gif

import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;

// Import the Java I/O package for the I/O Exceptions
import java.io.*;

// Import the FieldTalk protocol library
import com.focus_sw.fieldtalk.*;


public class CyclicPollApplet extends Applet implements Runnable
{
   /**************************************************************************
    * Modbus communication related data
    **************************************************************************/

   Thread pollThread; // The cyclic poll thread
   volatile boolean pollThreadExit; // Flag to safely terminate the thread
   MbusTcpMasterProtocol mbus = new MbusTcpMasterProtocol(); // The protocol
   short readDataTable[] = new short[2]; // The data table to be read


   /**************************************************************************
    * User interface data
    **************************************************************************/

   GridBagLayout gridBagLayout = new GridBagLayout();
   JLabel StatusLabel = new JLabel();
   JLabel titleLabel = new JLabel();
   JLabel tank1Label = new JLabel();
   JLabel tank2Label = new JLabel();
   JLabel tankLevel1Label = new JLabel();
   JLabel tankLevel2Label = new JLabel();
   JProgressBar tankLevel1Bar = new JProgressBar();
   JProgressBar tankLevel2Bar = new JProgressBar();
   JButton startPumpButton = new JButton();
   JButton pumpStopButton = new JButton();


   /**************************************************************************
    * Standard applet methods
    **************************************************************************/


   public CyclicPollApplet()
   {
   }


   public void init()
   {
      try
      {
         jbInit();
         invalidateUiData();
      }
      catch(Exception e)
      {
         e.printStackTrace();
      }
   }


   public void start()
   {
      try
      {
         StatusLabel.setText("Connecting...");
         mbus.openProtocol("127.0.0.1");
         StatusLabel.setText("Connected to MODBUS/TCP slave device");
         pollThreadExit = false;
         pollThread = new Thread(this);
         pollThread.start();
      }
      catch (Exception e)
      {
         StatusLabel.setText(e.toString());
      }
   }


   public void stop()
   {
      try
      {
         pollThreadExit = true; // Stop thread safely
         try { pollThread.join(); }
         catch (java.lang.InterruptedException e) { /* ignore */ }
         mbus.closeProtocol();
         StatusLabel.setText("Connection closed");
         invalidateUiData();
      }
      catch (Exception e)
      {
         StatusLabel.setText(e.toString());
         invalidateUiData();
      }
   }


   /**************************************************************************
    * User interface management
    **************************************************************************/

   private void jbInit() throws Exception
   {
      StatusLabel.setBorder(BorderFactory.createLoweredBevelBorder());
      StatusLabel.setText("Status");
      titleLabel.setFont(new java.awt.Font("Dialog", 1, 14));
      titleLabel.setBorder(BorderFactory.createRaisedBevelBorder());
      titleLabel.setText("FieldTalk(tm) Modbus Master Protocol Sample");
      startPumpButton.setBackground(Color.green);
      startPumpButton.setText("Start Pump");
      startPumpButton.addActionListener(new java.awt.event.ActionListener()
      {
         public void actionPerformed(ActionEvent e)
         {
            startPumpButton_actionPerformed(e);
         }
      });
      pumpStopButton.setBackground(Color.red);
      pumpStopButton.setText("Stop Pump");
      pumpStopButton.addActionListener(new java.awt.event.ActionListener()
      {
         public void actionPerformed(ActionEvent e)
         {
            pumpStopButton_actionPerformed(e);
         }
      });
      tankLevel1Label.setBackground(Color.white);
      tankLevel1Label.setFont(new java.awt.Font("Dialog", 1, 12));
      tankLevel1Label.setForeground(Color.blue);
      tankLevel1Label.setBorder(BorderFactory.createLoweredBevelBorder());
      tankLevel1Label.setHorizontalAlignment(SwingConstants.RIGHT);
      tankLevel1Label.setHorizontalTextPosition(SwingConstants.RIGHT);
      tankLevel2Label.setBackground(Color.white);
      tankLevel2Label.setFont(new java.awt.Font("Dialog", 1, 12));
      tankLevel2Label.setForeground(Color.magenta);
      tankLevel2Label.setBorder(BorderFactory.createLoweredBevelBorder());
      tankLevel2Label.setHorizontalAlignment(SwingConstants.RIGHT);
      tankLevel2Label.setHorizontalTextPosition(SwingConstants.RIGHT);
      tankLevel2Bar.setOrientation(JProgressBar.VERTICAL);
      tankLevel2Bar.setForeground(Color.magenta);
      tankLevel2Bar.setPreferredSize(new Dimension(50, 200));
      tankLevel2Bar.setMaximum(1000);
      tankLevel1Bar.setOrientation(JProgressBar.VERTICAL);
      tankLevel1Bar.setForeground(Color.blue);
      tankLevel1Bar.setPreferredSize(new Dimension(50, 200));
      tankLevel1Bar.setMaximum(1000);
      this.setLayout(gridBagLayout);
      tank1Label.setText("Tank 1");
      tank2Label.setText("Tank 2");
      this.add(tankLevel1Bar, new GridBagConstraints(0, 2, 1, 2, 0.0, 0.0,
            GridBagConstraints.CENTER, GridBagConstraints.BOTH,
            new Insets(10, 10, 10, 10), 0, 0));
      this.add(startPumpButton, new GridBagConstraints(2, 3, 1, 1, 0.0, 0.0
            ,GridBagConstraints.NORTH, GridBagConstraints.NONE,
            new Insets(10, 10, 10, 10), 0, 0));
      this.add(tank1Label, new GridBagConstraints(0, 1, 1, 1, 0.0, 0.0
            ,GridBagConstraints.CENTER, GridBagConstraints.NONE,
            new Insets(10, 10, 0, 10), 0, 0));
      this.add(tank2Label, new GridBagConstraints(1, 1, 1, 1, 0.0, 0.0
            ,GridBagConstraints.CENTER, GridBagConstraints.NONE,
            new Insets(10, 10, 0, 10), 0, 0));
      this.add(StatusLabel, new GridBagConstraints(0, 5, 3, 1, 0.0, 0.0
            ,GridBagConstraints.CENTER, GridBagConstraints.BOTH,
            new Insets(0, 0, 0, 0), 0, 0));
      this.add(titleLabel, new GridBagConstraints(0, 0, 3, 1, 0.0, 0.0
            ,GridBagConstraints.CENTER, GridBagConstraints.BOTH,
            new Insets(0, 0, 0, 0), 0, 0));
      this.add(tankLevel2Bar, new GridBagConstraints(1, 2, 1, 2, 0.0, 0.0
            ,GridBagConstraints.CENTER, GridBagConstraints.BOTH,
            new Insets(10, 10, 10, 10), 0, 0));
      this.add(tankLevel1Label, new GridBagConstraints(0, 4, 1, 1, 0.0, 0.0
            ,GridBagConstraints.NORTH, GridBagConstraints.HORIZONTAL,
            new Insets(0, 10, 10, 10), 0, 0));
      this.add(tankLevel2Label, new GridBagConstraints(1, 4, 1, 1, 0.0, 0.0
            ,GridBagConstraints.NORTH, GridBagConstraints.HORIZONTAL,
            new Insets(0, 10, 10, 10), 0, 0));
      this.add(pumpStopButton, new GridBagConstraints(2, 2, 1, 1, 0.0, 0.0
            ,GridBagConstraints.SOUTH, GridBagConstraints.NONE,
            new Insets(10, 10, 10, 10), 0, 0));
   }


   void invalidateUiData()
   {
      // Invalidate user interface data
      tankLevel1Label.setText("???");
      tankLevel2Label.setText("???");
      tankLevel1Bar.setValue(0);
      tankLevel2Bar.setValue(0);
   }


   /**************************************************************************
    * Data transfer methods
    **************************************************************************/

   public void run()
   {
      while (!pollThreadExit)
      {
         //
         // Sleep for 1000 ms
         //
         try { Thread.currentThread().sleep(1000); }
         catch (java.lang.InterruptedException e) { /* ignore */ }

         //
         // Data transmission
         //
         try
         {
            // Read data from slave into the readDataTable
            mbus.readMultipleRegisters(1, 100, readDataTable);
            StatusLabel.setText("Updating live data ...");

            // Update user interface with values
            tankLevel1Label.setText(Integer.toString(readDataTable[0]));
            tankLevel2Label.setText(Integer.toString(readDataTable[1]));
            tankLevel1Bar.setValue((int) readDataTable[0]);
            tankLevel2Bar.setValue((int) readDataTable[1]);
         }
         catch (Exception e)
         {
            // I/O exception or bus protocol exception occured
            StatusLabel.setText(e.toString());
            invalidateUiData();
         }
      }
   }


   void startPumpButton_actionPerformed(ActionEvent a)
   {
         try
         {
            // Write command bit 0 to command register at 110
            mbus.writeSingleRegister(1, 110, (short) 0x0001);
         }
         catch (IOException e)
         {
            // I/O exception or bus protocol exception occured
            StatusLabel.setText(e.toString());
         }
   }


   void pumpStopButton_actionPerformed(ActionEvent a)
   {
         try
         {
            // Write command bit 1 to command register at 110
            mbus.writeSingleRegister(1, 110, (short) 0x0002);
         }
         catch (Exception e)
         {
            // I/O exception or bus protocol exception occured
            StatusLabel.setText(e.toString());
         }
   }
}