지그 체결 테스트기 gui
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
최승민 9fc060c14b 지그 체결 테스트 gui 4 weeks ago
.vs 지그 체결 테스트 gui 4 weeks ago
jig_test 지그 체결 테스트 gui 4 weeks ago
KN-2000W_KO_TCD210154AG_20251217_MANUAL_W.pdf 지그 체결 테스트 gui 4 weeks ago
README.md 지그 체결 테스트 gui 4 weeks ago
SemiIOLite_Manual.pdf 지그 체결 테스트 gui 4 weeks ago
jig_test.slnx 지그 체결 테스트 gui 4 weeks ago

README.md

지그 압력 및 누출 검사 애플리케이션 (Jig Pressure & Leak Test App)

1. 프로젝트 개요

본 프로젝트는 특정 지그(Jig)에 제품을 고정하고 압력을 인가한 뒤, 유지 시간 동안 내부 압력의 변화를 측정하여 누출(Leak) 여부를 자동으로 검사하는 데스크톱 전용 모니터링 애플리케이션입니다.

항목 내용
프레임워크 C# WPF (.NET Framework 4.7.2)
아키텍처 MVVM (Model-View-ViewModel) + Service Layer
솔루션 파일 jig_test.slnx
NuGet 패키지 System.IO.Ports (10.0.4), NModbus / NModbus.Serial (3.0.81)

주요 기능

  • 수동 검사: 물리 스위치(i1, i2) 조작에 의해 자동으로 누출 검사 시퀀스가 트리거됨
  • 자동 검사: 버튼 한 번으로 인가 → 목표 압력 대기 → 고정 → 유지 → 배기까지 전 공정을 자동 수행
  • 실시간 모니터링: 100ms 폴링으로 I/O 상태 및 압력값을 실시간 표시
  • 통신 분리 및 안정성: ConnectionManager를 통한 통신 인프라 캡슐화 및 bool 기반 상태 관리로 안정성 확보
  • 자가 복구: 통신 끊김 감지 시 독립적 자동 재연결
  • 설정 관리: 통신 포트, 기기 ID, 검사 파라미터를 XML 파일(config.xml)로 저장/불러오기

2. 폴더 구조

jig_test/                               ← 솔루션 루트
├── jig_test.slnx                       ← 솔루션 파일
├── README.md                           ← 본 문서
├── KN-2000W_..._MANUAL_W.pdf           ← 압력 센서 매뉴얼
├── SemiIOLite_Manual.pdf               ← I/O 보드 매뉴얼
│
└── jig_test/                           ← 프로젝트 폴더
    ├── jig_test.csproj                 ← 프로젝트 설정 (.NET 4.7.2, WPF)
    ├── App.xaml / App.xaml.cs          ← 앱 진입점, 글로벌 예외 처리
    │
    ├── Models/                         ← 데이터 모델
    │   └── AppConfig.cs               ← 모든 설정값 (포트, 속도, 검사파라미터)
    │
    ├── Services/                       ← 핵심 서비스 서비스 (Infrastructure 계층)
    │   ├── ConfigService.cs            ← XML 직렬화 기반 설정 저장/로드
    │   ├── ConnectionManager.cs        ← ★ 통신 인프라 (포트 수명, 폴링, 재연결 관리)
    │   ├── SemiIOLiteController.cs     ← I/O 보드 제어 (LS산전 ASCII 프로토콜)
    │   └── PressureSensorController.cs ← 압력 센서 통신 (Modbus RTU)
    │
    ├── ViewModels/                     ← MVVM ViewModel 계층
    │   ├── Base/
    │   │   ├── ObservableObject.cs     ← INotifyPropertyChanged 구현 기반 클래스
    │   │   └── RelayCommand.cs         ← ICommand 구현 (View 이벤트→ViewModel 바인딩)
    │   ├── Converters/
    │   │   └── InverseBooleanConverter.cs ← bool 반전 변환기
    │   ├── MainViewModel.cs            ← ★ 핵심 비즈니스 로직 (검사 시퀀스, UI 바인딩)
    │   ├── SettingsViewModel.cs        ← 통신 설정 창 로직
    │   └── ParameterViewModel.cs       ← 검사 파라미터 창 로직
    │
    └── Views/                          ← MVVM View 계층 (XAML UI)
        ├── MainWindow.xaml / .cs       ← 메인 대시보드 UI
        ├── SettingsWindow.xaml / .cs   ← 통신 설정 다이얼로그
        └── ParameterWindow.xaml / .cs  ← 검사 파라미터 다이얼로그

