wangxichen 3 дней назад
Родитель
Сommit
b29c958e77
2 измененных файлов с 121 добавлено и 26 удалено
  1. 63 2
      src/com/mes/ui/MesClient.java
  2. 58 24
      src/com/mes/ui/PlcUtil.java

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

@@ -85,9 +85,21 @@ public class MesClient extends JFrame {
 
     public static JLabel fxlabel;
 
-    public static S7PLC s7PLC = new S7PLC(EPlcType.S1500, "192.168.90.91");
+    // 信号灯
+    public static JLabel feedingLight;
+    public static JLabel replyLight;
+    public static JLabel plcCodeLabel; // PLC 码内容回显(DB5000.260)
+    public static ImageIcon imageGreen;
+    public static ImageIcon imageGray;
+    public static Timer lightTimer;
+
+    public static S7PLC s7PLC = new S7PLC(EPlcType.S1500, "192.168.90.86");
 
     public static int dateLoading = 0;
+    // 已取码标志:取到码后锁住,等本件完成或刷新工件后才允许取下一件
+    public static boolean qrLoaded = false;
+    // 本件工位结果已提交标志:PLC 反馈复位后才允许下一轮提交
+    public static boolean resultSubmitted = false;
 
     public static void main(String[] args) {
 
@@ -196,6 +208,7 @@ public class MesClient extends JFrame {
         check_quality_result = false;
         planStop = false;
         nextRetryTime = 0;
+        qrLoaded = false;
         MesClient.finish_ok_bt.setEnabled(false);
         MesClient.finish_ng_bt.setEnabled(false);
         product_sn.setText("");
@@ -510,12 +523,34 @@ public class MesClient extends JFrame {
 
         fxlabel = new JLabel("该工件为返修件,请仔细检查");
         fxlabel.setFont(new Font("微软雅黑", Font.PLAIN, 38));
-        fxlabel.setBounds(81, 170, 810, 70);
+        fxlabel.setBounds(81, 190, 810, 70);
         fxlabel.setForeground(Color.RED);
         fxlabel.setHorizontalAlignment(SwingConstants.CENTER);
         fxlabel.setVisible(false);
         indexPanelA.add(fxlabel);
 
+        // 信号灯:请求镭雕码、二维码接收反馈
+        imageGreen = new ImageIcon(MesClient.class.getResource("/bg/green_dot.png"));
+        imageGreen.setImage(imageGreen.getImage().getScaledInstance(24, 24, Image.SCALE_SMOOTH));
+        imageGray = new ImageIcon(MesClient.class.getResource("/bg/grey_dot.png"));
+        imageGray.setImage(imageGray.getImage().getScaledInstance(24, 24, Image.SCALE_SMOOTH));
+
+        feedingLight = new JLabel("请求镭雕码(DB5000.0.4)", imageGray, SwingConstants.LEFT);
+        feedingLight.setFont(new Font("微软雅黑", Font.PLAIN, 14));
+        feedingLight.setBounds(81, 150, 400, 30);
+        indexPanelA.add(feedingLight);
+
+        replyLight = new JLabel("二维码接收反馈(DB5000.0.5)", imageGray, SwingConstants.LEFT);
+        replyLight.setFont(new Font("微软雅黑", Font.PLAIN, 14));
+        replyLight.setBounds(481, 150, 400, 30);
+        indexPanelA.add(replyLight);
+
+        // PLC 码内容回显
+        plcCodeLabel = new JLabel("PLC码(DB5000.260):-");
+        plcCodeLabel.setFont(new Font("微软雅黑", Font.PLAIN, 18));
+        plcCodeLabel.setBounds(81, 270, 810, 35);
+        indexPanelA.add(plcCodeLabel);
+
         finish_ok_bt = new JButton("OK");
         finish_ok_bt.setEnabled(false);
         finish_ok_bt.addActionListener(new ActionListener() {
@@ -618,6 +653,32 @@ public class MesClient extends JFrame {
                 }
             }
         });
+
+        startLightTimer();
+    }
+
+    // 信号灯单独刷新,与业务轮询解耦
+    public static void startLightTimer() {
+        if(lightTimer != null) {
+            lightTimer.cancel();
+        }
+        lightTimer = new Timer();
+        lightTimer.schedule(new TimerTask() {
+            public void run() {
+                try{
+                    boolean feeding = PlcUtil.getFeeding(s7PLC);
+                    boolean reply = PlcUtil.getReply(s7PLC);
+                    String plcCode = PlcUtil.getQrcode(s7PLC);
+                    SwingUtilities.invokeLater(() -> {
+                        feedingLight.setIcon(feeding ? imageGreen : imageGray);
+                        replyLight.setIcon(reply ? imageGreen : imageGray);
+                        plcCodeLabel.setText("PLC码(DB5000.260):" + (plcCode == null || plcCode.isEmpty() ? "-" : plcCode));
+                    });
+                }catch (Throwable t) {
+                    log.error("信号灯刷新异常: " + t.getMessage());
+                }
+            }
+        }, 500, 1000);
     }
 
     public static void setMenuStatus(String msg,int error){

+ 58 - 24
src/com/mes/ui/PlcUtil.java

@@ -5,51 +5,78 @@ import com.github.xingshuangs.iot.protocol.s7.service.S7PLC;
 
 public class PlcUtil {
 
+    // PLC 连接同时被取码线程和信号灯线程使用,读写统一加锁,避免并发导致读写失败
+    private static final Object PLC_LOCK = new Object();
+
     // 上料请求镭雕码内容
     public static Boolean getFeeding(S7PLC s7PLC){
-        try{
-            return s7PLC.readBoolean("DB5000.0.4");
-        }catch (Exception e){
-            e.printStackTrace();
-            return false;
+        synchronized (PLC_LOCK) {
+            try{
+                return s7PLC.readBoolean("DB5000.0.4");
+            }catch (Exception e){
+                e.printStackTrace();
+                return false;
+            }
         }
     }
 
     // 二维码接收反馈
     public static Boolean getReply(S7PLC s7PLC){
-        try{
-            return s7PLC.readBoolean("DB5000.0.5");
-        }catch (Exception e){
-            e.printStackTrace();
-            return false;
+        synchronized (PLC_LOCK) {
+            try{
+                return s7PLC.readBoolean("DB5000.0.5");
+            }catch (Exception e){
+                e.printStackTrace();
+                return false;
+            }
         }
     }
 
     // 获取码内容
     public static String getQrcode(S7PLC s7PLC){
-        try{
-            return s7PLC.readString("DB5000.260",28).trim();
-        }catch (Exception e){
-            e.printStackTrace();
-            return "";
+        synchronized (PLC_LOCK) {
+            try{
+                return s7PLC.readString("DB5000.260",28).trim();
+            }catch (Exception e){
+                e.printStackTrace();
+                return "";
+            }
         }
     }
 
-    // 设置码内容
+    // 设置码内容:写完后立即读回校验
     public static Boolean setQrcode(S7PLC s7PLC,String sn){
-        try{
-            s7PLC.writeString("DB5000.260", sn);
-            return true;
-        }catch (Exception e){
-            e.printStackTrace();
-            return false;
+        synchronized (PLC_LOCK) {
+            try{
+                s7PLC.writeString("DB5000.260", sn);
+                String readBack = s7PLC.readString("DB5000.260",28).trim();
+                MesClient.log.info("写PLC码: {}, 读回: {}", sn, readBack);
+                return true;
+            }catch (Exception e){
+                MesClient.log.error("写PLC码失败: " + sn, e);
+                return false;
+            }
         }
     }
 
     public static void monitorPlc(S7PLC s7PLC){
         Boolean feeding = getFeeding(s7PLC);
+        Boolean reply = getReply(s7PLC);
+
+        // 反馈复位后,允许下一轮提交
+        if(!reply){
+            MesClient.resultSubmitted = false;
+        }
+
+        // 二维码反馈:打码完成,结束本轮(只打码,不提交工位结果)
+        if(reply && MesClient.qrLoaded && !MesClient.resultSubmitted){
+            MesClient.resultSubmitted = true;
+            MesClient.resetScanA();
+            MesClient.setMenuStatus("打码完成,等待下一件",0);
+        }
+
         // 计划已完成/无计划时不再自动取码;失败后按间隔重试
-        if (feeding && MesClient.dateLoading == 0 && !MesClient.planStop
+        if (feeding && MesClient.dateLoading == 0 && !MesClient.qrLoaded && !MesClient.planStop
                 && System.currentTimeMillis() >= MesClient.nextRetryTime){
             MesClient.dateLoading = 1;
             JSONObject retObj = DataUtil.getHmbContent(MesClient.user_menu.getText().trim());
@@ -67,7 +94,14 @@ public class PlcUtil {
                     MesClient.currentPn = pn;
                     MesClient.pnLabel.setText(pn);
                 }
-                setQrcode(s7PLC,hmb);
+                if(!setQrcode(s7PLC,hmb)){
+                    MesClient.setMenuStatus("写入PLC失败,请检查PLC连接",-1);
+                    MesClient.nextRetryTime = System.currentTimeMillis() + 10000;
+                    MesClient.dateLoading = 0;
+                    return;
+                }
+                // 锁住,本件未完成前不再取新码
+                MesClient.qrLoaded = true;
                 MesClient.dateLoading = 0;
                 MesClient.product_sn.setText(hmb);
                 MesClient.mesClientFrame.repaint();