AI를 이용한 HMI(UI)개발 (Copilot AI + Qt Designer)

본 장에서는 AI를 활용하여 Qt Designer로 설계한 HMI UI(.ui 파일)를 기반으로 HMI 프로그램을 개발하는 방법을 설명합니다. UI 화면은 .ui 파일을 통해 프로그램에 적용되며, 동작 로직은 VS Code 환경에서 Copilot AI 채팅 에이전트 기능을 활용하여 효율적으로 작성합니다.

  • Qt Designer를 이용한 HMI 구성 화면 설계. (.ui 파일 생성)
  • ui 파일과 main.py(메인 프로그램)를 기반으로, VS Code의 Copilot AI 채팅 에이전트를 활용하여 프로그램을 구현합니다.
  • AI를 활용한 개발 방식은 Vibe Coding 개념으로 구현 가능.

Vibe Coding은 개발자의 의도를 자연어로 AI에 전달하고, AI가 생성한 코드를 반복 검증·수정함으로써 빠르게 결과물을 완성하는 직관적 개발 방식입니다.

LOL 본 예제 프로젝트(상단 UI 이미지 기준)는 산업 현장 실무에서 많이 사용되는 HMI 구성을 기준으로 제작하였으며, 개발 진행 과정에서 AI를 활용한 개발 방법을 단계별로 설명합니다. 또한 UI 기능을 항목별로 구분하여, 각 기능의 요구 조건에 맞는 동작을 Vibe Coding 방식으로 구현하는 절차를 안내합니다.

1. Copilot 설치

Copilot Chat은 VS Code 내부에서 코드·파일·프로젝트 문맥을 이해한 상태로 대화형 AI 지원을 제공하는 기능입니다.

GitHub Copilot AI를 설치하여 사용하기 위해서는 GitHub 계정 로그인 및 권한 승인이 필요합니다. 아래 절차에 따라 설치를 진행합니다.

  • 1. GitHub Copilot, GitHub Copilot Chat 확장 검색 및 설치
  • 2. GitHub 계정 로그인 및 사용 권한 승인
  • 3. Copilot 활성화 상태 확인

설치와 GitHub 계정 로그인이 정상적으로 완료되면, VS Code 오른쪽 하단 상태바에 Copilot 아이콘이 표시되며 정상 설치 상태임을 확인할 수 있습니다.

2. main.py 에.ui 등록

프로젝트 구성 파일(.ui, main.py, 이미지 파일)을 동일한 프로젝트 폴더에 배치한 후, Vibe Coding(Ai) 방식을 활용하여 main.py 메인 프로그램을 작성하고 HMI 디자인 화면을 실제로 띄우는 방법을 설명합니다.

  • 프로젝트 구성 : main.py, .ui, 이미지 파일, 이미지가 포함된 Resource.qrc
  • Agent 기능 : Copilot AI의 에이전트 기능을 사용하여 코드 생성을 적용할 수 있으며, 이를 통해 빌드 및 실행이 가능합니다.
=== Vibe Coding(Ai) ===
Qt Designer로 제작한 CFNET_AI.ui 파일을 사용하여 UI를 실행할 수 있는 main.py 기본 메인 프로그램을 작성해 주세요. 
실행 환경은 Raspberry Pi 5의 Debian Bookworm OS이며, Python + PyQt5(Qt5 기반) 환경을 사용합니다.
.ui 파일을 로드하여 메인 윈도우를 실행하는 최소한의 기본 구조 코드로 작성해 주시기 바랍니다.

-코드 생성 및 적용 : Copilot AI의 에이전트가 생성한 코드는 “유지(Maintain)” 옵션을 선택하여 코드에 적용할 수 있습니다.


-에러 처리 : 기본 코드 생성 후 실행 시 아래와 같은 오류가 발생할 수 있습니다. 이는 Resource.qrc 파일이 Python 파일로 변환되지 않아 import되지 않기 때문에 발생하는 문제입니다. 해당 오류 역시 아래 절차에 따라 Vibe Coding(Ai) 방식으로 수정 및 빌드할 수 있습니다.

=== Vibe Coding(Ai) ===
“에러 내용 복사” 후,
해당 오류가 발생한 원인, 잘못된 코드 부분, 그리고 추가로 필요한 수정 사항이 있는지 확인하여 수정해 주세요.

- 수정 후 실행

Tip : 한글이 깨져서 표시될 경우, 한글 폰트를 추가로 설치해 주세요.

  • sudo apt update
  • sudo apt install fonts-nanum fonts-nanum-coding fonts-nanum-extra
  • sudo fc-cache -fv

3. HMI 동작로직

현장 실무에서 사용되는 시스템 로직 조건을 기반으로, HMI 기능과 하드웨어 동작을 Vibe Coding(Ai) 방식으로 구현하는 방법을 기능별로 설명합니다.

✔ 날짜•시간 표시 및 CFDO 동작 조건

  • 상단에 오늘 날짜와 시간 표시
  • 운전 / 정지 버튼 ON·OFF 동작에 따라 CFDO 출력 포트 P0, P1이 토글 동작합니다.
  • 운전 버튼과 정지 버튼이 모두 ON 상태일 경우, Alarm 출력(OUT)이 점등됩니다.

