1. 현재 핵심 설정
SEAT_HARD_LIMIT_UP_MS = 6000
모든 자동/수동 위치 목표는 0..6000ms 범위 안에서만 허용됩니다.
storedSeatPositionMs = EEPROM
하드코딩 기본 위치는 사용하지 않고 EEPROM에서 읽습니다. EEPROM 초기화 시 6000ms로 설정됩니다.
11 / 10
일반 자동 하강과 수동 하강 위치 계산은 상승보다 1.1배 빠른 것으로 추정합니다.
MANUAL_STEP_MS = 500
u는 +500ms, d는 -500ms 이동 목표를 설정합니다.
UP 7000ms -> DOWN 6000ms
10회 사용 후 시동 OFF 상태 5분 경과 시 자동 보정합니다. c 명령은 즉시 보정합니다.
RELAY_DEADTIME_MS = 120
상승/하강 반전 시 릴레이를 잠깐 OFF로 두어 접점 부담을 줄입니다.
2. 입력 신호 판정
| 항목 | 조건 | 결과 |
|---|---|---|
| P ON | parkingRawValue >= 950 | parkingState = HIGH |
| P OFF | parkingRawValue <= 940 | parkingState = LOW |
| 주행 raw | IG1 HIGH && P LOW | 시트 상승 목표 상태 |
| 주행 확정 | 주행 raw가 80ms 유지 | confirmedDriveMode = HIGH |
| P/비주행 확정 | 비주행 raw가 250ms 유지 | confirmedDriveMode = LOW |
| 시동 직후 안정화 | IG1 LOW -> HIGH 후 1000ms | 릴레이 OFF, P 신호 튐 무시 |
3. 장시간 주차 후 전원 인가부터 시뮬레이션
3.1 잠금 해제 직후
IG1 = LOW P = LOW confirmedDriveMode = LOW targetPosMs = 0 relay = OFF
사용자 설명 기준으로 잠금 해제 직후에는 IG1 OFF, P OFF입니다. 코드는 주행 조건을 IG1 HIGH && P LOW로 보므로 상승하지 않습니다.
3.2 브레이크 후 시동 ON 직후
IG1 LOW -> HIGH isStabilizing = true for 1000ms: seat(0) relay = OFF
시동 직후 P가 약 1초 동안 ON/OFF/ON으로 흔들려도 안정화 구간에서 릴레이는 동작하지 않습니다.
3.3 P단 유지
IG1 = HIGH P = HIGH confirmedDriveMode = LOW targetPosMs = 0
P단에서는 목표 위치가 0입니다. 현재 추정 위치가 0보다 높으면 하강합니다.
3.4 P단 외 이동
P = LOW for 80ms confirmedDriveMode = HIGH targetPosMs = storedSeatPositionMs relay = UP until currentPosMs reaches targetPosMs
P단 외 상태가 80ms 유지되면 EEPROM에 저장된 위치까지 상승합니다.
3.5 P단 복귀 또는 시동 OFF
confirmedDriveMode = LOW targetPosMs = 0 currentPosMs -= deltaTime * 11 / 10 when currentPosMs <= 0: currentPosMs = 0 DOWN relay extra 300ms relay = OFF
하강은 1.1배 속도로 위치를 추정하고, 바닥 도달 후 300ms 추가 하강으로 바닥 밀착감을 줍니다.
4. 한 글자 시리얼 명령
시리얼 연결 후 처음에는 잠금 상태입니다. 빈 Enter를 한 번 입력하면 도움말과 현재 상태를 출력하고, 그때부터 한 글자 명령을 사용할 수 있습니다. 잠금 해제 후 Enter 단독 입력은 아무 동작도 하지 않습니다. 안전을 위해 p/u/d/a/c/r 명령은 P단에서만 실행됩니다.
| 명령 | 동작 | 응답 |
|---|---|---|
s | 현재 상태 1회 출력 | 상태 ACK 출력 |
u | 현재 추정 위치에서 +500ms 목표 설정 | 현재 위치/목표 출력 |
d | 현재 추정 위치에서 -500ms 목표 설정 | 현재 위치/목표 출력 |
p | 현재 추정 위치를 EEPROM 자동 상승 위치로 저장 | 저장된 위치 출력 |
g | 1초마다 debug 출력 시작 | debug 중에는 x만 작동 |
x | debug 모드 종료 전용 | debug 종료 후 상태 출력 |
a | 수동 모드 해제, 기어 기반 자동 목표로 복귀 | 상태 출력 |
c | 즉시 보정: 상승 7초, 하강 6초, 위치 0 설정 | 상태 출력 |
r | 10회 자동 보정 카운터 초기화 | 상태 출력 |
h | 도움말 출력 | 도움말 + 현재 상태 출력 |
주의: 명령은 한 글자만 받습니다. debug, down, position 2000처럼 긴 문자열은 실행하지 않습니다.
5. 수동 위치 세팅 시뮬레이션
| 현재 추정 위치 | 입력 | 계산 | 결과 |
|---|---|---|---|
| 2000 | u | 2000 + 500 = 2500 | 목표 2500으로 상승, 상태 출력 |
| 2500 | u | 2500 + 500 = 3000 | 목표 3000으로 상승, 상태 출력 |
| 3000 | p | 현재 위치 3000 저장 | EEPROM 저장 위치가 3000으로 변경 |
| 3000 | P단 복귀 | 목표 0 | 하강 |
| 0 | P단 외 이동 | 목표 EEPROM 3000 | 3000까지 자동 상승 |
6. 범위 초과 시뮬레이션
| 현재 추정 위치 | 입력 | 계산 | 결과 |
|---|---|---|---|
| 5800 | u | 6300 | 0..6000 범위 초과, 경고 출력, 목표 변경 없음 |
| 200 | d | -300 | 0..6000 범위 초과, 경고 출력, 목표 변경 없음 |
| 임의 | abc | 한 글자 아님 | 실행 거절, ACK 상태 출력 |
7. 10회 사용 후 자동 보정 시뮬레이션
each IG1 HIGH -> LOW: useCount++ EEPROM.update(useCount) if useCount >= 10 and IG1 LOW for 5 minutes: UP relay ON for 7000ms DOWN relay ON for 6000ms relay OFF currentPosMs = 0 targetPosMs = 0 useCount = 0
자동 보정 중 시동이 켜지면 중단합니다. 단, c로 시작한 강제 보정은 IG1 ON 상태에서도 끝까지 진행합니다.
8. 현재 주의 사항
- 시트 위치는 실제 센서가 아니라 시간 기반 추정값입니다.
- 전원 차단 후 재부팅하면
currentPosMs는 0에서 시작합니다. u/d는 위치 조절만 하고 EEPROM 저장은 하지 않습니다. 저장은 반드시p로 합니다.d는 하강,g는 debug입니다. debug 충돌을 피하기 위해d를 debug로 쓰지 않습니다.- debug 상태에서는
x만 작동하며,r,a,s,u,d,p,c는 모두 무시됩니다.
9. 추가 예외처리 기준
| 예외 상황 | 처리 | 목적 |
|---|---|---|
| 시트 이동 중 키 입력 | ERR: busy 출력 후 명령 무시 |
연속 입력으로 500ms 단위가 흐트러지는 문제 방지 |
P단이 아닌 상태에서 p/u/d/a/c/r 입력 |
ERR: check gear state. Command requires P. 출력 |
수동 이동, 저장, 보정, EEPROM 변경이 P단 외 상태에서 실행되는 문제 방지 |
| 수동 이동 완료 전 기어 상태 변경 | 수동 완료 대기 플래그 해제 | 자동 제어로 넘어간 뒤 잘못된 MANUAL_STEP_DONE 출력 방지 |
| 내부 위치값 범위 이탈 | currentMs, targetMs를 0..6000으로 보정 |
시간 계산 오차나 상태 꼬임으로 인한 비정상 목표 방지 |
| 보정 시작/중단 | 수동 이동 플래그, 하강 잔여값, 하단 추가 하강 상태 초기화 | 보정과 일반 이동 상태가 섞이는 문제 방지 |