====== 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가 생성한 코드를 반복 검증·수정함으로써 빠르게 결과물을 완성하는 직관적 개발 방식입니다.//
{{ :modularpi:python:aipyhmi:example_sceenshot.png?nolink |}}
LOL** 본 예제 프로젝트(상단 UI 이미지 기준)는 산업 현장 실무에서 많이 사용되는 HMI 구성을 기준으로 제작하였으며, 개발 진행 과정에서 AI를 활용한 개발 방법을 단계별로 설명합니다.
또한 UI 기능을 항목별로 구분하여, 각 기능의 요구 조건에 맞는 동작을 Vibe Coding 방식으로 구현하는 절차를 안내합니다.**
=====1. Copilot 설치 =====
Copilot Chat은 VS Code 내부에서 코드·파일·프로젝트 문맥을 이해한 상태로 대화형 AI 지원을 제공하는 기능입니다.
* [[https://code.visualstudio.com/docs/copilot/overview|VS Code의 GitHub Copilot 사용법 가이드(필독)]]:!:
* **코드 작성 도움, 기존 코드 설명, 리팩토링 / 버그 수정, 특정 파일·함수 기준 질문 가능**\\
GitHub Copilot AI를 설치하여 사용하기 위해서는 GitHub 계정 로그인 및 권한 승인이 필요합니다. 아래 절차에 따라 설치를 진행합니다.
* 1. GitHub Copilot, GitHub Copilot Chat 확장 검색 및 설치
* 2. GitHub 계정 로그인 및 사용 권한 승인
* 3. Copilot 활성화 상태 확인
설치와 GitHub 계정 로그인이 정상적으로 완료되면, VS Code 오른쪽 하단 상태바에 Copilot 아이콘이 표시되며 정상 설치 상태임을 확인할 수 있습니다.
{{ :modularpi:python:aipyhmi:setup_copilot.png?nolink |}}
=====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 파일을 로드하여 메인 윈도우를 실행하는 최소한의 기본 구조 코드로 작성해 주시기 바랍니다.
{{ :modularpi:python:aipyhmi:project_folder.png?nolink |}}
**-코드 생성 및 적용 :** Copilot AI의 에이전트가 생성한 코드는 “유지(Maintain)” 옵션을 선택하여 코드에 적용할 수 있습니다.
{{ :modularpi:python:aipyhmi:init_vibe.png?nolink |}}
\\
**-에러 처리 **: 기본 코드 생성 후 실행 시 아래와 같은 오류가 발생할 수 있습니다.
이는 Resource.qrc 파일이 Python 파일로 변환되지 않아 import되지 않기 때문에 발생하는 문제입니다.
해당 오류 역시 아래 절차에 따라 Vibe Coding(Ai) 방식으로 수정 및 빌드할 수 있습니다.
=== Vibe Coding(Ai) ===
“에러 내용 복사” 후,
해당 오류가 발생한 원인, 잘못된 코드 부분, 그리고 추가로 필요한 수정 사항이 있는지 확인하여 수정해 주세요.
{{ :modularpi:python:aipyhmi:errorscreen1.png?nolink |}}
**- 수정 후 실행**
{{ :modularpi:python:aipyhmi:formscreen1.png?nolink |}}
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)**이 점등됩니다.
{{ :modularpi:python:aipyhmi:31screen.png?nolink |}}
=== 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"로 변경한다.
{{ :modularpi:python:aipyhmi:3_1_ai_manual.mp4?950x550|}}
==== ✔ CFDI 입력 상태 표시 및 알람 조건 ====
* 0.3초 주기로 CFDI의 입력 상태Lamp를 화면에 표시합니다.
* CFDI의 입력 상태 data 값을 표시합니다.
* CFDI의 16개 입력 포트 중 4개 이상이 ON 상태일 경우, INPUT 알람을 발생시킵니다.
{{ :modularpi:python:aipyhmi:32screen.png?nolink |}}
=== 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**로 변경한다.
{{url>https://www.youtube.com/embed/K6cxFarOcKc 840,480}}
==== ✔ CFDA 출력 제어 및 상태 조건 ====
* 전압 출력 조절 삼각 버튼 클릭 시 출력 값이 409 단위로 증가 또는 감소합니다.
* CFDA 출력 상태 데이터 값과 현재 출력 중인 전압 값을 화면에 표시합니다.
* 출력 전압이 **6 V 이상(데이터 값 2,457 이상)**일 경우, DA 알람을 발생시킵니다.
{{ :modularpi:python:aipyhmi:33screen.png?nolink |}}
=== 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'**로 변경한다.
{{url>https://www.youtube.com/embed/GasVvVjRp2U 840,480}}
==== ✔ CFAD 상태 및 조건 ====
* CFAD 의 ch3 채널 입력 상태 값을 화면에 표시합니다.
* CFAD 의 ch3 입력 상태 값을 기준으로, 최대 입력값 대비 비율을 계산하여 게이지 화면에 %로 표시합니다.
* 입력 전압이 **5 V 이상(50% 이상)**일 경우, AD 알람을 발생시킵니다.
{{ :modularpi:python:aipyhmi:34screen.png?nolink |}}
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"로 변경한다.
{{url>https://www.youtube.com/embed/gQwKVDZH-h4 840,480}}
[[..:index|Python을 이용한 CFNET I/O 개발]]