手機、電腦遠程控制PLC(S7協(xié)議與MQTT)
前言:S7 協(xié)議是?SIEMENS S7 系列產(chǎn)品之間通訊使用的標準協(xié)議,本文用JAVA實現(xiàn)與PLC以及服務(wù)器通訊,實現(xiàn)遠程控制,控制原理就是用JAVA去讀寫PLC數(shù)據(jù)塊,然后結(jié)合MQTT協(xié)議與服務(wù)器通訊,可以實現(xiàn)對PLC的遠程控制與數(shù)據(jù)采集。C#、python也可以實現(xiàn)與plc通訊,本文用JAVA
0x0軟件
西門子1200PLC(用官方的仿真也行)、博圖v15、eclipse、EMQX(MQTT服務(wù)器)、寶塔(服務(wù)器運維)、jdk、maven
1x0MQTT服務(wù)器搭建
2x0安裝博圖v15、仿真、nettoplcsim
保姆教程:https://blog.csdn.net/jjhghh/article/details/126491434#t0
nettoplcsim(有真機的不用安裝,這個用來將仿真機的IP地址轉(zhuǎn)換出來)
鏈接:https://pan.baidu.com/s/1Yvr69Jb0PVa13kaZQ9wSJA 提取碼:31s2
3x0eclipse安裝與配置maven
java環(huán)境配置:
https://blog.csdn.net/qq_38436214/article/details/105071088
eclipse安裝:
https://blog.csdn.net/rothschild666/article/details/82914600
maven配置:
https://blog.csdn.net/qq_43663493/article/details/104663638
4x0創(chuàng)建博圖項目
新建數(shù)據(jù)塊

點擊設(shè)備屬性勾選允許來自遠程對象的put/get通訊訪問

右鍵數(shù)據(jù)塊勾選掉優(yōu)化塊的訪問

啟動仿真將程序?qū)懭?/p>
打開nettoplcsim轉(zhuǎn)換IP地址
點擊add

點擊和你同網(wǎng)段的地址

選擇你仿真plc的地址一般都是192.168.0.1

點擊開始

5x0JAVA端采集程序與通訊程序
新建maven項目

選擇maven project

勾選最上面這個

按要求填寫

添加POM依賴庫
<dependencies>
<dependency>
<groupId>com.github.s7connector</groupId>
<artifactId>s7connector</artifactId>
<version>2.1</version>
</dependency>
<dependency>
<groupId>org.eclipse.paho</groupId>
<artifactId>org.eclipse.paho.client.mqttv3</artifactId>
<version>1.2.0</version>
</dependency>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20211205</version>
</dependency>
</dependencies>

連接plc代碼
public static S7Connector connector; // 初始化PLC連接對象
connector = S7ConnectorFactory.buildTCPConnector().withHost("192.168.8.98") // PLC 的 IP 地址
.withRack(0) // 架機號,可選
.withSlot(1) // 插槽號,可選
.build();
讀取數(shù)據(jù)代碼
byte[] PlcData = connector.read(DaveArea.DB, // 選擇數(shù)據(jù)區(qū)塊
1, // 區(qū)塊編號
2, // 數(shù)據(jù)值長度 int長度2
0); // 開始位置 偏移量
int plcin = intCon.extract(new Integer(0).getClass(), PlcData, 0, 0);
System.out.println(plcin);
寫入數(shù)據(jù)塊代碼
byte[] data = new byte[2];
int i = 0;//需要寫入的值
ByteBuffer buffer = ByteBuffer.allocate(4).putInt(i);
data[0] = buffer.get(2);
data[1] = buffer.get(3);
connector.write(DaveArea.DB, 1, 0, data);
連接MQTT代碼
public static String brokerUrl = "tcp://cxxxxxx:1883";//MQTT服務(wù)器地址
? ?public static String clientId = "mqtt-subscriber";//連接ID,相當于備注
? ?public static String topic = "top";//訂閱的主題
MqttClient client = new MqttClient(brokerUrl, clientId);
? ? ? ? ? ?client.setCallback(new postt());
? ? ? ? ? ?client.connect();
? ? ? ? ? ?client.subscribe(topic);
完整代碼:
package ddd;
import java.nio.ByteBuffer;
import org.eclipse.paho.client.mqttv3.*;
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttCallback;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import com.github.s7connector.api.DaveArea;
import com.github.s7connector.api.S7Connector;
import com.github.s7connector.api.factory.S7ConnectorFactory;
import org.json.JSONObject;
public class postt implements MqttCallback{
? ?public static S7Connector connector; // 初始化PLC連接對象
? ?public static String brokerUrl = "tcp://xxxxxxxxx:1883";//MQTT服務(wù)器地址
? ?public static String clientId = "mqtt-subscriber";//連接ID,相當于備注
? ?public static String topic = "top";//訂閱的主題
? ?public static void main(String[] args) throws MqttException {
? ? ? ? ? ?// 連接到 PLC
? ? ? ? ? ?connector = S7ConnectorFactory.buildTCPConnector().withHost("192.168.8.98") // PLC 的 IP 地址
? ? ? ? ? ? ? ? ? ?.withRack(0) // 架機號,可選
? ? ? ? ? ? ? ? ? ?.withSlot(1) // 插槽號,可選
? ? ? ? ? ? ? ? ? ?.build();
? ? ? ? ? ? //連接到 MQTT 服務(wù)器
? ? ? ? ? ?MqttClient client = new MqttClient(brokerUrl, clientId);
? ? ? ? ? ?client.setCallback(new postt());
? ? ? ? ? ?client.connect();
? ? ? ? ? ?client.subscribe(topic);
? ?}
? ?//PLC寫入數(shù)據(jù)
? ?public void readplc(int a,int b,int c) {
? ? ? ?byte[] data = new byte[2];
? ? ? ?int i = b;//需要寫入的值
? ? ? ?ByteBuffer buffer = ByteBuffer.allocate(4).putInt(i);
? ? ? ?data[0] = buffer.get(2);
? ? ? ?data[1] = buffer.get(3);
? ? ? ?connector.write(DaveArea.DB, c, a, data);
? ?}
? ?//斷連回調(diào)
? ?public void connectionLost(Throwable throwable) {
? ? ? ?System.out.println("連接丟失:" + throwable.getMessage());
? ?}
? ?//收到消息的回調(diào)
? ?public void messageArrived(String topic, MqttMessage message) throws Exception {
? ? ? ?System.out.println("收到消息訂閱主題" + topic + ": " + new String(message.getPayload()));
? ? ? ?JSONObject json = new JSONObject(new String(message.getPayload()));
? ? ? ?int wen = json.getInt("wen");
? ? ? ?System.out.print("解析成功:"+wen);
? ? ? ?readplc(0,wen,1);//將值寫入
? ?}
? ?//消息發(fā)送成功的回調(diào)
? ?public void deliveryComplete(IMqttDeliveryToken token) {
?
? ?}
}
打開在線的webmqtt測試工具,成功接收并解析到結(jié)果

????測試成功寫入plc,成功

最后:
通過MQTT結(jié)合S7可以實現(xiàn)Web端、微信小程序端、Android端、IOS端對PLC遠程控制以及采集PLC數(shù)據(jù),可以結(jié)合硬件mqtt網(wǎng)關(guān),然后前端用charts和threejs即可實現(xiàn)大數(shù)據(jù)看板與工廠數(shù)字孿生構(gòu)建數(shù)字化工廠