3. 아키텍처 (MVVM 패턴)

┌──────────────────────────────────────────────────────────────┐
│                         App.xaml.cs                          │
│           (글로벌 예외 처리: UI / AppDomain / Task)            │
└──────────────────────┬───────────────────────────────────────┘
                       │ StartupUri
┌──────────────────────▼───────────────────────────────────────┐
│  VIEW (XAML)                                                 │
│  ┌─────────────────────────────────────────────────────────┐ │
│  │ MainWindow.xaml   ← DataBinding →  MainViewModel.cs    │ │
│  │ SettingsWindow    ← DataBinding →  SettingsViewModel    │ │
│  │ ParameterWindow    ← DataBinding →  ParameterViewModel  │ │
│  └───────────────────┬─────────────────────────────────────┘ │
└──────────────────────┼───────────────────────────────────────┘
                       │ Event / Method
┌──────────────────────▼───────────────────────────────────────┐
│  INFRASTRUCTURE / SERVICES                                   │
│  ┌─────────────────────────────────────────────────────────┐ │
│  │                  ConnectionManager                      │ │
│  │ (Timer, SerialPort LifeCycle, Reconnect, Event Dispatch)│ │
│  └───────┬────────────────────────────┬────────────────────┘ │
│          │ Composition                │ Composition          │
│  ┌───────▼──────────┐         ┌───────▼──────────┐           │
│  │ SemiIOLite       │         │ PressureSensor   │           │
│  │ Controller       │         │ Controller       │           │
│  └───────┬──────────┘         └───────┬──────────┘           │
│          │ COM Port                   │ COM Port             │
└──────────┼────────────────────────────┼──────────────────────┘
           ▼                            ▼
    ┌──────────────┐            ┌──────────────┐
    │ Semi IO Lite │            │  KN-2240W    │
    │ I/O Board    │            │ Pressure     │
    │ (SIO-0201A)  │            │ Sensor       │
    └──────────────┘            └──────────────┘

데이터 흐름 요약

  1. ConnectionManager → Service: 100ms 타이머로 각 컨트롤러의 RequestXxx 메서드 호출 및 송신 HEX 로그 발행
  2. Service → Hardware: 시리얼 포트를 통해 실제 물리 레이어로 데이터 송신
  3. Hardware → ConnectionManager: DataReceived 이벤트 발생 시 바이트 버퍼링 및 패킷 완성 검사
  4. ConnectionManager → ViewModel: 패킷이 완성되면 이벤트를 통해 ViewModel에 전달 (IOPacketReceived 등)
  5. ViewModel → View: 수신 패킷을 파싱하여 lock 기반으로 압력값 갱신 및 UI 상태 프로퍼티 변경 → 바인딩 자동 반영

4. 핵심 파일 상세

4.1. Models/AppConfig.cs

모든 애플리케이션 설정을 담는 POCO 모델 클래스입니다.

프로퍼티 타입 기본값 용도
PortName string "COM1" I/O 보드 COM 포트
BaudRate int 9600 I/O 보드 통신 속도
PressurePortName string "COM2" 압력 센서 COM 포트
PressureBaudRate int 9600 압력 센서 통신 속도
IOEnabled bool true I/O 보드 사용 여부
IOStationId int 2 I/O 보드 국번 ID
PressureEnabled bool true 압력 센서 사용 여부
PressureSlaveId int 1 Modbus 슬레이브 주소
HoldTime int 30 누출 검사 유지 시간 (초)
AllowedErrorRange double 0.3 허용 압력 오차 (bar)
AutoTestTargetPressure double 4.0 자동 검사 목표 압력 (bar)
IsLogVisible bool false 하단 로그 창 표시 여부

4.2. Services/ConfigService.cs

AppConfig를 XML 직렬화 방식으로 저장/로드합니다.

  • Load(): config.xml 파일이 없거나 손상 시 기본 AppConfig 반환 (안전한 폴백)
  • Save(): 실행 파일 위치의 config.xml에 현재 설정을 즉시 저장

