to3796zw 5e01c9a63c feat: 용접 전/후 Scout 핸드셰이크 추가
SeqAutoRunPTOP에 용접 전/후 Scout(SeqScoutNormal 재사용) 핸드셰이크
배선. PLC가 Scout Request를 올리면 캡처·이미지 저장 후 Complete 회신.

bit 매핑(0x09 Recipe_CHG는 미사용 → Scout로 재정의):
- Pre  Req=M70509(eBitInput 0x09) / Complete=M70009(eBitOutput 0x09)
- Post Req=M70510(eBitInput 0x0A) / Complete=M70010(eBitOutput 0x0A)

이미지 파일명: {기존}_auto_{recipeNo}_{pageNo}_{pre|post}.PNG (폴더 유지).
SCOUT_ENABLED=false면 노드 즉시 통과로 기존 사이클 무영향.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-22 14:31:12 +09:00

252 lines
7.7 KiB
C#

using AuroraPLC;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ILSOS_PrismaticRD_PTOP.Device
{
partial class PLCControllerPTOP
{
// 최신화 된 메모리 맵 정보
public enum eBitInput : int
{
PLC_LIVE_STATUS = 0x00,
PLC_AUTO_STATUS = 0x01,
PLC_AUTO_REQ = 0x02,
PLC_MANUAL_REQ = 0x03,
PLC_LIGHT_ALARM_STATUS = 0x04,
PLC_HEAVY_ALARM_STATUS = 0x05,
PLC_DOOR_INTERLOCK = 0x06,
PLC_EMO_STATUS = 0x07,
PLC_PAGE_CHANGE_REQ = 0x08,
// 260622: M70509 = 용접 전 Scout Request (구 PLC_RECIPE_CHANGE_REQ/RMS_USED, 모두 미사용 → 재정의)
// Recipe 전환은 PAGE_CHANGE_REQ 트리거 + PLC_RECIPE_NO 워드로 처리하므로 이 bit는 Scout가 사용.
PLC_PRE_WELD_SCOUT_REQ = 0x09,
// 260622: M70510 = 용접 후 Scout Request (신규)
PLC_POST_WELD_SCOUT_REQ = 0x0A,
// 0x0B ~ 0x0E
// 260621: M70515 확정 = Weld_01 Ready (가변용접 시 PLC ON → Recipe/Page 확인 팝업 + Resume 트리거)
PLC_WELD_READY_REQ = 0x0F,
PLC_WELD_TRIGGER_REQ = 0x10, // M70516 (구 Ready)
PLC_WELD_WAIT = 0x11,
PLC_WELD_COMPLETE_ACK = 0x12,
// 0x13 ~ 0x1D
PLC_ALARM_RESET = 0x1E, // x
PLC_RMS_PARAMETER_READ_REQUEST = 0x25,
// ── 두 번째 블록 (M70600~) ──────────────────────────
PLC_AUTO_STATUS_P = 0x65,
PLC_AUTO_REQ_P = 0x66,
PLC_MANUAL_REQ_P = 0x67,
PLC_LIGHT_ALARM_STATUS_P = 0x68,
PLC_HEAVY_ALARM_STATUS_P = 0x69,
PLC_DOOR_INTERLOCK_P = 0x6A,
PLC_EMO_STATUS_P = 0x6B,
// 0x6D
// 0x6F ~ 0x73
PLC_WELD_P_READY_REQ = 0x74,
PLC_WELD_P_WAIT = 0x75,
PLC_WELD_P_COMP_ACK = 0x76,
}
public enum eBitOutput : int
{
PC_LIVE_STATUS = 0x00,
PC_AUTO_STATUS = 0x01,
PC_AUTO_COMPLETE = 0x02,
PC_MANUAL_COMPLETE = 0x03,
PC_LIGHT_ALARM_STATUS = 0x04,
PC_HEAVY_ALARM_STATUS = 0x05,
PC_DOOR_INTERLOCK = 0x06,
PC_EMO_STATUS = 0x07,
PC_PAGE_CHANGE_COMPLETE = 0x08,
// 260622: M70009 = 용접 전 Scout Complete (구 PC_RECIPE_CHANGE_COMPLETE, PLC 미감시 → 재정의)
PC_PRE_WELD_SCOUT_COMPLETE = 0x09,
// 260622: M70010 = 용접 후 Scout Complete (신규)
PC_POST_WELD_SCOUT_COMPLETE = 0x0A,
// 0x0B ~ 0x0E
// 260621: M70015 확정 = Weld_01 ReadyACK (Resume ACK/run 신호)
PC_WELD_READY_ACK = 0x0F,
PC_WELD_TRIGGER_ACK = 0x10, // M70016 (구 ReadyACK)
PC_WELD_BUSY = 0x11,
PC_WELD_COMPLETE = 0x12,
PC_WELD_NG_JUDGE = 0x14,
PC_RMS_PARAMETER_READ_REQUEST_ACK = 0x25,
PC_AUTO_STATUS_P = 0x65,
PC_AUTO_REQUEST_P = 0x66,
PC_LIGHT_ALARM_STATUS_P = 0x68,
PC_HEAVY_ALARM_STATUS_P = 0x69,
PC_WELD_P_READY_REQ = 0x74,
PC_WELD_P_BUSY = 0x75,
PC_WELD_P_COMP_ACK = 0x76,
}
public enum eWordInput : int
{
PLC_ERROR_CODE = 0X00,
PLC_PAGE_NO,
PLC_RECIPE_NO, // 260618: D70502 Recipe No (구 PLC_STEP_NO, index 2 유지)
PLC_CURRENT_SLOT_NO, // EL / CLEAN 사용
EMPTY_04,
EMPTY_05,
EMPTY_06,
EMPTY_07,
EMPTY_08,
EMPTY_09,
HEAD_THETA_POSITION, // D70510 (Laser1 Head Theta), index 10
EMPTY_11,
EMPTY_12,
EMPTY_13,
EMPTY_14,
EMPTY_15,
EMPTY_16,
EMPTY_17,
EMPTY_18,
EMPTY_19,
PLC_CELL_ID_01,
PLC_CELL_ID_02,
PLC_CELL_ID_03,
PLC_CELL_ID_04,
PLC_CELL_ID_05,
PLC_CELL_ID_06,
PLC_CELL_ID_07,
PLC_CELL_ID_08,
PLC_CELL_ID_09,
PLC_CELL_ID_10,
PLC_LOT_ID_01,
PLC_LOT_ID_02,
PLC_LOT_ID_03,
PLC_LOT_ID_04,
PLC_LOT_ID_05,
PLC_LOT_ID_06,
PLC_LOT_ID_07,
PLC_LOT_ID_08,
EMPTY_38,
EMPTY_39,
EMPTY_40,
EMPTY_41,
EMPTY_42,
EMPTY_43,
EMPTY_44,
EMPTY_45,
EMPTY_46,
EMPTY_47,
EMPTY_48,
EMPTY_49,
EMPTY_50,
EMPTY_51,
EMPTY_52,
EMPTY_53,
EMPTY_54,
EMPTY_55,
EMPTY_56,
EMPTY_57,
EMPTY_58,
EMPTY_59,
PC_RMS_ALLOC_START,
PC_RMS_ALLOC_END = 97,
EMPTY_98,
EMPTY_99,
}
public enum eWordOutput : int
{
PC_ERROR_CODE = 0X00,
PC_PAGE_NO,
PC_RECIPE_NO, // 260618: D70002 Recipe No 에코 (구 EMPTY_02, index 2 유지)
EMPTY_03,
EMPTY_04,
EMPTY_05,
EMPTY_06,
EMPTY_07,
PC_WELD_OFFSET_X,
EMPTY_09,
PC_WELD_OFFSET_Y,
EMPTY_11,
PC_DISPLACEMENT1_MEASUREMENT,
EMPTY_13,
PC_DISPLACEMENT2_MEASUREMENT = 0X0E,
EMPTY_15,
EMPTY_16,
EMPTY_17,
EMPTY_18,
EMPTY_19,
PC_CELL_ID_01,
PC_CELL_ID_02,
PC_CELL_ID_03,
PC_CELL_ID_04,
PC_CELL_ID_05,
PC_CELL_ID_06,
PC_CELL_ID_07,
PC_CELL_ID_08,
PC_CELL_ID_09,
PC_CELL_ID_10,
PC_LOT_ID_01,
PC_LOT_ID_02,
PC_LOT_ID_03,
PC_LOT_ID_04,
PC_LOT_ID_05,
PC_LOT_ID_06,
PC_LOT_ID_07,
PC_LOT_ID_08,
EMPTY_38,
EMPTY_39,
PC_FDC_PAGE1_POWER,
PC_FDC_PAGE1_VELOCITY,
PC_FDC_PAGE2_POWER,
PC_FDC_PAGE2_VELOCITY,
PC_FDC_PAGE3_POWER,
PC_FDC_PAGE3_VELOCITY,
EMPTY_46,
EMPTY_47,
EMPTY_48,
EMPTY_49,
EMPTY_50,
EMPTY_51,
EMPTY_52,
EMPTY_53,
EMPTY_54,
EMPTY_55,
EMPTY_56,
EMPTY_57,
EMPTY_58,
EMPTY_59,
PC_RMS_ALLOC_START,
PC_RMS_ALLOC_END = 97,
EMPTY_98,
EMPTY_99,
}
// Cell 정보
internal string CellId()
{
StringBuilder sb = new StringBuilder();
var item = ReadWords(eWordInput.PLC_CELL_ID_01, eWordInput.PLC_CELL_ID_05);
if (item.datas == null) return string.Empty;
foreach (var word in item.datas)
sb.Append(Conv_ReadData(PLCBase.eDataType.Type_Ascii, word, 0, false, false));
return sb.ToString();
}
// Lot 정보
internal string LotId()
{
StringBuilder sb = new StringBuilder();
var item = ReadWords(eWordInput.PLC_LOT_ID_01, eWordInput.PLC_LOT_ID_08);
if (item.datas == null) return string.Empty;
foreach (var word in item.datas)
sb.Append(Conv_ReadData(PLCBase.eDataType.Type_Ascii, word, 0, false, false));
return sb.ToString();
}
}
}