From 20ae50e4c7a551af2f4824962a647f124988bd35 Mon Sep 17 00:00:00 2001 From: seo-amugae Date: Sun, 7 Jun 2026 06:11:58 +0900 Subject: [PATCH] Add EEPROM-backed seat position setting --- Auto_Seat.ino | 121 +++++++++++++++----------------------------------- 1 file changed, 36 insertions(+), 85 deletions(-) diff --git a/Auto_Seat.ino b/Auto_Seat.ino index a2e5a36..d89d326 100644 --- a/Auto_Seat.ino +++ b/Auto_Seat.ino @@ -1,5 +1,6 @@ // Auto_Seat -// Timed automatic seat controller with relay protection. +// EEPROM-backed automatic seat controller. +#include #define seatRelayD8 8 #define seatRelayD9 9 @@ -11,31 +12,24 @@ const int PARKING_ON_THRESHOLD = 950; const int PARKING_OFF_THRESHOLD = 940; 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; +const int EEPROM_MAGIC_ADDR = 0; +const byte EEPROM_MAGIC_VALUE = 0x64; +const int EEPROM_SEAT_POSITION_ADDR = 2; boolean ignitionState = LOW; boolean parkingState = LOW; -boolean prevIgnitionState = LOW; boolean confirmedDriveMode = LOW; boolean pendingDriveMode = LOW; -bool isStabilizing = false; -bool downEdgeMarginActive = false; int parkingRawValue = 0; +uint16_t storedSeatPositionMs = 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; +int seatAction = 0; void setup() { pinMode(parkingPin, INPUT); @@ -43,7 +37,7 @@ void setup() { pinMode(seatRelayD8, OUTPUT); pinMode(seatRelayD9, OUTPUT); applySeatAction(0); - seat(0); + loadSettings(); measurement(); confirmedDriveMode = getRawDriveMode(); pendingDriveMode = confirmedDriveMode; @@ -53,27 +47,13 @@ void setup() { void loop() { measurement(); - unsigned long currentTime = millis(); - unsigned long deltaTime = currentTime - lastTime; - lastTime = currentTime; - - if (prevIgnitionState == LOW && ignitionState == HIGH) { - isStabilizing = true; - stabilizeStartTime = currentTime; - } - prevIgnitionState = ignitionState; - - if (isStabilizing && currentTime - stabilizeStartTime < IGNITION_STABILIZE_MS) { - seat(0); - updateRelayOutput(currentTime); - return; - } - isStabilizing = false; - - updateConfirmedDriveMode(currentTime); + unsigned long now = millis(); + unsigned long deltaTime = now - lastTime; + lastTime = now; + updateConfirmedDriveMode(now); targetPosMs = getTargetForConfirmedMode(); updateMovement(deltaTime); - updateRelayOutput(currentTime); + applySeatAction(seatAction); } void measurement() { @@ -84,80 +64,51 @@ void measurement() { } boolean getRawDriveMode() { return ignitionState == HIGH && parkingState == LOW; } -long getTargetForConfirmedMode() { return confirmedDriveMode == HIGH ? SEAT_HARD_LIMIT_UP_MS : 0; } +long getTargetForConfirmedMode() { return confirmedDriveMode == HIGH ? storedSeatPositionMs : 0; } -void updateConfirmedDriveMode(unsigned long currentTime) { +void updateConfirmedDriveMode(unsigned long now) { boolean rawDriveMode = getRawDriveMode(); if (rawDriveMode != pendingDriveMode) { pendingDriveMode = rawDriveMode; - pendingDriveModeStartTime = currentTime; + pendingDriveModeStartTime = now; } unsigned long confirmMs = pendingDriveMode == HIGH ? DRIVE_CONFIRM_MS : PARK_CONFIRM_MS; - if (pendingDriveMode != confirmedDriveMode && currentTime - pendingDriveModeStartTime >= confirmMs) { + if (pendingDriveMode != confirmedDriveMode && now - 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); + seatAction = 1; currentPosMs += deltaTime; - if (currentPosMs >= targetPosMs) { - currentPosMs = targetPosMs; - seat(0); - } + if (currentPosMs >= targetPosMs) { currentPosMs = targetPosMs; seatAction = 0; } } else if (currentPosMs > targetPosMs) { - seat(-1); + seatAction = -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); - } - } + if (currentPosMs <= targetPosMs) { currentPosMs = targetPosMs; downSpeedRemainder = 0; seatAction = 0; } } else { - seat(0); + seatAction = 0; } } +void loadSettings() { + if (EEPROM.read(EEPROM_MAGIC_ADDR) != EEPROM_MAGIC_VALUE) { + EEPROM.update(EEPROM_MAGIC_ADDR, EEPROM_MAGIC_VALUE); + writeUint16(EEPROM_SEAT_POSITION_ADDR, SEAT_HARD_LIMIT_UP_MS); + } + storedSeatPositionMs = readUint16(EEPROM_SEAT_POSITION_ADDR); + if (storedSeatPositionMs > SEAT_HARD_LIMIT_UP_MS) { + storedSeatPositionMs = SEAT_HARD_LIMIT_UP_MS; + writeUint16(EEPROM_SEAT_POSITION_ADDR, storedSeatPositionMs); + } +} + +uint16_t readUint16(int addr) { return (uint16_t)EEPROM.read(addr) | ((uint16_t)EEPROM.read(addr + 1) << 8); } +void writeUint16(int addr, uint16_t value) { EEPROM.update(addr, value & 0xFF); EEPROM.update(addr + 1, (value >> 8) & 0xFF); } 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); }