4.3. Services/ConnectionManager.cs — ★ 통신 인프라 관리자

MainViewModel에서 통신 관련 저수준 책임을 분리하여 캡슐화한 클래스입니다.

기능 상세 내용
포트 관리 IO 및 압력 포트의 생성, 오픈, 클로즈, Dispose 주기 관리
폴링 루프 100ms DispatcherTimer를 구동하여 장비 상태 체크 명령 주기적 송신
버퍼 관리 DataReceived 이벤트로 들어오는 단편화된 바이트를 패킷 단위로 조립
연결 상태 응답 타임아웃(1.5초) 감지 시 bool 기반 상태 갱신 및 이벤트 발행
자가 복구 포트 닫힘이나 연속 실패(10회) 감지 시 3초 간격 자동 재연결 시도
이벤트 발행 패킷 수신, 로그 발생, 연결 상태 변경 등을 이벤트를 통해 외부에 알림

4.4. Services/SemiIOLiteController.cs — I/O 보드 제어

LS산전 ASCII 프로토콜로 릴레이 출력을 제어하고 입력(i1, i2)을 읽습니다.

릴레이 상태 (RelayState enum)

이름 동작
0 None 모든 릴레이 OFF (고정/밀폐 상태)
1 Exhaust 릴레이1 ON — 배기 밸브 작동
2 Pressurize 릴레이2 ON — 인가 밸브 작동
3 Clamp 릴레이1+2 ON — 지그 물리 고정

주요 메서드

메서드 역할
SetStateAsync(RelayState) 릴레이 상태 변경 쓰기 명령 전송 + ACK 응답 대기 (최대 500ms)
RequestInputState(onTx) 주소 0A07의 입력 상태 읽기 요청 전송 (비동기)
ParseInputBuffer(buffer, out i1, out i2) 수신 버퍼를 파싱하여 i1, i2 디지털 입력 감지
CheckConnectionAsync() 주소 0001 읽기로 통신 유효성 확인 (핸드셰이크)

4.5. Services/PressureSensorController.cs — 압력 센서 통신

KN-2240W 디지털 센서와 Modbus RTU 프로토콜로 통신합니다.

Modbus RTU 프레임 구조

구분 바이트 구성
요청 (8바이트) [Slave Addr] [Func 0x04] [Start Addr Hi] [Start Addr Lo] [Count Hi] [Count Lo] [CRC Lo] [CRC Hi]
응답 (7바이트) [Slave Addr] [Func 0x04] [Byte Count] [Data Hi] [Data Lo] [CRC Lo] [CRC Hi]

주요 메서드

메서드 역할
RequestCurrentPressure(onTx) 레지스터 0x0000 1개 읽기 요청 전송
ParsePressureResponse(buffer, out pressureValue) CRC 검증 + 데이터 파싱 후 원시 압력값 반환
BuildReadRequest(startAddress, count) Modbus RTU Read Input Registers 프레임 동적 생성

4.6. ViewModels/MainViewModel.cs — ★ 비즈니스 로직 및 UI 바인딩

통신 인프라를 제외한 순수 검사 시퀀스와 사용자 인터페이스 로직을 담당합니다. (~800줄)

4.6.1. 이벤트 기반 데이터 처리

  • _connManager.IOPacketReceived 구독: IO 보드 응답 시 UpdateJigLamps 호출
  • _connManager.PressurePacketReceived 구독: 압력 센서 응답 시 압력값 갱신 및 UI 반영

4.6.2. 자가 복구 (Self-Healing) 알고리즘 (ConnectionManager 내 구현)

[정상 동작] → 100ms 폴링 중 응답 수신
        ↓ 1.5초 무응답
[경고] → 램프 Red + 실패 카운터 증가
        ↓ 10회 연속 무응답
[단절 선언] → 포트 닫기 및 리소스 정리
        ↓ 즉시
[재연결 시도] → 3초 주기로 포트 재오픈 시도

4.6.3. 수동 검사 시퀀스 (StartAutoHoldSequence)

[스위치 → 인가 위치]                        _wasPressurized = true
        ↓
[스위치 → 고정 위치] && _wasPressurized
        ↓
StartAutoHoldSequence() 트리거
        ↓
