|
|
@@ -0,0 +1,560 @@
|
|
|
+package com.mes.test;
|
|
|
+
|
|
|
+import com.github.xingshuangs.iot.protocol.modbus.service.ModbusTcp;
|
|
|
+import org.slf4j.Logger;
|
|
|
+import org.slf4j.LoggerFactory;
|
|
|
+
|
|
|
+import java.util.Scanner;
|
|
|
+
|
|
|
+/**
|
|
|
+ * PLC调试测试类 - 用于测试拉铆枪点位读取和启停控制
|
|
|
+ *
|
|
|
+ * 功能:
|
|
|
+ * 1. 测试拉铆枪的各个数据点位能否正常读取
|
|
|
+ * 2. 测试拉铆枪启停控制点位能否正常读写
|
|
|
+ *
|
|
|
+ * 拉铆枪启停控制点位说明:
|
|
|
+ * - 远程开机点位: 3328 (Coil)
|
|
|
+ * - 远程关机点位: 3079 (Coil)
|
|
|
+ * - 控制模式: 1090 (0=本地, 1=远程)
|
|
|
+ * - 系统运行中: 3128 (Coil)
|
|
|
+ */
|
|
|
+public class PlcDebugTest {
|
|
|
+
|
|
|
+ private static final Logger log = LoggerFactory.getLogger(PlcDebugTest.class);
|
|
|
+
|
|
|
+ // PLC连接配置
|
|
|
+ private static final String PLC_A_IP = "192.168.0.6";
|
|
|
+ private static final String PLC_B_IP = "192.168.0.16";
|
|
|
+ private static final int UNIT_ID = 1;
|
|
|
+
|
|
|
+ private static ModbusTcp plcA;
|
|
|
+ private static ModbusTcp plcB;
|
|
|
+ private static Scanner scanner;
|
|
|
+
|
|
|
+ public static void main(String[] args) {
|
|
|
+ scanner = new Scanner(System.in);
|
|
|
+
|
|
|
+ log.info("=== PLC调试测试工具启动 ===");
|
|
|
+
|
|
|
+ try {
|
|
|
+ // 初始化PLC连接
|
|
|
+ initPlcConnections();
|
|
|
+
|
|
|
+ // 显示主菜单
|
|
|
+ showMainMenu();
|
|
|
+
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("程序运行出错: " + e.getMessage(), e);
|
|
|
+ } finally {
|
|
|
+ closeConnections();
|
|
|
+ scanner.close();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 初始化PLC连接
|
|
|
+ */
|
|
|
+ private static void initPlcConnections() {
|
|
|
+ try {
|
|
|
+ log.info("正在连接PLC A (" + PLC_A_IP + ")...");
|
|
|
+ plcA = new ModbusTcp(UNIT_ID, PLC_A_IP);
|
|
|
+ plcA.setConnectTimeout(1000);
|
|
|
+ plcA.setReceiveTimeout(1000);
|
|
|
+ log.info("PLC A连接成功");
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("PLC A连接失败: " + e.getMessage());
|
|
|
+ }
|
|
|
+
|
|
|
+ try {
|
|
|
+ log.info("正在连接PLC B (" + PLC_B_IP + ")...");
|
|
|
+ plcB = new ModbusTcp(UNIT_ID, PLC_B_IP);
|
|
|
+ plcB.setConnectTimeout(1000);
|
|
|
+ plcB.setReceiveTimeout(1000);
|
|
|
+ log.info("PLC B连接成功");
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("PLC B连接失败: " + e.getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 显示主菜单
|
|
|
+ */
|
|
|
+ private static void showMainMenu() {
|
|
|
+ while (true) {
|
|
|
+ System.out.println("\n========================================");
|
|
|
+ System.out.println(" PLC调试测试工具主菜单");
|
|
|
+ System.out.println("========================================");
|
|
|
+ System.out.println("1. 读取拉铆枪A当前数据");
|
|
|
+ System.out.println("2. 读取拉铆枪B当前数据");
|
|
|
+ System.out.println("3. 启动拉铆枪A心跳(模拟质量检查合格)");
|
|
|
+ System.out.println("4. 停止拉铆枪A心跳(模拟工作完成)");
|
|
|
+ System.out.println("5. 启动拉铆枪B心跳(模拟质量检查合格)");
|
|
|
+ System.out.println("6. 停止拉铆枪B心跳(模拟工作完成)");
|
|
|
+ System.out.println("7. 查看拉铆枪A心跳状态");
|
|
|
+ System.out.println("8. 查看拉铆枪B心跳状态");
|
|
|
+ System.out.println("0. 退出");
|
|
|
+ System.out.println("========================================");
|
|
|
+ System.out.print("请选择功能 (0-8): ");
|
|
|
+
|
|
|
+ String choice = scanner.nextLine().trim();
|
|
|
+
|
|
|
+ switch (choice) {
|
|
|
+ case "1":
|
|
|
+ testRivetGunDataA();
|
|
|
+ break;
|
|
|
+ case "2":
|
|
|
+ testRivetGunDataB();
|
|
|
+ break;
|
|
|
+ case "3":
|
|
|
+ startHeartBeatA();
|
|
|
+ break;
|
|
|
+ case "4":
|
|
|
+ stopHeartBeatA();
|
|
|
+ break;
|
|
|
+ case "5":
|
|
|
+ startHeartBeatB();
|
|
|
+ break;
|
|
|
+ case "6":
|
|
|
+ stopHeartBeatB();
|
|
|
+ break;
|
|
|
+ case "7":
|
|
|
+ testHeartBeatControlA();
|
|
|
+ break;
|
|
|
+ case "8":
|
|
|
+ testHeartBeatControlB();
|
|
|
+ break;
|
|
|
+ case "0":
|
|
|
+ log.info("退出程序");
|
|
|
+ return;
|
|
|
+ default:
|
|
|
+ System.out.println("无效的选择,请重新输入!");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 测试拉铆枪A的数据点位读取
|
|
|
+ */
|
|
|
+ private static void testRivetGunDataA() {
|
|
|
+ if (plcA == null) {
|
|
|
+ System.out.println("错误: PLC A未连接!");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ System.out.println("\n=== 测试拉铆枪A数据点位 ===");
|
|
|
+
|
|
|
+ try {
|
|
|
+ // 心跳连接
|
|
|
+ short heartBeatConn = plcA.readInt16(4160);
|
|
|
+ System.out.println("心跳连接 (地址4160): " + heartBeatConn);
|
|
|
+
|
|
|
+ // 心跳间隔
|
|
|
+ short heartBeatInterval = plcA.readInt16(4170);
|
|
|
+ System.out.println("心跳间隔 (地址4170): " + heartBeatInterval + " (超时后设备禁止运行)");
|
|
|
+
|
|
|
+ // 作业模式
|
|
|
+ short workMode = plcA.readInt16(1092);
|
|
|
+ System.out.println("作业模式 (地址1092): " + workMode);
|
|
|
+
|
|
|
+ // 最大拉力 F-out
|
|
|
+ int fOut = plcA.readInt32(4112);
|
|
|
+ System.out.println("F-out最大拉力 (地址4112): " + fOut + " (实际值: " + (fOut/1000.0) + " kN)");
|
|
|
+
|
|
|
+ // S-out对应位移
|
|
|
+ int sOut = plcA.readInt32(4120);
|
|
|
+ System.out.println("S-out对应位移 (地址4120): " + sOut + " (实际值: " + (sOut/1000.0) + " mm)");
|
|
|
+
|
|
|
+ // F-min最小拉力
|
|
|
+ int fMin = plcA.readInt32(4116);
|
|
|
+ System.out.println("F-min最小拉力 (地址4116): " + fMin + " (实际值: " + (fMin/1000.0) + " kN)");
|
|
|
+
|
|
|
+ // F-max最大拉力
|
|
|
+ int fMax = plcA.readInt32(4114);
|
|
|
+ System.out.println("F-max最大拉力 (地址4114): " + fMax + " (实际值: " + (fMax/1000.0) + " kN)");
|
|
|
+
|
|
|
+ // S-min最小位移
|
|
|
+ int sMin = plcA.readInt32(4124);
|
|
|
+ System.out.println("S-min最小位移 (地址4124): " + sMin + " (实际值: " + (sMin/1000.0) + " mm)");
|
|
|
+
|
|
|
+ // S-max最大位移
|
|
|
+ int sMax = plcA.readInt32(4126);
|
|
|
+ System.out.println("S-max最大位移 (地址4126): " + sMax + " (实际值: " + (sMax/1000.0) + " mm)");
|
|
|
+
|
|
|
+ // 预设数量/任务数量
|
|
|
+ int taskNum = plcA.readInt32(4534);
|
|
|
+ System.out.println("预设数量 (地址4534): " + taskNum);
|
|
|
+
|
|
|
+ // 已打数量/当前数量
|
|
|
+ short curNum = plcA.readInt16(66);
|
|
|
+ System.out.println("已打数量 (地址66): " + curNum);
|
|
|
+
|
|
|
+ // 合格数量
|
|
|
+ short qualifiedNum = plcA.readInt16(68);
|
|
|
+ System.out.println("合格数量 (地址68): " + qualifiedNum);
|
|
|
+
|
|
|
+ // 质量状态
|
|
|
+ short qualityStatus = plcA.readInt16(1072);
|
|
|
+ System.out.println("质量状态 (地址1072): " + qualityStatus);
|
|
|
+
|
|
|
+ System.out.println("\n✓ 拉铆枪A数据点位读取成功!");
|
|
|
+
|
|
|
+ } catch (Exception e) {
|
|
|
+ System.out.println("✗ 读取失败: " + e.getMessage());
|
|
|
+ log.error("读取拉铆枪A数据失败", e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 测试拉铆枪B的数据点位读取
|
|
|
+ */
|
|
|
+ private static void testRivetGunDataB() {
|
|
|
+ if (plcB == null) {
|
|
|
+ System.out.println("错误: PLC B未连接!");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ System.out.println("\n=== 测试拉铆枪B数据点位 ===");
|
|
|
+
|
|
|
+ try {
|
|
|
+ // 心跳连接
|
|
|
+ short heartBeatConn = plcB.readInt16(4160);
|
|
|
+ System.out.println("心跳连接 (地址4160): " + heartBeatConn);
|
|
|
+
|
|
|
+ // 心跳间隔
|
|
|
+ short heartBeatInterval = plcB.readInt16(4170);
|
|
|
+ System.out.println("心跳间隔 (地址4170): " + heartBeatInterval + " (超时后设备禁止运行)");
|
|
|
+
|
|
|
+ // 作业模式
|
|
|
+ short workMode = plcB.readInt16(1092);
|
|
|
+ System.out.println("作业模式 (地址1092): " + workMode);
|
|
|
+
|
|
|
+ // 最大拉力 F-out
|
|
|
+ int fOut = plcB.readInt32(4112);
|
|
|
+ System.out.println("F-out最大拉力 (地址4112): " + fOut + " (实际值: " + (fOut/1000.0) + " kN)");
|
|
|
+
|
|
|
+ // S-out对应位移
|
|
|
+ int sOut = plcB.readInt32(4120);
|
|
|
+ System.out.println("S-out对应位移 (地址4120): " + sOut + " (实际值: " + (sOut/1000.0) + " mm)");
|
|
|
+
|
|
|
+ // F-min最小拉力
|
|
|
+ int fMin = plcB.readInt32(4116);
|
|
|
+ System.out.println("F-min最小拉力 (地址4116): " + fMin + " (实际值: " + (fMin/1000.0) + " kN)");
|
|
|
+
|
|
|
+ // F-max最大拉力
|
|
|
+ int fMax = plcB.readInt32(4114);
|
|
|
+ System.out.println("F-max最大拉力 (地址4114): " + fMax + " (实际值: " + (fMax/1000.0) + " kN)");
|
|
|
+
|
|
|
+ // S-min最小位移
|
|
|
+ int sMin = plcB.readInt32(4124);
|
|
|
+ System.out.println("S-min最小位移 (地址4124): " + sMin + " (实际值: " + (sMin/1000.0) + " mm)");
|
|
|
+
|
|
|
+ // S-max最大位移
|
|
|
+ int sMax = plcB.readInt32(4126);
|
|
|
+ System.out.println("S-max最大位移 (地址4126): " + sMax + " (实际值: " + (sMax/1000.0) + " mm)");
|
|
|
+
|
|
|
+ // 预设数量/任务数量
|
|
|
+ int taskNum = plcB.readInt32(4534);
|
|
|
+ System.out.println("预设数量 (地址4534): " + taskNum);
|
|
|
+
|
|
|
+ // 已打数量/当前数量
|
|
|
+ short curNum = plcB.readInt16(1136);
|
|
|
+ System.out.println("已打数量 (地址1136): " + curNum);
|
|
|
+
|
|
|
+ // 合格数量
|
|
|
+ short qualifiedNum = plcB.readInt16(68);
|
|
|
+ System.out.println("合格数量 (地址68): " + qualifiedNum);
|
|
|
+
|
|
|
+ // 质量状态
|
|
|
+ short qualityStatus = plcB.readInt16(1072);
|
|
|
+ System.out.println("质量状态 (地址1072): " + qualityStatus);
|
|
|
+
|
|
|
+ System.out.println("\n✓ 拉铆枪B数据点位读取成功!");
|
|
|
+
|
|
|
+ } catch (Exception e) {
|
|
|
+ System.out.println("✗ 读取失败: " + e.getMessage());
|
|
|
+ log.error("读取拉铆枪B数据失败", e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 心跳定时器
|
|
|
+ private static java.util.Timer heartBeatTimerA;
|
|
|
+ private static java.util.Timer heartBeatTimerB;
|
|
|
+ private static boolean heartBeatFlagA = false;
|
|
|
+ private static boolean heartBeatFlagB = false;
|
|
|
+ private static short heartBeatValueA = 1; // 心跳值,在1和2之间切换
|
|
|
+ private static short heartBeatValueB = 1; // 心跳值,在1和2之间切换
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 启动拉铆枪A心跳 - 模拟质量检查合格后启动
|
|
|
+ */
|
|
|
+ private static void startHeartBeatA() {
|
|
|
+ if (plcA == null) {
|
|
|
+ System.out.println("错误: PLC A未连接!");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ System.out.println("\n=== 启动拉铆枪A心跳 ===");
|
|
|
+ System.out.println("警告: 此操作将启动心跳,拉铆枪A将被启用!");
|
|
|
+ System.out.print("是否继续? (y/n): ");
|
|
|
+
|
|
|
+ String confirm = scanner.nextLine().trim().toLowerCase();
|
|
|
+ if (!confirm.equals("y")) {
|
|
|
+ System.out.println("已取消操作");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ try {
|
|
|
+ // 停止旧的定时器
|
|
|
+ if (heartBeatTimerA != null) {
|
|
|
+ heartBeatTimerA.cancel();
|
|
|
+ }
|
|
|
+
|
|
|
+ // 先设置心跳间隔时间(10代表1秒)
|
|
|
+ plcA.writeInt16(4170, (short) 10);
|
|
|
+ System.out.println("已设置心跳间隔为10(代表1秒)");
|
|
|
+
|
|
|
+ heartBeatFlagA = true;
|
|
|
+ heartBeatValueA = 1; // 初始化心跳值
|
|
|
+ heartBeatTimerA = new java.util.Timer();
|
|
|
+ heartBeatTimerA.schedule(new java.util.TimerTask() {
|
|
|
+ public void run() {
|
|
|
+ try {
|
|
|
+ if (heartBeatFlagA) {
|
|
|
+ // 向4160写入相邻不重复的数值(1, 2, 3循环)
|
|
|
+ plcA.writeInt16(4160, heartBeatValueA);
|
|
|
+ System.out.println("心跳A: 写入4160=" + heartBeatValueA);
|
|
|
+
|
|
|
+ // 切换心跳值(1→2→3→1循环)
|
|
|
+ heartBeatValueA = (short) (heartBeatValueA % 3 + 1);
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("心跳A执行失败: " + e.getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }, 100, 500);
|
|
|
+
|
|
|
+ System.out.println("✓ 拉铆枪A心跳已启动!");
|
|
|
+ System.out.println("提示: 心跳每500ms向地址4160写入1、2、3循环");
|
|
|
+ System.out.println("提示: 如果1秒内没有心跳,设备将禁止运行");
|
|
|
+ System.out.println("提示: 使用菜单4停止心跳");
|
|
|
+
|
|
|
+ } catch (Exception e) {
|
|
|
+ System.out.println("✗ 启动失败: " + e.getMessage());
|
|
|
+ log.error("启动拉铆枪A心跳失败", e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 停止拉铆枪A心跳 - 模拟工作完成后停止
|
|
|
+ */
|
|
|
+ private static void stopHeartBeatA() {
|
|
|
+ System.out.println("\n=== 停止拉铆枪A心跳 ===");
|
|
|
+
|
|
|
+ try {
|
|
|
+ heartBeatFlagA = false;
|
|
|
+ if (heartBeatTimerA != null) {
|
|
|
+ heartBeatTimerA.cancel();
|
|
|
+ heartBeatTimerA = null;
|
|
|
+ }
|
|
|
+
|
|
|
+ System.out.println("✓ 拉铆枪A心跳已停止!");
|
|
|
+ System.out.println("提示: 拉铆枪A现在应该自动停止工作");
|
|
|
+
|
|
|
+ } catch (Exception e) {
|
|
|
+ System.out.println("✗ 停止失败: " + e.getMessage());
|
|
|
+ log.error("停止拉铆枪A心跳失败", e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 启动拉铆枪B心跳 - 模拟质量检查合格后启动
|
|
|
+ */
|
|
|
+ private static void startHeartBeatB() {
|
|
|
+ if (plcB == null) {
|
|
|
+ System.out.println("错误: PLC B未连接!");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ System.out.println("\n=== 启动拉铆枪B心跳 ===");
|
|
|
+ System.out.println("警告: 此操作将启动心跳,拉铆枪B将被启用!");
|
|
|
+ System.out.print("是否继续? (y/n): ");
|
|
|
+
|
|
|
+ String confirm = scanner.nextLine().trim().toLowerCase();
|
|
|
+ if (!confirm.equals("y")) {
|
|
|
+ System.out.println("已取消操作");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ try {
|
|
|
+ // 停止旧的定时器
|
|
|
+ if (heartBeatTimerB != null) {
|
|
|
+ heartBeatTimerB.cancel();
|
|
|
+ }
|
|
|
+
|
|
|
+ // 先设置心跳间隔时间(10代表1秒)
|
|
|
+ plcB.writeInt16(4170, (short) 10);
|
|
|
+ System.out.println("已设置心跳间隔为10(代表1秒)");
|
|
|
+
|
|
|
+ heartBeatFlagB = true;
|
|
|
+ heartBeatValueB = 1; // 初始化心跳值
|
|
|
+ heartBeatTimerB = new java.util.Timer();
|
|
|
+ heartBeatTimerB.schedule(new java.util.TimerTask() {
|
|
|
+ public void run() {
|
|
|
+ try {
|
|
|
+ if (heartBeatFlagB) {
|
|
|
+ // 向4160写入相邻不重复的数值(1, 2, 3循环)
|
|
|
+ plcB.writeInt16(4160, heartBeatValueB);
|
|
|
+ System.out.println("心跳B: 写入4160=" + heartBeatValueB);
|
|
|
+
|
|
|
+ // 切换心跳值(1→2→3→1循环)
|
|
|
+ heartBeatValueB = (short) (heartBeatValueB % 3 + 1);
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("心跳B执行失败: " + e.getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }, 100, 500);
|
|
|
+
|
|
|
+ System.out.println("✓ 拉铆枪B心跳已启动!");
|
|
|
+ System.out.println("提示: 心跳每500ms向地址4160写入1、2、3循环");
|
|
|
+ System.out.println("提示: 如果1秒内没有心跳,设备将禁止运行");
|
|
|
+ System.out.println("提示: 使用菜单6停止心跳");
|
|
|
+
|
|
|
+ } catch (Exception e) {
|
|
|
+ System.out.println("✗ 启动失败: " + e.getMessage());
|
|
|
+ log.error("启动拉铆枪B心跳失败", e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 停止拉铆枪B心跳 - 模拟工作完成后停止
|
|
|
+ */
|
|
|
+ private static void stopHeartBeatB() {
|
|
|
+ System.out.println("\n=== 停止拉铆枪B心跳 ===");
|
|
|
+
|
|
|
+ try {
|
|
|
+ heartBeatFlagB = false;
|
|
|
+ if (heartBeatTimerB != null) {
|
|
|
+ heartBeatTimerB.cancel();
|
|
|
+ heartBeatTimerB = null;
|
|
|
+ }
|
|
|
+
|
|
|
+ System.out.println("✓ 拉铆枪B心跳已停止!");
|
|
|
+ System.out.println("提示: 拉铆枪B现在应该自动停止工作");
|
|
|
+
|
|
|
+ } catch (Exception e) {
|
|
|
+ System.out.println("✗ 停止失败: " + e.getMessage());
|
|
|
+ log.error("停止拉铆枪B心跳失败", e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 测试拉铆枪A心跳控制点位
|
|
|
+ */
|
|
|
+ private static void testHeartBeatControlA() {
|
|
|
+ if (plcA == null) {
|
|
|
+ System.out.println("错误: PLC A未连接!");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ System.out.println("\n=== 查看拉铆枪A心跳状态 ===");
|
|
|
+ System.out.println("心跳控制原理:");
|
|
|
+ System.out.println("1. MES向地址4160写入相邻不重复的数值(如1, 2, 3...1, 2循环)");
|
|
|
+ System.out.println("2. MES向地址4170写入心跳间隔时间(秒)");
|
|
|
+ System.out.println("3. 如果到达时间没有检测到心跳连接,设备禁止运行");
|
|
|
+
|
|
|
+ try {
|
|
|
+ System.out.println("\n当前状态:");
|
|
|
+
|
|
|
+ // 读取心跳连接点位
|
|
|
+ short heartBeatConn = plcA.readInt16(4160);
|
|
|
+ System.out.println("心跳连接 (地址4160): " + heartBeatConn + " (MES写入的心跳值)");
|
|
|
+
|
|
|
+ // 读取心跳间隔点位
|
|
|
+ short heartBeatInterval = plcA.readInt16(4170);
|
|
|
+ System.out.println("心跳间隔 (地址4170): " + heartBeatInterval + " 秒");
|
|
|
+
|
|
|
+ // 判断心跳状态
|
|
|
+ if (heartBeatConn > 0) {
|
|
|
+ System.out.println("\n状态: ✓ 心跳正常,拉铆枪可以工作");
|
|
|
+ } else {
|
|
|
+ System.out.println("\n状态: ✗ 心跳未启动,拉铆枪禁止运行");
|
|
|
+ }
|
|
|
+
|
|
|
+ System.out.println("\n提示: 使用菜单3启动心跳,菜单4停止心跳");
|
|
|
+
|
|
|
+ } catch (Exception e) {
|
|
|
+ System.out.println("✗ 读取失败: " + e.getMessage());
|
|
|
+ log.error("读取拉铆枪A心跳控制点位失败", e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 测试拉铆枪B心跳控制点位
|
|
|
+ */
|
|
|
+ private static void testHeartBeatControlB() {
|
|
|
+ if (plcB == null) {
|
|
|
+ System.out.println("错误: PLC B未连接!");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ System.out.println("\n=== 查看拉铆枪B心跳状态 ===");
|
|
|
+ System.out.println("心跳控制原理:");
|
|
|
+ System.out.println("1. MES向地址4160写入相邻不重复的数值(如1, 2, 3...1, 2循环)");
|
|
|
+ System.out.println("2. MES向地址4170写入心跳间隔时间(秒)");
|
|
|
+ System.out.println("3. 如果到达时间没有检测到心跳连接,设备禁止运行");
|
|
|
+
|
|
|
+ try {
|
|
|
+ System.out.println("\n当前状态:");
|
|
|
+
|
|
|
+ // 读取心跳连接点位
|
|
|
+ short heartBeatConn = plcB.readInt16(4160);
|
|
|
+ System.out.println("心跳连接 (地址4160): " + heartBeatConn + " (MES写入的心跳值)");
|
|
|
+
|
|
|
+ // 读取心跳间隔点位
|
|
|
+ short heartBeatInterval = plcB.readInt16(4170);
|
|
|
+ System.out.println("心跳间隔 (地址4170): " + heartBeatInterval + " 秒");
|
|
|
+
|
|
|
+ // 判断心跳状态
|
|
|
+ if (heartBeatConn > 0) {
|
|
|
+ System.out.println("\n状态: ✓ 心跳正常,拉铆枪可以工作");
|
|
|
+ } else {
|
|
|
+ System.out.println("\n状态: ✗ 心跳未启动,拉铆枪禁止运行");
|
|
|
+ }
|
|
|
+
|
|
|
+ System.out.println("\n提示: 使用菜单5启动心跳,菜单6停止心跳");
|
|
|
+
|
|
|
+ } catch (Exception e) {
|
|
|
+ System.out.println("✗ 读取失败: " + e.getMessage());
|
|
|
+ log.error("读取拉铆枪B心跳控制点位失败", e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 关闭连接
|
|
|
+ */
|
|
|
+ private static void closeConnections() {
|
|
|
+ try {
|
|
|
+ // 停止心跳定时器
|
|
|
+ if (heartBeatTimerA != null) {
|
|
|
+ heartBeatTimerA.cancel();
|
|
|
+ }
|
|
|
+ if (heartBeatTimerB != null) {
|
|
|
+ heartBeatTimerB.cancel();
|
|
|
+ }
|
|
|
+
|
|
|
+ if (plcA != null) {
|
|
|
+ plcA.close();
|
|
|
+ log.info("PLC A连接已关闭");
|
|
|
+ }
|
|
|
+ if (plcB != null) {
|
|
|
+ plcB.close();
|
|
|
+ log.info("PLC B连接已关闭");
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("关闭连接失败", e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|