=== Vibe Coding (Ai) ===
1. date_time 객체에 현재 날짜와 시간을 표시한다(시계 기능).
2. CFRASP.py 모듈에서 CFNET 클래스를 import하고,   cfnet = CFNET() 형태로 CFNET 객체를 생성한다.
3. run_btn과 step_btn 버튼을 toggle 방식(QPushButton.setCheckable(True))으로 동작하게 한다.
4. 토글 상태에 따라 2바이트 변수 cf_out을 사용하며, run_btn 상태는 cf_out의 bit 0, step_btn 상태는 cf_out의 bit 1
   에 각각 매핑한다.
5. run_btn 또는 step_btn의 상태가 변경될 때마다 cfnet.digitalWrite(0, cf_out)를 호출하여
   현재 cf_out 값을 디지털 출력으로 반영한다. 
6. run_btn과 step_btn이 모두 체크(ON) 상태일 때만 alram_out 객체의 표시 이미지를 "Alram_on.png"로 변경한다.
   그 외의 모든 경우(둘 중 하나라도 OFF 상태일 때)에는 alram_out 객체의 표시 이미지를 "Alram_off.png"로 변경한다.

✔ CFDI 입력 상태 표시 및 알람 조건

  • 0.3초 주기로 CFDI의 입력 상태Lamp를 화면에 표시합니다.
  • CFDI의 입력 상태 data 값을 표시합니다.
  • CFDI의 16개 입력 포트 중 4개 이상이 ON 상태일 경우, INPUT 알람을 발생시킵니다.

=== Vibe Coding (Ai) ===
1. 입력 읽기
cfnet.digitalRead(0)을 0.3초 주기로 반복 호출한다.
반환값은 **2바이트 정수 변수 cf_in**에 저장한다.

2. 입력 비트값에 램프 on/off 이미지 매칭
cf_in의 값을 CFDI_0_Value 객체에 16진수(0x0000) 형식으로 표시한다.
16비트 변수 cf_in의 i번째 비트 상태를 체크해서, lamp_IN_[i] 객체의 라벨 이미지를 비트 상태에 맞추어
(1=ON.png, 0=OFF.png)업데이트한다.

3. 알람 조건 처리
cf_in의 16비트 중 ON 상태인 비트 개수가 4개 이상일 때만 alram_in 객체의 표시 이미지를 **Alram_on.png**로 변경한다.
그 외 모든 경우 alram_in 객체의 표시 이미지를 **Alram_off.png**로 변경한다.

✔ CFDA 출력 제어 및 상태 조건

  • 전압 출력 조절 삼각 버튼 클릭 시 출력 값이 409 단위로 증가 또는 감소합니다.
  • CFDA 출력 상태 데이터 값과 현재 출력 중인 전압 값을 화면에 표시합니다.
  • 출력 전압이 6 V 이상(데이터 값 2,457 이상)일 경우, DA 알람을 발생시킵니다.

=== Vibe Coding (Ai) ===
1. 변수 설정 및 초기화
변수 cfda_ch0, cfda_ch1을 생성하고 초기값 0을 할당한다.
모든 변수의 유효 범위는 0에서 4095 사이이며, 계산 결과가 이 범위를 벗어날 
경우 최댓값(4095) 또는 최솟값(0)으로 고정한다(Clamping 처리).

2. 버튼 이벤트 
da[i]_up 버튼 클릭 시: cfda_ch[i] 값을 409 증가시킨다. (최대 4095 제한) 
cfnet.analogWrite(0, i, cfda_ch[i]) 함수를 실행하여 출력한다.
da[i]_down 버튼 클릭 시: cfda_ch[i] 값을 409 감소시킨다. (최소 0 제한)
cfnet.analogWrite(0, i, cfda_ch[i]) 함수를 실행하여 출력한다.

3. 데이터 출력 및 표시

버튼 클릭 후, 화면의 da[i]_value 라벨에는 cfda_ch[i] 값을 정수형으로 표시한다.
da[i]_v_value 라벨에는 cfda_ch[i]를 409로 나눈 값을 소수점 첫째 자리까지 표시한다.

4. 알람 조건 및 이미지 제어
알람 활성화: cfda_ch0 또는 cfda_ch1 중 하나라도 값이 2,457 이상이면 
alram_da 객체의 이미지를 **'Alram_on.png'**로 변경한다.
알람 해제: 두 변수의 값이 모두 2,457 미만이면 alram_da 객체의 이미지를 **'Alram_off.png'**로 변경한다.

✔ CFAD 상태 및 조건

  • CFAD 의 ch3 채널 입력 상태 값을 화면에 표시합니다.
  • CFAD 의 ch3 입력 상태 값을 기준으로, 최대 입력값 대비 비율을 계산하여 게이지 화면에 %로 표시합니다.
  • 입력 전압이 5 V 이상(50% 이상)일 경우, AD 알람을 발생시킵니다.

<code> 1. 변수 설정 변수 cfad_ch3,을 생성하고 초기값 0을 할당한다. 100ms마다 cfad_ch3 = cfnet.analogRead(0, 3) 업데이트한다. 2. 상태값 화면 표시 QLCDNumber 위젯 (adc_value): cfad_ch3 값 표시. QProgressBar 위젯 (adc_bar): value 속성에 cfad_ch3 대입. 3. 알람 로직 cfad_ch3값이 13,333 이면 alram_ad 객체의 표시 이미지를 “Alram_on.png”로 변경한다. 그 외의 모든 경우에는 alram_ad 객체의 표시 이미지를 “Alram_off.png”로 변경한다.

Python을 이용한 CFNET I/O 개발