fix: 260618 내부댐퍼·스마트수면·쾌적조리 동작 수정

- 내부댐퍼: 모드전환 중 명령경로(CTRL_FAN)가 팬 감속에 끼어들어 댐퍼가
  간헐적으로 안 움직이던 문제 수정 (Fan_Speed_process 게이트 보호)
- 명령경로 즉시 팬설정(My_Homenet/My_Hood) 모드변경분 주석 — 마스터 정렬
- 스마트수면: 거실(room1) CO2 무관 항상 CLOSE (사양 8p)
- 대시보드: 쾌적조리 버튼 강조=ComfortCook(연동 Enable),
  활성=후드/시나리오 무관 항상 토글 (사양 9p 3.1 독립 토글)
- doc/260618 수정 정리 + 개발사양서 갱신

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-18 18:48:41 +09:00
parent 82caac3872
commit c5e4c48d24
7 changed files with 206 additions and 10 deletions
+9
View File
@@ -1158,6 +1158,15 @@ PASS1:
}
else
{
/* [모드전환 댐퍼게이트 보호] 모드전환 진행중(Damper_wait_time==5)에는
명령경로(대시보드 CTRL_FAN 등)가 풍량을 올려도 무시하고 팬을 0으로 강제.
팬이 0까지 내려가야 Damper_Mode 가 실행되어 내부댐퍼가 이동한다.
(CTRL_FAN 이 감속창에 간헐적으로 끼어들어 댐퍼가 안 움직이던 문제 수정) */
if(Damper_wait_time == 5)
{
Target_Fan1_Speed = 0;
Target_Fan2_Speed = 0;
}
Diffuser_Damper_process(Run_Mode);
}
+8 -4
View File
@@ -256,7 +256,10 @@ static void hn_apply_cmd(uint8_t cmd, uint8_t *pl, uint8_t len)
/* 전원 ON : 환기 모드 + 풍량 1단 (ERVSimulator HomeNetProtocol 와 동일) */
Set_Run_Mode = Run_Mode = MODE_VENTILATION;
Set_Fan_Mode = Fan_Mode = 1;
Fan_Speed_Setting(Run_Mode, Fan_Mode); /* 즉시 반영 (모드전환과 동일) */
/* [모드변경댐퍼테스트] 마스터 정렬 : 모드변경 시 명령경로 즉시 팬설정 제거.
팬이 0까지 감속해야 Fan_Speed_process 가 Damper_Mode 를 호출(내부댐퍼 이동).
팬 복원은 Fan_Speed_process wait==1 에서 수행. */
//Fan_Speed_Setting(Run_Mode, Fan_Mode); /* 즉시 반영 (모드전환과 동일) */
}
/* 전원 토글 시 수동 댐퍼/LED 해제 → 자동 추종 복귀 */
for(i = 1; i <= 4; i++) { Diffuser_Damper_Manual[i] = 0; Diffuser_Led_Manual[i] = 0; }
@@ -288,9 +291,10 @@ static void hn_apply_cmd(uint8_t cmd, uint8_t *pl, uint8_t len)
{
Set_Fan_Mode = Fan_Mode = 1;
Command_request_type |= TYPE_FAN_SPEED;
/* 즉시 반영 : 풍량 단수(Total_Air_Volume)가 안 바뀌는 모드전환
(예: 환기1단→공청1단)에서도 새 모드 VSP가 걸리도록 CTRL_FAN 과 동일하게 직접 호출 */
Fan_Speed_Setting(Run_Mode, Fan_Mode);
/* [모드변경댐퍼테스트] 마스터 정렬 : 모드변경 시 명령경로 즉시 팬설정 제거.
팬이 0까지 감속해야 Fan_Speed_process 가 Damper_Mode 를 호출(내부댐퍼 이동).
새 모드 VSP 복원은 Fan_Speed_process wait==1 에서 수행. */
//Fan_Speed_Setting(Run_Mode, Fan_Mode);
}
}
}
+6 -2
View File
@@ -189,7 +189,9 @@ uint8_t Hood_process(void)//200ms
}
Command_request_type |= (TYPE_MODE|TYPE_FAN_SPEED);
Fan_Speed_Setting(Run_Mode, Fan_Mode); /* 즉시 반영(룸컨 echo 대기 없이 — CTRL_FAN 동일) */
/* [모드변경댐퍼테스트] 마스터 정렬 : 모드변경(→환기) 시 명령경로 즉시 팬설정 제거.
팬 복원은 Fan_Speed_process wait==1 에서 수행. */
//Fan_Speed_Setting(Run_Mode, Fan_Mode); /* 즉시 반영(룸컨 echo 대기 없이 — CTRL_FAN 동일) */
Tx_Yeundong_Delay = 30;
}
else if(Hood_Status == 0) // 후드 OFF : 즉시 원래 모드/풍량 복귀 (메이크업 유지는 후드측 담당, 사양 260613 9p 3.3)
@@ -204,7 +206,9 @@ uint8_t Hood_process(void)//200ms
}
Command_request_type |= (TYPE_MODE|TYPE_FAN_SPEED|TYPE_HOOD_STATE);
if(Run_Mode != MODE_AUTO) Fan_Speed_Setting(Run_Mode, Fan_Mode); /* 즉시 복귀 반영 */
/* [모드변경댐퍼테스트] 마스터 정렬 : 모드복귀 시 명령경로 즉시 팬설정 제거.
팬 복원은 Fan_Speed_process wait==1 에서 수행. */
//if(Run_Mode != MODE_AUTO) Fan_Speed_Setting(Run_Mode, Fan_Mode); /* 즉시 복귀 반영 */
Hood_Yeundong_flag = 0;
Hood_Warming_up_Timer = 0;
Tx_Yeundong_Delay = 0;
+6 -2
View File
@@ -912,8 +912,12 @@ uint8_t Air_Quality_damper_process(void)
Pre_Ext_Select_Room = Ext_Select_Room;
}
/* 매 틱 : 실별 CO2 히스테리시스. CO2 >= 1000 OPEN, <= 800 CLOSE, 그 사이(데드존)는 현재 상태 유지 */
for(Room_Num = 1; Room_Num < 5; Room_Num++)
/* 거실(room1)은 사양상 CO2 무관하게 항상 CLOSE → 매 틱 강제 닫음 */
Memory_Diffuser_Dmp_Ang_SA[1] = 0; Memory_Diffuser_Dmp_Ang_RA[1] = 0;
Diffuser_Air_quality[1] = 0;//OFF
/* 매 틱 : 침실1~3(room2~4) 만 CO2 히스테리시스. CO2 >= 1000 OPEN, <= 800 CLOSE, 그 사이(데드존)는 현재 상태 유지 */
for(Room_Num = 2; Room_Num < 5; Room_Num++)
{
if(SEN66_CO2_value[Room_Num] >= 1000)
{ Memory_Diffuser_Dmp_Ang_SA[Room_Num] = 110; Memory_Diffuser_Dmp_Ang_RA[Room_Num] = 110; }
+5 -2
View File
@@ -578,11 +578,14 @@ namespace ErvDashboard
// 시나리오모드
SetActive(SmartSleepBtn, _state.SmartSleep);
SetActive(ComfortCookBtn, _state.HoodRunning); // 메이크업 실제 동작중(후드 가동)일 때만 강조 — 후드 OFF면 해제
// 쾌적조리는 사양 9p 3.1 의 'UI 토글(연동 스위치)' — 후드 가동중이 아니라 토글 ON/OFF(=Hood_YeunDong_Enable)를 강조.
// (HoodRunning 으로 강조하면 대기/Roll-back 상태에서 버튼이 꺼져 보여 재선택 시 토글이 반대로 먹던 문제 수정)
SetActive(ComfortCookBtn, _state.ComfortCook);
SetActive(ReliefRecoverBtn, _state.ReliefRecover);
// (활성 모드 버튼은 OFF 토글 가능해야 하므로 자기 자신은 유지)
SmartSleepBtn.IsEnabled = !subActive || _state.SmartSleep;
ComfortCookBtn.IsEnabled = !subActive || _state.ComfortCook;
// 쾌적조리는 사양 9p 3.1 의 '독립 토글(연동 스위치)' — 후드 연결/가동·다른 시나리오와 무관하게 항상 토글 가능.
ComfortCookBtn.IsEnabled = true;
ReliefRecoverBtn.IsEnabled = !subActive || _state.ReliefRecover;
// 스마트수면 시간설정 버튼 : 스마트수면 ON 일 때만 활성
SmartSleepSetBtn.IsEnabled = _state.SmartSleep;
@@ -0,0 +1,172 @@
# 260618 수정 요약 (핸드오프용)
> 작업 PC 이전 시점 기준. 아래 상세 항목 (1)~(5) 의 최종 변경 정리.
## 변경 파일 (커밋 포함)
| 파일 | 변경 요지 | 관련 항목 |
|---|---|---|
| `Source/HECO2/User/MyMotor.c` | 모드전환 중(`Damper_wait_time==5`) 팬 강제 0 → 내부댐퍼 이동 게이트 보호 | (3) |
| `Source/HECO2/User/My_Homenet.c` | 모드변경 시 명령경로 즉시 `Fan_Speed_Setting` 호출 주석(L259/293) — 마스터 정렬 | (1) |
| `Source/HECO2/User/My_Hood.c` | 후드연동 모드변경 시 즉시 `Fan_Speed_Setting` 주석(L192/207) — 마스터 정렬 | (1) |
| `Source/HECO2/User/My_system.c` | 스마트수면 거실(room1) CO2 무관 항상 CLOSE | (2) |
| `TestProgram/PCDashBoard/MainWindow.xaml.cs` | 쾌적조리 버튼 강조=ComfortCook(L583), 활성=항상(L587) | (4)(5) |
| `개발사양서/...DL_동작로직_260613.pptx` | 사양서 갱신(바이너리) | - |
## 빌드 상태
- 펌웨어: `cd SOURCE/HECO2 && bash build.sh all` → 경고/오류 0.
- 대시보드: `dotnet publish ErvDashboard.csproj -c Release` → 오류 0 (NU1701 경고만).
- 대시보드 exe: `TestProgram/PCDashBoard/bin/Release/net10.0-windows/win-x64/publish/ErvDashboard.exe`
## 실장비/대시보드 확인 필요(테스트 대기)
- 환기→공청 반복 전환 시 내부댐퍼 매번 이동(간헐성 해소). 전환 시 팬이 잠깐 0까지 멈췄다 복귀하는 것이 정상.
- 스마트수면 진입 시 거실 닫힘 + 침실 CO2 개폐.
- 쾌적조리 버튼이 후드 연결/전원 무관하게 항상 토글되는지.
## 미적용/보류
- (선택) 쾌적조리를 스마트수면/안심회복과의 **상호배타에서 분리**(사양상 독립 토글) — SubMode_Click L401~406.
- (보류) 펌웨어 쾌적조리를 `Ext_Run_Mode==2` 상태머신으로 배선(현재 My_system 846/952 dead code). 1차 대시보드 수정으로 충분한지 검증 후 결정.
- 1차 명령경로 주석(My_Homenet/My_Hood)은 (3) 게이트 보호로 중복이나 무해 — 정리 보류.
---
# 260618 내부댐퍼 — 운전모드 변경 시 미동작 수정 (1차: 명령경로 즉시 팬설정 제거)
## 증상
- 환기 → 공청 전환 시 **팬은 정상 동작하는데 내부댐퍼(본체 6개)가 안 움직임.**
## 원인 (마스터 `D:\Project\nuvoton\HERV_DL_MH_2nd\Program` 비교로 확정)
- 내부댐퍼 이동 트리거(`Fan_Speed_process`가 모드변경 시 `Damper_Mode()` 호출)는 HECO2/마스터 **동일하게 존재**. 빠진 게 아님.
- 그 트리거는 **"팬이 0까지 감속"되어야 발동**하도록 게이팅됨(공기 흐름 중 댐퍼 미동작 의도):
`모드변경 → 팬타깃0 → 팬=0 도달 → Damper_Mode 호출(댐퍼 이동) → 정렬(Step_Status==0x3F) → 팬 복원`
- **마스터:** 명령 핸들러가 팬 타깃을 안 건드림 → 팬이 0 도달 → 댐퍼 이동.
- **HECO2:** 명령 핸들러가 모드변경 즉시 `Fan_Speed_Setting()` 직접 호출 → 팬 타깃이 곧바로 운전속도로 올라감 → **팬이 0에 도달 못 함 → `if(Fan!=0) if(wait==5) goto PASS1` 게이트가 `Damper_Mode` 영원히 스킵 → 댐퍼 미동작, 팬만 정상.**
- 마스터엔 없고 HECO2에만 추가된 명령경로 `Fan_Speed_Setting` 호출이 게이트를 막은 것.
## 변경 파일/내용 (1차 = 모드 변경 시 호출만 제거, 풍량단수 변경 호출은 유지)
주석 처리(삭제 아님, 복원 용이). 마커: `[모드변경댐퍼테스트]`
- `Source/HECO2/User/My_Homenet.c`
- L259 CTRL_POWER(전원ON→환기) `Fan_Speed_Setting` 주석
- L293 CTRL_RUNMODE(운전모드 변경) `Fan_Speed_Setting` 주석 ← 보고 증상(대시보드 환기→공청)의 직접 경로
- **L306 CTRL_FAN(풍량단수만 변경)은 유지** (댐퍼 무관, 팬 단수 반응 필요)
- `Source/HECO2/User/My_Hood.c`
- L192 후드ON(→환기) `Fan_Speed_Setting` 주석
- L207 후드OFF(모드 복귀) `Fan_Speed_Setting` 주석
- **L219 후드 단수변경(풍량만)은 유지**
## 핵심 결정
- 모드 변경 후 팬 복원은 `Fan_Speed_process`의 wait==1 호출(MyMotor.c 1018/1056/1090/1124, ③)이 담당 → 팬이 꺼진 채 남지 않음.
- RJ2(`My_RJ2.c`)·분배기(`My_bunbaegi.c`)는 두 소스 동일 → 미수정.
- 이번엔 "동작모드 변경 트리거 복원(①, 디퓨저 시퀀스 명령트리거)"은 보류 — ②(땜빵) 제거만으로 댐퍼가 움직이는지 먼저 검증.
## 빌드 결과
- `cd SOURCE/HECO2 && bash build.sh all` → 성공, 경고/오류 0.
- text 43920 / data 1940 / bss 3388 (HERV.elf). (이전 44008 → 코드 제거로 감소)
## 미해결 / 후속
- 실장비/시뮬레이터에서 **환기→공청 시 내부댐퍼 이동** 확인 필요(특히 고풍량 전환 시 팬 감속 대기시간 체감).
- 검증 후: 필요하면 ①(동작모드 변경 트리거 = MyMotor.c 디퓨저/팬복원 타이밍의 명령 트리거)도 마스터 정렬 검토.
- 풍량단수만 바꿀 때(L306/L219) 팬 즉시 반응 정상인지 확인.
---
# 260618 (2) 스마트수면 모드 — 거실 댐퍼 미닫힘 수정
## 증상
- 스마트수면 동작 중 **거실 댐퍼가 열려 있음**. 사양(개발사양서 8p)상 거실은 항상 CLOSE여야 함.
## 사양 (개발사양서 8p, 스마트수면)
- 환기 수동·풍량 1단 고정.
- 초기상태: **거실 CLOSE, 침실1~3 OPEN**.
- 거실 급기(SA)/배기(RA) 모두 **X(항상 닫힘)** — CO2 무관.
- 침실1~3: CO2 >= 1000 PPM → 해당 침실 OPEN, CO2 <= 800 PPM → CLOSE.
## 원인
- `My_system.c` `Air_Quality_damper_process()` `Ext_Run_Mode == 4` 블록.
- 진입 1회(L905)는 거실(room1)을 올바르게 CLOSE 하지만, **매 틱 CO2 루프가 `Room_Num = 1`부터 돌아(L916) 거실까지 CO2 기준으로 다시 OPEN** 시킴.
- 룸 인덱스: room1=거실, room2~4=침실1~3.
## 변경 파일/내용
- `Source/HECO2/User/My_system.c` (스마트수면 매 틱 처리)
- 거실(room1) 매 틱 강제 CLOSE + LED off 추가.
- CO2 히스테리시스 루프 시작을 `Room_Num = 1`**`Room_Num = 2`** (침실1~3만 개폐).
## 빌드 결과
- `bash build.sh all` → 성공, 경고/오류 0. text 43940 / data 1940 / bss 3388.
## 후속
- 실장비에서 스마트수면 진입 시 거실 닫힘 + 침실 CO2 개폐 확인.
---
# 260618 (3) 내부댐퍼 미동작 — 진짜 원인(타이밍 레이스) 수정
## 추가 진단 (사용자 확인)
- 테스트 경로 = **PC 대시보드**(My_Homenet 경로).
- 팬 거동 = **0까지 안 내려감**, 그리고 **간헐적**(어쩌다 정상 댐퍼 동작).
- → 전형적 **타이밍 레이스**. (1)차 수정으로 CTRL_RUNMODE(293)는 막았지만, 대시보드가 모드변경과 함께 보내는 **CTRL_FAN(306, 유지됨)** 이 모드전환 감속창(팬→0 구간)에 끼어드는 타이밍이면 팬 타깃을 다시 켜서 팬이 0 도달 못 함 → Damper_Mode 게이트 안 열림.
- 끼어드는 타이밍이 아니면 정상 → 간헐성 설명됨.
## 수정 (2차 = 게이트 보호, 단일 지점)
- `Source/HECO2/User/MyMotor.c` `Fan_Speed_process()` PASS1 직후(정상운전 분기, VSP 제외):
- `Damper_wait_time == 5`(=모드전환 진행중 전용 신호. 4개 모드 진입에서만 set, Step 정렬 전까지 5 유지)일 때
`Target_Fan1_Speed = 0; Target_Fan2_Speed = 0;` **강제** → 명령경로(CTRL_FAN 등)가 감속창에 끼어들어도 무시하고 팬을 0으로 떨굼 → 댐퍼 이동 보장.
- 전환 완료(Step_Status==0x3F) 후 wait가 5→1로 감소하며 wait==1에서 Fan_Speed_Setting(③)이 팬 복원.
- 풍량단수만 변경(같은 모드, wait==0)은 force-zero 미적용 → CTRL_FAN(306) 즉시 반응 유지.
## 동작 변화(주의)
- 이제 환기→공청 전환 시 **팬이 잠깐 0까지 멈췄다가**(댐퍼 이동) 다시 도는 게 정상(설계상 공기흐름 중 댐퍼 미동작). 기존 "안 멈추던" 거동에서 바뀜.
## 빌드 결과
- `bash build.sh all` → 성공, 경고/오류 0. text 43948.
## 후속
- 실장비에서 환기→공청 **반복 전환** 시 매번 댐퍼 이동(간헐성 사라짐) 확인.
- 같은 모드 풍량단수 변경 시 팬 즉시 반응 정상 확인.
---
# 260618 (4) 쾌적조리 재선택 안됨 — 대시보드 버튼 강조 버그
## 증상
- 쾌적조리 동작 마치고 이전 모드 복귀 후 다시 쾌적조리 버튼 누르면 선택(ON)이 안 됨. 눌러도 토글 반응이 안 보임.
## 사양 (개발사양서 9p)
- 쾌적조리 = 운전모드가 아닌 **'후드 연동 UI 토글 스위치'**. 사용자가 켤 때까지 ON 유지.
- 3.1 매트릭스: 토글 ON + 후드꺼짐 = 대기(본래 모드 가동), 토글 ON + 후드켜짐 = 메이크업 강제연동.
- 3.3 Roll-back: 후드 OFF 후 20분 환기 약 후 이전 모드 복귀 — 이는 메이크업 복귀 타이밍이지 토글 OFF가 아님.
- → 토글은 **계속 armed**가 정상. 펌웨어 `Hood_YeunDong_Enable`(토글)은 정상.
## 원인 (순수 대시보드 버그)
- `_state.ComfortCook` = status byte4 bit1 = 펌웨어 `Hood_YeunDong_Enable`(토글 Enable).
- 대시보드가 **토글 판단은 `_state.ComfortCook`(L386), 버튼 강조는 `_state.HoodRunning`(L581, 후드 실제 가동중)** 으로 서로 다른 변수 사용.
- 대기/Roll-back 상태(HoodRunning=0, ComfortCook=1)에서 버튼이 꺼져 보이고, 다시 누르면 `next=!ComfortCook=false` → OFF 전송 → "선택 안됨".
## 변경 파일/내용
- `TestProgram/PCDashBoard/MainWindow.xaml.cs` L581:
- `SetActive(ComfortCookBtn, _state.HoodRunning);``SetActive(ComfortCookBtn, _state.ComfortCook);`
- 토글 상태(=Enable)를 강조하도록 일치. (모드/풍량 잠금 `subActive`는 사양 3.1대로 HoodRunning 유지 — 대기 중 본래 모드 조작 허용.)
## 빌드 결과
- `dotnet build ErvDashboard.csproj` → 오류 0 (NU1701 경고 9개는 기존 패키지 호환 경고, 무관).
## 미해결 / 후속(선택)
- 사양상 쾌적조리는 운전모드 시나리오(스마트수면/안심회복)와 **독립**인데, 대시보드는 셋을 상호배타 처리(SubMode_Click L401~406, ApplySubModeLocal). 스마트수면/안심회복 켤 때 쾌적조리가 강제 OFF됨 → 사양과 불일치 가능. 필요 시 분리 검토.
---
# 260618 (5) 쾌적조리 버튼 활성(Enable)이 후드 상태에 묶임 — 독립 토글로 수정
## 증상
- 쾌적조리 버튼이 디폴트 비활성, 전원 ON/후드 연결 시에야 토글됨. 사양 9p 3.1상 쾌적조리는 후드 연결과 무관한 독립 토글.
## 원인
- `MainWindow.xaml.cs` L587 `ComfortCookBtn.IsEnabled = !subActive || _state.ComfortCook;`
- `subActive = SmartSleep || HoodRunning || ReliefRecover`**HoodRunning(후드 가동중)** 포함 → 후드 상태가 쾌적조리 버튼 활성을 좌우.
## 변경 파일/내용
- `TestProgram/PCDashBoard/MainWindow.xaml.cs` L587:
- `ComfortCookBtn.IsEnabled = !subActive || _state.ComfortCook;``ComfortCookBtn.IsEnabled = true;`
- 쾌적조리는 독립 토글 → 후드 연결/가동·다른 시나리오와 무관하게 항상 토글 가능. (모드/풍량 버튼은 기존대로 subActive 잠금 유지.)
## 빌드/배포
- `dotnet publish ErvDashboard.csproj -c Release` → 오류 0. publish 단일 exe 갱신.