Procházet zdrojové kódy

端口,条码高低位

wangxichen před 8 hodinami
rodič
revize
0826602836

+ 175 - 0
src/com/mes/plc/HeliumFlow.java

@@ -0,0 +1,175 @@
+package com.mes.plc;
+
+import com.alibaba.fastjson2.JSONObject;
+import com.mes.component.StationPanel;
+import com.mes.ui.DataUtil;
+import com.mes.ui.MesClient;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * 氦检单工位流程:
+ * M205 上升沿 → 读条码 → 复位 M205 → 校验 → 写 M206
+ * M207 上升沿 → 清 M206 → 检测中
+ * M208 上升沿 → 读泄露 → 显示结果
+ *
+ * 开始/结束信号是保持电平,只在 0→1 时触发
+ */
+public class HeliumFlow {
+
+    private static final Logger log = LoggerFactory.getLogger(HeliumFlow.class);
+
+    private final int station;
+    private final McPlcClient plc;
+    private final StationPanel ui;
+
+    private final String scanAddr;
+    private final String allowAddr;
+    private final String startAddr;
+    private final String endAddr;
+    private final String leakAddr;
+    private final String codeAddr;
+
+    private boolean initialized = false;
+    private boolean lastScan = false; // 启动时若已扫码,也要处理
+    private boolean lastStart;
+    private boolean lastEnd;
+    private String currentSn = "";
+
+    public HeliumFlow(int station, McPlcClient plc, StationPanel ui,
+                      String scanAddr, String allowAddr, String startAddr, String endAddr,
+                      String leakAddr, String codeAddr) {
+        this.station = station;
+        this.plc = plc;
+        this.ui = ui;
+        this.scanAddr = scanAddr;
+        this.allowAddr = allowAddr;
+        this.startAddr = startAddr;
+        this.endAddr = endAddr;
+        this.leakAddr = leakAddr;
+        this.codeAddr = codeAddr;
+    }
+
+    private String name() {
+        return station == 2 ? "B" : "A";
+    }
+
+    /** 启动时同步开始/结束信号的当前电平,避免误触发 */
+    private void init() {
+        Boolean start = plc.tryReadBit(startAddr);
+        Boolean end = plc.tryReadBit(endAddr);
+        if (start == null || end == null) {
+            return; // 通信未就绪,下轮再同步
+        }
+        lastStart = start;
+        lastEnd = end;
+        initialized = true;
+        log.info(name() + " 工位流程初始化: start=" + start + " end=" + end);
+    }
+
+    public void poll() {
+        if (!initialized) {
+            init();
+            return;
+        }
+        if (!plc.isConnected()) {
+            initialized = false;
+            return;
+        }
+
+        Boolean scan = plc.tryReadBit(scanAddr);
+        Boolean start = plc.tryReadBit(startAddr);
+        Boolean end = plc.tryReadBit(endAddr);
+        if (scan == null || start == null || end == null) {
+            return; // 本轮通信异常,跳过
+        }
+
+        if (scan && !lastScan) {
+            onScan();
+        }
+        lastScan = scan;
+
+        if (start && !lastStart) {
+            onStart();
+        }
+        lastStart = start;
+
+        if (end && !lastEnd) {
+            onEnd();
+        }
+        lastEnd = end;
+    }
+
+    /** 扫码:读码 → 复位扫码信号 → 查质量 → 写允许位 */
+    private void onScan() {
+        String code = plc.readString(codeAddr, MesClient.plc_code_len);
+        if (code == null || code.isEmpty()) {
+            MesClient.addLog(name() + " 扫码信号已到,但条码为空,等待重试");
+            return;
+        }
+
+        currentSn = code;
+        ui.setCode(code);
+        ui.setSignal(StationPanel.SIG_SCAN, true);
+        ui.setSignal(StationPanel.SIG_CODE, true);
+        ui.setState("校验中", StationPanel.STATE_BUSY);
+        MesClient.addLog(name() + " 读到条码 " + code);
+
+        // 读码成功后复位扫码成功信号
+        plc.writeBit(scanAddr, false);
+
+        MesClient.getUser();
+        JSONObject ret = DataUtil.checkQuality(code, MesClient.user20);
+        boolean allow = ret != null && "true".equalsIgnoreCase(String.valueOf(ret.get("result")));
+        plc.writeBit(allowAddr, allow);
+        ui.setSignal(StationPanel.SIG_ALLOW, allow);
+
+        if (allow) {
+            ui.setState("允许运行", StationPanel.STATE_OK);
+            MesClient.addLog(name() + " 校验通过,允许运行");
+        } else {
+            currentSn = ""; // 禁止运行,不参与后续提交
+            ui.setState("禁止运行", StationPanel.STATE_NG);
+            String msg = ret == null ? "请求失败" : ret.getString("message");
+            MesClient.addLog(name() + " 禁止运行:" + msg);
+        }
+    }
+
+    /** 检测开始:清允许位,界面进入检测中 */
+    private void onStart() {
+        plc.writeBit(allowAddr, false);
+        ui.setSignal(StationPanel.SIG_ALLOW, false);
+        ui.setSignal(StationPanel.SIG_START, true);
+        ui.setState("检测中", StationPanel.STATE_RUN);
+        MesClient.addLog(name() + " 检测开始");
+    }
+
+    /** 检测结束:读泄露,提交结果 */
+    private void onEnd() {
+        String leak = plc.readString(leakAddr, 8);
+        ui.setData(null, leak);
+        ui.setSignal(StationPanel.SIG_LEAK, !leak.isEmpty());
+        ui.setSignal(StationPanel.SIG_END, true);
+        MesClient.addLog(name() + " 检测结束,泄露=" + leak);
+
+        if (currentSn.isEmpty()) {
+            MesClient.addLog(name() + " 无当前条码,跳过提交");
+            return;
+        }
+
+        // 设备判定结果点位待补,当前按 OK 提交
+        String result = "OK";
+        ui.setState("上传中", StationPanel.STATE_BUSY);
+        MesClient.getUser();
+        JSONObject ret = DataUtil.sendQuality(currentSn, result, MesClient.user20);
+        boolean ok = ret != null && "true".equalsIgnoreCase(String.valueOf(ret.get("result")));
+        if (ok) {
+            ui.setResult(result);
+            ui.setState("检测完成", StationPanel.STATE_OK);
+            MesClient.addLog(name() + " 结果已提交 " + currentSn + " " + result);
+        } else {
+            ui.setState("提交失败", StationPanel.STATE_NG);
+            MesClient.addLog(name() + " 结果提交失败:" + (ret == null ? "请求失败" : ret.getString("message")));
+        }
+    }
+}

