Java多种实现OPC通信 ——之N种方式

1.PLC和OPC

  • PLC:
    • 西门子的S7 300
  • OPC:
    • 实验用模拟OPCServer(50M):MatrikonOPC,百度网盘 ,密码: ykj2
    • 实际OPCServer使用(450M,中文):KEPServer V6,百度网盘,密码: mcur

2.连接测试

3.通信实现

4.实现过程

  • 先恶补了一下OPC的概念:
  • 先使用MatrikonOPC模拟实现:
  • 关于OPC UA
    • 支持的西门子PLC至少是s7-1500,
    • 我的s7-300是没法用的,所以就不需要搜集OPC UA的资料了
  • 关于Utgard
    • utgard是一个开源的项目,基于j-interop做的,用于和OPC SERVER通讯。
    • j-interop是纯java封装的用于COM/DCOM通讯的开源项目,这样就不必使用JNI
  • 关于JeasyOPC
    • JeasyOPC源码下载
    • 借助一个dll库来实现的和OPCServer的通信,但是JCustomOpc.dll,,太老了,而且支持只32位系统
  • 实现
    • 当然选Utgard
    • 过程就是把需要的jar包找到,
    • 然后复制编程指导里的读写代码,读就是启动线程一直监控读值,写就是直接写
  • 测试:
    • 参考OPC_Client里的例子
    • 关于配置文件的代码直接复制用了
    • 例子实际也用不到,试了试,,因为实际只需要读写变量就可以了
  • 问题:
    • 在虚拟机里用localhost一直报错,要写固定IP才行
    • 需要下载一个bcprov-jdk16-146.jar包,因为报安全算法错误
      • 位置:"C:\Program Files\Java\jdk1.8.0_92\jre\lib\ext\bcprov-jdk16-146.jar"
      • java.security位置:"C:\Program Files\Java\jdk1.8.0_92\jre\lib\security\java.security"
      • 在java.security最后添加一句:security.provider.x=org.bouncycastle.jce.provider.BouncyCastleProvider

5.代码

下载:链接: 百度网盘 ,密码: x7f1

截图:

转载请注明出处:https://blog.csdn.net/beiwulou2994

读值

package tcb;

import java.util.concurrent.Executors;

import org.jinterop.dcom.common.JIException;
import org.openscada.opc.lib.common.ConnectionInformation;
import org.openscada.opc.lib.da.AccessBase;
import org.openscada.opc.lib.da.DataCallback;
import org.openscada.opc.lib.da.Item;
import org.openscada.opc.lib.da.ItemState;
import org.openscada.opc.lib.da.Server;
import org.openscada.opc.lib.da.SyncAccess;

public class UtgardTutorial1 {

    public static void main(String[] args) throws Exception {
        // 连接信息
        final ConnectionInformation ci = new ConnectionInformation();
        ci.setHost("192.168.0.1");
        ci.setDomain("");
        ci.setUser("OPCUser");
        ci.setPassword("123456");

        // MatrikonOPC Server
        // ci.setClsid("F8582CF2-88FB-11D0-B850-00C0F0104305");
        // final String itemId = "u.u";//项的名字按实际

        // KEPServer
        ci.setClsid("7BC0CC8E-482C-47CA-ABDC-0FE7F9C6E729");
        final String itemId = "u.u.u";// 项的名字按实际
        // final String itemId = "通道 1.设备 1.标记 1";

        // create a new server
        final Server server = new Server(ci, Executors.newSingleThreadScheduledExecutor());

        try {
            // connect to server
            server.connect();
            // add sync access, poll every 500 ms
            final AccessBase access = new SyncAccess(server, 500);
            access.addItem(itemId, new DataCallback() {
                @Override
                public void changed(Item item, ItemState state) {
                    System.out.println("-----" + state);
                }
            });
            // start reading
            access.bind();
            // wait a little bit
            Thread.sleep(10 * 1000);
            // stop reading
            access.unbind();
        } catch (final JIException e) {
            System.out.println(String.format("%08X: %s", e.getErrorCode(), server.getErrorMessage(e.getErrorCode())));
        }
    }
}

转载请注明出处:https://blog.csdn.net/beiwulou2994

 写值

package tcb;

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import org.jinterop.dcom.common.JIException;
import org.jinterop.dcom.core.JIVariant;
import org.openscada.opc.lib.common.ConnectionInformation;
import org.openscada.opc.lib.da.AccessBase;
import org.openscada.opc.lib.da.DataCallback;
import org.openscada.opc.lib.da.Group;
import org.openscada.opc.lib.da.Item;
import org.openscada.opc.lib.da.ItemState;
import org.openscada.opc.lib.da.Server;
import org.openscada.opc.lib.da.SyncAccess;

public class UtgardTutorial2 {
     
    public static void main(String[] args) throws Exception {
 
        // 连接信息 
        final ConnectionInformation ci = new ConnectionInformation();
        
        ci.setHost("192.168.0.1");
        ci.setDomain("");
        ci.setUser("OPCUser");
        ci.setPassword("123456");
        
        // MatrikonOPC Server
        // ci.setClsid("F8582CF2-88FB-11D0-B850-00C0F0104305");
        // final String itemId = "u.u";//项的名字按实际

        // KEPServer
        ci.setClsid("7BC0CC8E-482C-47CA-ABDC-0FE7F9C6E729");
        final String itemId = "u.u.u";// 项的名字按实际
        // final String itemId = "通道 1.设备 1.标记 1";
        
        // create a new server
        final Server server = new Server(ci, Executors.newSingleThreadScheduledExecutor());
        try {
            // connect to server
            server.connect();
            // add sync access, poll every 500 ms
            final AccessBase access = new SyncAccess(server, 500);
            access.addItem(itemId, new DataCallback() {
                @Override
                public void changed(Item item, ItemState state) {
                    // also dump value
                    try {
                        if (state.getValue().getType() == JIVariant.VT_UI4) {
                            System.out.println("<<< " + state + " / value = " + state.getValue().getObjectAsUnsigned().getValue());
                        } else {
                            System.out.println("<<< " + state + " / value = " + state.getValue().getObject());
                        }
                    } catch (JIException e) {
                        e.printStackTrace();
                    }
                }
            });
 
            // Add a new group
            final Group group = server.addGroup("test");
            // Add a new item to the group
            final Item item = group.addItem(itemId);
 
            // start reading
            access.bind();
 
            // add a thread for writing a value every 3 seconds
            //写入线程,至于为什么要用线程,要一直写,,如果只写一次就不用写线程了
            ScheduledExecutorService writeThread = Executors.newSingleThreadScheduledExecutor();
            writeThread.scheduleWithFixedDelay(new Runnable() {
                @Override
                public void run() {
                    final JIVariant value = new JIVariant("24");//一直写入24
                    try {
                        System.out.println(">>> " + "writing value " + "24");
                        item.write(value);
                    } catch (JIException e) {
                        e.printStackTrace();
                    }
                }
            }, 5, 3, TimeUnit.SECONDS);
 
            // wait a little bit 
            Thread.sleep(20 * 1000);
            writeThread.shutdownNow();
            // stop reading
            access.unbind();
        } catch (final JIException e) {
            System.out.println(String.format("%08X: %s", e.getErrorCode(), server.getErrorMessage(e.getErrorCode())));
        }
    }
}

转载请注明出处:https://blog.csdn.net/beiwulou2994

猜你喜欢

转载自blog.csdn.net/beiwulou2994/article/details/81589371