|
|
@@ -7,67 +7,246 @@ import org.slf4j.LoggerFactory;
|
|
|
|
|
|
public class S7Utils {
|
|
|
public static final Logger log = LoggerFactory.getLogger(S7Utils.class);
|
|
|
- public static S7PLC s7PLC = new S7PLC(EPlcType.S200_SMART, "192.168.20.20");
|
|
|
|
|
|
- //发送允许启动信号
|
|
|
- public static void writeStart(boolean b) {
|
|
|
+ /** 心跳 DB1000.DBX0.0 */
|
|
|
+ public static final String ADDR_HEARTBEAT = "DB1000.0.0";
|
|
|
+ /** 请求效验 DB1000.DBX2.1 */
|
|
|
+ public static final String ADDR_REQ_CHECK = "DB1000.2.1";
|
|
|
+ /** 请求MES录入 DB1000.DBX2.2 */
|
|
|
+ public static final String ADDR_REQ_ENTRY = "DB1000.2.2";
|
|
|
+ /** Mes效验OK DB1000.DBX0.1 */
|
|
|
+ public static final String ADDR_MES_CHECK_OK = "DB1000.0.1";
|
|
|
+ /** Mes效验NG DB1000.DBX0.2 */
|
|
|
+ public static final String ADDR_MES_CHECK_NG = "DB1000.0.2";
|
|
|
+ /** Mes录入成功 DB1000.DBX0.3 */
|
|
|
+ public static final String ADDR_MES_ENTRY_OK = "DB1000.0.3";
|
|
|
+ /** 工件码 DB1000.DBB6 ~ DB1000.DBB65,共60字节 Char */
|
|
|
+ public static final String ADDR_PRODUCT_SN = "DB1000.6.0";
|
|
|
+ public static final int PRODUCT_SN_LEN = 60;
|
|
|
+ /** 最终测量结果 DB1000.DBW4 Word */
|
|
|
+ public static final String ADDR_FINAL_RESULT = "DB1000.4.0";
|
|
|
+
|
|
|
+ /** 第1次测量:结果/爬升电流/电压1/电阻/电压2/电流 */
|
|
|
+ public static final String ADDR_MEASURE_RESULT_1 = "DB1000.66.0";
|
|
|
+ public static final String ADDR_CURRENT_PS_1 = "DB1000.68.0";
|
|
|
+ public static final String ADDR_ONE_VOLTAGE_1 = "DB1000.72.0";
|
|
|
+ public static final String ADDR_RESISTANCE_1 = "DB1000.84.0";
|
|
|
+ public static final String ADDR_TWO_VOLTAGE_1 = "DB1000.80.0";
|
|
|
+ public static final String ADDR_CURRENT_1 = "DB1000.76.0";
|
|
|
+
|
|
|
+ /** 第2次测量:结果/爬升电流/电压1/电阻/电压2/电流 */
|
|
|
+ public static final String ADDR_MEASURE_RESULT_2 = "DB1000.112.0";
|
|
|
+ public static final String ADDR_CURRENT_PS_2 = "DB1000.114.0";
|
|
|
+ public static final String ADDR_ONE_VOLTAGE_2 = "DB1000.118.0";
|
|
|
+ public static final String ADDR_RESISTANCE_2 = "DB1000.130.0";
|
|
|
+ public static final String ADDR_TWO_VOLTAGE_2 = "DB1000.126.0";
|
|
|
+ public static final String ADDR_CURRENT_2 = "DB1000.122.0";
|
|
|
+
|
|
|
+ /** 第3次测量:结果/爬升电流/电压1/电阻/电压2/电流 */
|
|
|
+ public static final String ADDR_MEASURE_RESULT_3 = "DB1000.158.0";
|
|
|
+ public static final String ADDR_CURRENT_PS_3 = "DB1000.160.0";
|
|
|
+ public static final String ADDR_ONE_VOLTAGE_3 = "DB1000.164.0";
|
|
|
+ public static final String ADDR_RESISTANCE_3 = "DB1000.176.0";
|
|
|
+ public static final String ADDR_TWO_VOLTAGE_3 = "DB1000.172.0";
|
|
|
+ public static final String ADDR_CURRENT_3 = "DB1000.168.0";
|
|
|
+
|
|
|
+ /** 第4次测量:结果/爬升电流/电压1/电阻/电压2/电流 */
|
|
|
+ public static final String ADDR_MEASURE_RESULT_4 = "DB1000.204.0";
|
|
|
+ public static final String ADDR_CURRENT_PS_4 = "DB1000.206.0";
|
|
|
+ public static final String ADDR_ONE_VOLTAGE_4 = "DB1000.210.0";
|
|
|
+ public static final String ADDR_RESISTANCE_4 = "DB1000.222.0";
|
|
|
+ public static final String ADDR_TWO_VOLTAGE_4 = "DB1000.218.0";
|
|
|
+ public static final String ADDR_CURRENT_4 = "DB1000.214.0";
|
|
|
+
|
|
|
+ public static S7PLC s7PLC = new S7PLC(EPlcType.S200_SMART, Config.plc_ip);
|
|
|
+
|
|
|
+ private S7Utils() {
|
|
|
+ }
|
|
|
+
|
|
|
+ public static boolean readBoolean(String address) {
|
|
|
try {
|
|
|
- s7PLC.writeBoolean("DB100.0.2", b);
|
|
|
- log.info("设置<MES允许启动> : {}", b);
|
|
|
+ return s7PLC.readBoolean(address);
|
|
|
} catch (Exception e) {
|
|
|
- log.error("设置<MES允许启动> 失败: {}", e.getMessage());
|
|
|
+ log.error("读取S7地址 {} 失败: {}", address, e.getMessage());
|
|
|
+ return false;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- public static void writeFinish(boolean b) {
|
|
|
+ public static void writeBoolean(String address, boolean value) {
|
|
|
try {
|
|
|
- s7PLC.writeBoolean("DB100.0.3", b);
|
|
|
- log.info("设置<检测完成> : {}", b);
|
|
|
+ s7PLC.writeBoolean(address, value);
|
|
|
} catch (Exception e) {
|
|
|
- log.error("设置<检测完成> 失败");
|
|
|
+ log.error("写入S7地址 {} 失败: {}", address, e.getMessage());
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- public static Boolean readSpot() {
|
|
|
+ /**
|
|
|
+ * 读取工件码:DB1000.DBB6 ~ DB1000.DBB65(Char数组,非STRING)
|
|
|
+ * 注意:不能用 readString,否则会把首字节当成长度头导致丢第一位
|
|
|
+ */
|
|
|
+ public static String readProductSn() {
|
|
|
try {
|
|
|
- boolean result = s7PLC.readBoolean("DB100.0.4");
|
|
|
- log.info("读取<产品到位检测> : {}", result);
|
|
|
- return result;
|
|
|
+ byte[] bytes = s7PLC.readByte(ADDR_PRODUCT_SN, PRODUCT_SN_LEN);
|
|
|
+ if (bytes == null || bytes.length == 0) {
|
|
|
+ return "";
|
|
|
+ }
|
|
|
+ String sn = new String(bytes, java.nio.charset.StandardCharsets.ISO_8859_1);
|
|
|
+ int end = sn.indexOf('\0');
|
|
|
+ if (end >= 0) {
|
|
|
+ sn = sn.substring(0, end);
|
|
|
+ }
|
|
|
+ sn = sn.trim();
|
|
|
+ log.info("读取工件码: {}", sn);
|
|
|
+ return sn;
|
|
|
} catch (Exception e) {
|
|
|
- log.error("读取<产品到位检测> 失败");
|
|
|
- return false;
|
|
|
+ log.error("读取工件码失败: {}", e.getMessage());
|
|
|
+ return "";
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-
|
|
|
- public static void writeSpot(boolean b) {
|
|
|
+ public static int readWord(String address) {
|
|
|
try {
|
|
|
- s7PLC.writeBoolean("DB100.0.4", b);
|
|
|
- log.info("设置<产品到位检测> : {}", b);
|
|
|
+ return Short.toUnsignedInt(s7PLC.readInt16(address));
|
|
|
} catch (Exception e) {
|
|
|
- log.error("设置<产品到位检测> 失败");
|
|
|
+ log.error("读取Word {} 失败: {}", address, e.getMessage());
|
|
|
+ return 0;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- public static Boolean readFeedback() {
|
|
|
+ public static float readFloat(String address) {
|
|
|
try {
|
|
|
- boolean result = s7PLC.readBoolean("DB100.0.5");
|
|
|
- log.info("读取<反馈给MES完成> : {}", result);
|
|
|
- return result;
|
|
|
+ return s7PLC.readFloat32(address);
|
|
|
} catch (Exception e) {
|
|
|
- log.error("读取<反馈给MES完成> 失败");
|
|
|
- return false;
|
|
|
+ log.error("读取Real {} 失败: {}", address, e.getMessage());
|
|
|
+ return 0f;
|
|
|
}
|
|
|
+ }
|
|
|
+
|
|
|
+ private static String formatFloat(float value) {
|
|
|
+ return String.format(java.util.Locale.US, "%.4f", value);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 读取指定次数的测量数据并封装为 MesProductVoltage
|
|
|
+ */
|
|
|
+ public static MesProductVoltage readVoltageData(String sn, String time,
|
|
|
+ String addrResult, String addrCurrentPs,
|
|
|
+ String addrOneVoltage, String addrResistance,
|
|
|
+ String addrTwoVoltage, String addrCurrent) {
|
|
|
+ int measureResult = readWord(addrResult);
|
|
|
+ float currentPs = readFloat(addrCurrentPs);
|
|
|
+ float oneVoltage = readFloat(addrOneVoltage);
|
|
|
+ float resistance = readFloat(addrResistance);
|
|
|
+ float twoVoltage = readFloat(addrTwoVoltage);
|
|
|
+ float current = readFloat(addrCurrent);
|
|
|
+
|
|
|
+ // Word 测量结果:1=OK,其它=NG
|
|
|
+ String result = (measureResult == 1) ? "OK" : "NG";
|
|
|
+
|
|
|
+ MesProductVoltage data = new MesProductVoltage();
|
|
|
+ data.setSn(sn);
|
|
|
+ data.setCurrent(formatFloat(current));
|
|
|
+ data.setCurrentPs(formatFloat(currentPs));
|
|
|
+ data.setOneVoltage(formatFloat(oneVoltage));
|
|
|
+ data.setTwoVoltage(formatFloat(twoVoltage));
|
|
|
+ data.setResistance(formatFloat(resistance));
|
|
|
+ data.setResult(result);
|
|
|
+ data.setTime(time);
|
|
|
+
|
|
|
+ log.info("读取测量数据 time={}: word={}, {}", time, measureResult, data);
|
|
|
+ return data;
|
|
|
+ }
|
|
|
+
|
|
|
+ /** 第1次测量 time=1 */
|
|
|
+ public static MesProductVoltage readVoltageData1(String sn) {
|
|
|
+ return readVoltageData(sn, "1",
|
|
|
+ ADDR_MEASURE_RESULT_1, ADDR_CURRENT_PS_1, ADDR_ONE_VOLTAGE_1,
|
|
|
+ ADDR_RESISTANCE_1, ADDR_TWO_VOLTAGE_1, ADDR_CURRENT_1);
|
|
|
+ }
|
|
|
+
|
|
|
+ /** 第2次测量 time=2 */
|
|
|
+ public static MesProductVoltage readVoltageData2(String sn) {
|
|
|
+ return readVoltageData(sn, "2",
|
|
|
+ ADDR_MEASURE_RESULT_2, ADDR_CURRENT_PS_2, ADDR_ONE_VOLTAGE_2,
|
|
|
+ ADDR_RESISTANCE_2, ADDR_TWO_VOLTAGE_2, ADDR_CURRENT_2);
|
|
|
+ }
|
|
|
+
|
|
|
+ /** 第3次测量 time=3 */
|
|
|
+ public static MesProductVoltage readVoltageData3(String sn) {
|
|
|
+ return readVoltageData(sn, "3",
|
|
|
+ ADDR_MEASURE_RESULT_3, ADDR_CURRENT_PS_3, ADDR_ONE_VOLTAGE_3,
|
|
|
+ ADDR_RESISTANCE_3, ADDR_TWO_VOLTAGE_3, ADDR_CURRENT_3);
|
|
|
+ }
|
|
|
|
|
|
+ /** 第4次测量 time=4 */
|
|
|
+ public static MesProductVoltage readVoltageData4(String sn) {
|
|
|
+ return readVoltageData(sn, "4",
|
|
|
+ ADDR_MEASURE_RESULT_4, ADDR_CURRENT_PS_4, ADDR_ONE_VOLTAGE_4,
|
|
|
+ ADDR_RESISTANCE_4, ADDR_TWO_VOLTAGE_4, ADDR_CURRENT_4);
|
|
|
}
|
|
|
|
|
|
- public static void writeFeedback(boolean b) {
|
|
|
+ /**
|
|
|
+ * 读取最终测量结果:DB1000.DBW4,1=OK,其它=NG
|
|
|
+ */
|
|
|
+ public static String readFinalResult() {
|
|
|
+ int word = readWord(ADDR_FINAL_RESULT);
|
|
|
+ String result = (word == 1) ? "OK" : "NG";
|
|
|
+ log.info("读取最终测量结果: word={}, result={}", word, result);
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * MES->PLC 心跳交互:读取后取反写回,每秒调用一次
|
|
|
+ */
|
|
|
+ public static boolean heartBeat() {
|
|
|
try {
|
|
|
- s7PLC.writeBoolean("DB100.0.5", b);
|
|
|
- log.info("设置<反馈给MES完成> : {}", b);
|
|
|
+ boolean current = s7PLC.readBoolean(ADDR_HEARTBEAT);
|
|
|
+ boolean next = !current;
|
|
|
+ s7PLC.writeBoolean(ADDR_HEARTBEAT, next);
|
|
|
+ return next;
|
|
|
} catch (Exception e) {
|
|
|
- log.error("设置<反馈给MES完成> 失败");
|
|
|
+ log.error("S7心跳交互失败: {}", e.getMessage());
|
|
|
+ return false;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ public static boolean readReqCheck() {
|
|
|
+ return readBoolean(ADDR_REQ_CHECK);
|
|
|
+ }
|
|
|
+
|
|
|
+ public static boolean readReqEntry() {
|
|
|
+ return readBoolean(ADDR_REQ_ENTRY);
|
|
|
+ }
|
|
|
+
|
|
|
+ public static boolean readMesCheckOk() {
|
|
|
+ return readBoolean(ADDR_MES_CHECK_OK);
|
|
|
+ }
|
|
|
+
|
|
|
+ public static boolean readMesCheckNg() {
|
|
|
+ return readBoolean(ADDR_MES_CHECK_NG);
|
|
|
+ }
|
|
|
+
|
|
|
+ public static boolean readMesEntryOk() {
|
|
|
+ return readBoolean(ADDR_MES_ENTRY_OK);
|
|
|
+ }
|
|
|
+
|
|
|
+ public static void writeMesCheckOk(boolean b) {
|
|
|
+ writeBoolean(ADDR_MES_CHECK_OK, b);
|
|
|
+ log.info("设置<Mes效验OK>: {}", b);
|
|
|
+ }
|
|
|
+
|
|
|
+ public static void writeMesCheckNg(boolean b) {
|
|
|
+ writeBoolean(ADDR_MES_CHECK_NG, b);
|
|
|
+ log.info("设置<Mes效验NG>: {}", b);
|
|
|
+ }
|
|
|
+
|
|
|
+ public static void writeMesEntryOk(boolean b) {
|
|
|
+ writeBoolean(ADDR_MES_ENTRY_OK, b);
|
|
|
+ log.info("设置<Mes录入成功>: {}", b);
|
|
|
+ }
|
|
|
+
|
|
|
+ public static void clearMesCheckResult() {
|
|
|
+ writeMesCheckOk(false);
|
|
|
+ writeMesCheckNg(false);
|
|
|
+ }
|
|
|
}
|