From 7bc43f4192f31f47a03185bd27c2517083c4ad5a Mon Sep 17 00:00:00 2001 From: seo-amugae Date: Sun, 7 Jun 2026 06:11:58 +0900 Subject: [PATCH] Tune seat travel timing and down movement ratio --- Auto_Seat.ino | 153 +++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 126 insertions(+), 27 deletions(-) diff --git a/Auto_Seat.ino b/Auto_Seat.ino index 68365f8..a2e5a36 100644 --- a/Auto_Seat.ino +++ b/Auto_Seat.ino @@ -1,22 +1,41 @@ // Auto_Seat -// Initial automatic seat relay controller. +// Timed automatic seat controller with relay protection. #define seatRelayD8 8 #define seatRelayD9 9 #define parkingPin A0 #define ignitionPin 7 +const uint16_t SEAT_HARD_LIMIT_UP_MS = 6000; const int PARKING_ON_THRESHOLD = 950; const int PARKING_OFF_THRESHOLD = 940; -const unsigned long SEAT_UP_MS = 2000UL; -const unsigned long SEAT_DOWN_MS = 2200UL; +const int DOWN_SPEED_NUM = 11; +const int DOWN_SPEED_DEN = 10; +const unsigned long IGNITION_STABILIZE_MS = 1000UL; +const unsigned long DRIVE_CONFIRM_MS = 80UL; +const unsigned long PARK_CONFIRM_MS = 250UL; +const unsigned long RELAY_DEADTIME_MS = 120UL; +const unsigned long DOWN_EDGE_MARGIN_MS = 300UL; -boolean parkingState = LOW; boolean ignitionState = LOW; -boolean previousDriveMode = LOW; +boolean parkingState = LOW; +boolean prevIgnitionState = LOW; +boolean confirmedDriveMode = LOW; +boolean pendingDriveMode = LOW; +bool isStabilizing = false; +bool downEdgeMarginActive = false; int parkingRawValue = 0; -unsigned long moveStartTime = 0; -int seatAction = 0; +long currentPosMs = 0; +long targetPosMs = 0; +long downSpeedRemainder = 0; +unsigned long lastTime = 0; +unsigned long stabilizeStartTime = 0; +unsigned long pendingDriveModeStartTime = 0; +unsigned long relayDeadtimeStartTime = 0; +unsigned long downEdgeMarginTime = DOWN_EDGE_MARGIN_MS; +int currentSeatAction = 0; +int requestedSeatAction = 0; +int lastStoppedSeatAction = 0; void setup() { pinMode(parkingPin, INPUT); @@ -24,21 +43,37 @@ void setup() { pinMode(seatRelayD8, OUTPUT); pinMode(seatRelayD9, OUTPUT); applySeatAction(0); + seat(0); + measurement(); + confirmedDriveMode = getRawDriveMode(); + pendingDriveMode = confirmedDriveMode; + targetPosMs = getTargetForConfirmedMode(); + lastTime = millis(); } void loop() { measurement(); - boolean driveMode = ignitionState == HIGH && parkingState == LOW; + unsigned long currentTime = millis(); + unsigned long deltaTime = currentTime - lastTime; + lastTime = currentTime; - if (driveMode != previousDriveMode) { - previousDriveMode = driveMode; - moveStartTime = millis(); - seatAction = driveMode ? 1 : -1; + if (prevIgnitionState == LOW && ignitionState == HIGH) { + isStabilizing = true; + stabilizeStartTime = currentTime; } + prevIgnitionState = ignitionState; - if (seatAction == 1 && millis() - moveStartTime >= SEAT_UP_MS) seatAction = 0; - if (seatAction == -1 && millis() - moveStartTime >= SEAT_DOWN_MS) seatAction = 0; - applySeatAction(seatAction); + if (isStabilizing && currentTime - stabilizeStartTime < IGNITION_STABILIZE_MS) { + seat(0); + updateRelayOutput(currentTime); + return; + } + isStabilizing = false; + + updateConfirmedDriveMode(currentTime); + targetPosMs = getTargetForConfirmedMode(); + updateMovement(deltaTime); + updateRelayOutput(currentTime); } void measurement() { @@ -48,19 +83,83 @@ void measurement() { else if (parkingState == HIGH && parkingRawValue <= PARKING_OFF_THRESHOLD) parkingState = LOW; } -void setRelay(int relayPin, boolean state) { - digitalWrite(relayPin, state ? LOW : HIGH); +boolean getRawDriveMode() { return ignitionState == HIGH && parkingState == LOW; } +long getTargetForConfirmedMode() { return confirmedDriveMode == HIGH ? SEAT_HARD_LIMIT_UP_MS : 0; } + +void updateConfirmedDriveMode(unsigned long currentTime) { + boolean rawDriveMode = getRawDriveMode(); + if (rawDriveMode != pendingDriveMode) { + pendingDriveMode = rawDriveMode; + pendingDriveModeStartTime = currentTime; + } + unsigned long confirmMs = pendingDriveMode == HIGH ? DRIVE_CONFIRM_MS : PARK_CONFIRM_MS; + if (pendingDriveMode != confirmedDriveMode && currentTime - pendingDriveModeStartTime >= confirmMs) { + confirmedDriveMode = pendingDriveMode; + } +} + +void updateMovement(unsigned long deltaTime) { + if (downEdgeMarginActive) { + seat(-1); + downEdgeMarginTime += deltaTime; + if (downEdgeMarginTime >= DOWN_EDGE_MARGIN_MS) { + downEdgeMarginActive = false; + downEdgeMarginTime = DOWN_EDGE_MARGIN_MS; + seat(0); + } + return; + } + + if (currentPosMs < targetPosMs) { + seat(1); + currentPosMs += deltaTime; + if (currentPosMs >= targetPosMs) { + currentPosMs = targetPosMs; + seat(0); + } + } else if (currentPosMs > targetPosMs) { + seat(-1); + long scaled = deltaTime * DOWN_SPEED_NUM + downSpeedRemainder; + currentPosMs -= scaled / DOWN_SPEED_DEN; + downSpeedRemainder = scaled % DOWN_SPEED_DEN; + if (currentPosMs <= targetPosMs) { + currentPosMs = targetPosMs; + downSpeedRemainder = 0; + if (targetPosMs == 0) { + downEdgeMarginActive = true; + downEdgeMarginTime = 0; + } else { + seat(0); + } + } + } else { + seat(0); + } +} + +void setRelay(int relayPin, boolean state) { digitalWrite(relayPin, state ? LOW : HIGH); } +void seat(int action) { requestedSeatAction = action; } + +void updateRelayOutput(unsigned long currentTime) { + if (requestedSeatAction == currentSeatAction) { + applySeatAction(currentSeatAction); + return; + } + if (currentSeatAction != 0) { + lastStoppedSeatAction = currentSeatAction; + currentSeatAction = 0; + relayDeadtimeStartTime = currentTime; + applySeatAction(0); + return; + } + bool sameDirectionResume = requestedSeatAction != 0 && requestedSeatAction == lastStoppedSeatAction; + bool deadtimeDone = currentTime - relayDeadtimeStartTime >= RELAY_DEADTIME_MS; + if (sameDirectionResume || deadtimeDone) currentSeatAction = requestedSeatAction; + applySeatAction(currentSeatAction); } void applySeatAction(int action) { - if (action == 1) { - setRelay(seatRelayD8, 1); - setRelay(seatRelayD9, 0); - } else if (action == -1) { - setRelay(seatRelayD8, 0); - setRelay(seatRelayD9, 1); - } else { - setRelay(seatRelayD8, 0); - setRelay(seatRelayD9, 0); - } + if (action == 1) { setRelay(seatRelayD8, 1); setRelay(seatRelayD9, 0); } + else if (action == -1) { setRelay(seatRelayD8, 0); setRelay(seatRelayD9, 1); } + else { setRelay(seatRelayD8, 0); setRelay(seatRelayD9, 0); } }