(1) 현재 압력을 "검사 시작 압력"으로 저장
(2) HoldTime 초 동안 1초 간격 대기
(3) |최종 압력 - 시작 압력| vs AllowedErrorRange 비교
    ├── 이내 → PASS (LimeGreen)
    └── 초과 → FAIL (Red)

4.6.4. 자동 검사 시퀀스 (StartAutoCycleSequence)

[시작 버튼 클릭] (고정 상태에서만 가능)
    ↓
단계 1: 인가(Pressurize) → 목표 압력 도달 대기
    ↓
단계 2: 고정(None) → 밸브 폐쇄
    ↓
단계 3: HoldTime 초 동안 압력 유지 검사
    ↓
단계 4: 배기(Exhaust) → 0.0bar 도달 대기 (60초 타임아웃)
    ↓
단계 5: 다시 고정(None) → 종료

4.6.5. 주요 바인딩 프로퍼티 요약

카테고리 프로퍼티 용도
장비 램프 LampIOStatus, LampPressureStatus I/O / 압력 센서 연결 표시등
압력 CurrentPressureText, CurrentPressureColor 실시간 압력값 표시
수동 결과 ResultText, ResultColor PASS/FAIL 결과 표시
자동 결과 AutoResultText, AutoResultColor 자동 검사 PASS/FAIL
로그 IOLogText, PrLogText I/O / 압력 센서 HEX 통신 로그

4.7. ViewModels/SettingsViewModel / ParameterViewModel

  • 설정 복사본(Clone)을 사용한 원본 보호 및 취소 기능
  • 시스템의 COM 포트 자동 감지 및 폴백 처리
  • 입력 유효성 검증 (정규식 필터링 및 범위 체크)

4.8. Views/MainWindow.xaml — 메인 UI 구조

  • Viewbox Stretch="Uniform": 창 크기 변화에도 UI 비율 유지
  • 커스텀 타이틀 바 + 탭 컨트롤 기반 화면 구성
  • 실시간 로그 창 (I/O 녹색, 압력 파란색) 접이식 구현 및 자동 스크롤

5. 안정성 메커니즘

5.1. bool 기반 상태 관리 (Refactoring #11)

기존에는 UI 램프의 Brush 색상을 비교하여 통신 상태를 판단했으나, 리액터링을 통해 _isIOConnected, _isPressureConnected 명시적 필드를 도입하여 로직의 안정성과 가독성을 높였습니다.

5.2. 책임 분리 (Refactoring #10)

ConnectionManager를 통해 통신 인프라를 캡슐화했습니다. 메인 로직은 장치와의 직접적인 포트 관리에서 자유로워졌으며, 이벤트 기반으로 응답을 처리하여 UI 스레드 정지 현상을 방지합니다.

5.3. 글로벌 예외 처리 (App.xaml.cs)

DispatcherUnhandledException, AppDomain.UnhandledException, TaskScheduler.UnobservedTaskException을 모두 처리하여 예기치 못한 에러 시에도 프로그램이 강제 종료되지 않도록 보호합니다.


6. 설정 파일 (config.xml)

실행 파일 위치에 XML 형식으로 저장되며, 손상 시 자동으로 기본값으로 복원됩니다.

<?xml version="1.0" encoding="utf-8"?>
<AppConfig>
  <PortName>COM3</PortName>
  <BaudRate>9600</BaudRate>
  <PressurePortName>COM4</PressurePortName>
  <PressureBaudRate>9600</PressureBaudRate>
  <IOEnabled>true</IOEnabled>
  <IOStationId>2</IOStationId>
  <PressureEnabled>true</PressureEnabled>
  <HoldTime>30</HoldTime>
  <AllowedErrorRange>0.3</AllowedErrorRange>
  <AutoTestTargetPressure>4.0</AutoTestTargetPressure>
  <IsLogVisible>false</IsLogVisible>
</AppConfig>

7. 유지보수 및 확장 가이드

새 검사 파라미터 추가 시

  1. Models/AppConfig.cs 데이터 추가 및 Clone() 메서드 업데이트
  2. Views/ParameterWindow.xaml 입력 UI 추가
  3. ViewModels/MainViewModel.UpdateParamDisplay()에 반영

새 기기 추가 시

  1. Services/ 컨트롤러 구현 → ConnectionManager.cs에 인스턴스/폴링 추가
  2. MainViewModel.cs에서 이벤트 구독 및 파싱 로직 연결