+ 9 - 8
src/com/mes/plc/McPlcClient.java

@@ -59,13 +59,19 @@ public class McPlcClient {
 
     /** 读单个位,失败返回 false 并标记断开 */
     public synchronized boolean readBit(String address) {
+        Boolean v = tryReadBit(address);
+        return v != null && v;
+    }
+
+    /** 读单个位:成功返回 true/false,通信失败返回 null(调用方可跳过本轮) */
+    public synchronized Boolean tryReadBit(String address) {
         try {
             checkMc();
             McDeviceContent content = mc.readDeviceBatchInBit(McDeviceAddress.createBy(address, 1));
             return mc.getBooleansBy(content.getData()).get(0);
         } catch (Exception e) {
             onError("读 " + address, e);
-            return false;
+            return null;
         }
     }
 
@@ -85,7 +91,7 @@ public class McPlcClient {
 
     /**
      * 读 D 区字符串(ASCII/GBK),charCount 为字符数
-     * 三菱 D 区每个字存 2 个字符且字节序相反,这里做高低字节交换
+     * 现场 PLC 存的是正序,直接按字节转字符串
      */
     public synchronized String readString(String address, int charCount) {
         try {
@@ -93,12 +99,7 @@ public class McPlcClient {
             int words = (charCount + 1) / 2;
             McDeviceContent content = mc.readDeviceBatchInWord(McDeviceAddress.createBy(address, words));
             byte[] raw = content.getData();
-            byte[] swapped = new byte[raw.length];
-            for (int i = 0; i + 1 < raw.length; i += 2) {
-                swapped[i] = raw[i + 1];
-                swapped[i + 1] = raw[i];
-            }
-            String s = new String(swapped, "GBK");
+            String s = new String(raw, "GBK");
             int end = s.indexOf('\0');
             if (end >= 0) {
                 s = s.substring(0, end);

+ 32 - 2
src/com/mes/ui/MesClient.java

@@ -4,6 +4,7 @@ import com.alibaba.fastjson2.JSONObject;
 import com.mes.component.MesRadio;
 import com.mes.component.MesWebView;
 import com.mes.component.StationPanel;
+import com.mes.plc.HeliumFlow;
 import com.mes.plc.McPlcClient;
 import com.mes.util.DateLocalUtils;
 import com.mes.util.HttpUtils;
@@ -42,7 +43,7 @@ public class MesClient extends JFrame {
 
     // PLC(三菱 MC 3E)
     public static String plc_ip = "";
-    public static int plc_port = 3000;
+    public static int plc_port = 2500;
     public static String plc_a_code_addr = "D5000";
     public static String plc_b_code_addr = "D6000";
     public static int plc_code_len = 24;
@@ -128,7 +129,7 @@ public class MesClient extends JFrame {
         mes_line_sn = pro.getProperty("mes.line_sn");
         mes_gw_des = OprnoUtil.getGwDes(mes_line_sn,mes_gw);
         plc_ip = pro.getProperty("plc.ip", "").trim();
-        plc_port = Integer.parseInt(pro.getProperty("plc.port", "3000").trim());
+        plc_port = Integer.parseInt(pro.getProperty("plc.port", "2500").trim());
         plc_a_code_addr = pro.getProperty("plc.a.code_addr", "D5000").trim();
         plc_b_code_addr = pro.getProperty("plc.b.code_addr", "D6000").trim();
         plc_code_len = Integer.parseInt(pro.getProperty("plc.code_len", "24").trim());
@@ -631,6 +632,7 @@ public class MesClient extends JFrame {
                         String sig = "M205=" + plcClient.readBit("M205") + "  M215=" + plcClient.readBit("M215");
                         addLog(sig);
                         log.info("PLC 点位: " + sig);
+                        startFlows();
                     } else {
                         setPlcStatus(false);
                     }
@@ -646,6 +648,34 @@ public class MesClient extends JFrame {
         }, 0, 3000);
     }
 
+    public static HeliumFlow flowA;
+    public static HeliumFlow flowB;
+    public static java.util.Timer flowTimer;
+
+    /** PLC 连接成功后启动 A/B 工位流程轮询 */
+    private static void startFlows() {
+        if (flowTimer != null) {
+            return;
+        }
+        flowA = new HeliumFlow(1, plcClient, stationA,
+                "M205", "M206", "M207", "M208", "D200", plc_a_code_addr);
+        flowB = new HeliumFlow(2, plcClient, stationB,
+                "M215", "M216", "M217", "M218", "D210", plc_b_code_addr);
+        flowTimer = new java.util.Timer(true);
+        flowTimer.schedule(new TimerTask() {
+            @Override
+            public void run() {
+                try {
+                    flowA.poll();
+                    flowB.poll();
+                } catch (Exception e) {
+                    log.info("氦检流程异常: " + e.getMessage());
+                }
+            }
+        }, 500, 500);
+        addLog("氦检流程已启动");
+    }
+
     public static void getMaterailData(){
         try{
             JSONObject retObj = DataUtil.getBindMaterail();

+ 1 - 1
src/resources/config/config.properties

@@ -5,7 +5,7 @@ mes.line_sn=CZ060
 
 # PLC MC 3E
 plc.ip=192.168.3.120
-plc.port=3000
+plc.port=2500
 # plc sacn code
 plc.a.code_addr=D5000
 plc.b.code_addr=D6000